0% ont trouvé ce document utile (0 vote)
0 vues47 pages

BPM

Le projet de fin d'année explore la détection du tempo d'une chanson à l'aide de différents algorithmes, notamment l'intercorrélation et l'autocorrélation. Les étudiants Pierre Fritsch et Thomas Dupas, sous la supervision de Jean-Luc Collette, mettent en œuvre ces méthodes pour mesurer le BPM (battements par minute) et réaliser des transitions musicales. Le document présente également une interface graphique pour faciliter l'utilisation des algorithmes développés.

Transféré par

Hiba Kammarti
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
0 vues47 pages

BPM

Le projet de fin d'année explore la détection du tempo d'une chanson à l'aide de différents algorithmes, notamment l'intercorrélation et l'autocorrélation. Les étudiants Pierre Fritsch et Thomas Dupas, sous la supervision de Jean-Luc Collette, mettent en œuvre ces méthodes pour mesurer le BPM (battements par minute) et réaliser des transitions musicales. Le document présente également une interface graphique pour faciliter l'utilisation des algorithmes développés.

Transféré par

Hiba Kammarti
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Projet de conception de fin de deuxième année

Détection du tempo d’une chanson

Pierre Fritsch Thomas Dupas

Avril – Juin 2005

Supélec
Projet encadré par Jean-Luc Collette
Table des matières

1. Introduction 5
1.1. Étendue du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2. Que signifie BPM ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2. Algorithmes de détection du rythme 7


2.1. Intercorrélation avec un peigne de Dirac . . . . . . . . . . . . . . . . . . . 7
2.1.1. Principe et limitations théoriques . . . . . . . . . . . . . . . . . . . 7
2.1.2. Mise en oeuvre pratique . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.3. Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2. Autocorrélation de la chanson . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1. Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.2. Implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.3. Avantages et inconvénients . . . . . . . . . . . . . . . . . . . . . . 11
2.3. Méthode de détection des crêtes . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.1. Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.2. Implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.3. Avantages et inconvénients . . . . . . . . . . . . . . . . . . . . . . 14

3. Implémentation de “fondu calé” 15


3.1. Précision requise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.1.1. Précision de la mesure du BPM . . . . . . . . . . . . . . . . . . . . 15
3.1.2. Qualité du modificateur de rythme . . . . . . . . . . . . . . . . . . 16
3.2. Implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.1. Mesure du BPM des morceaux . . . . . . . . . . . . . . . . . . . . 16
3.2.2. Time stretching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.3. Superposition des morceaux . . . . . . . . . . . . . . . . . . . . . . 16
3.2.4. Fondu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2.5. Reconstitution en un seul morceau . . . . . . . . . . . . . . . . . . 17

4. Interface graphique du programme de “fondu calé” 19

A. Code source 27
A.1. calcul bpm.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
A.2. calcul peigne.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A.3. calcul crete.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
A.4. calcul peigne.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A.5. donner peigne superposition.m . . . . . . . . . . . . . . . . . . . . . . . . 37

3
A.6. synchro morceaux.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
A.7. transition.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

B. Algorithme basé sur la mesure de l’énergie 45


B.1. Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
B.2. Première analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
B.3. Quelques optimisations directes . . . . . . . . . . . . . . . . . . . . . . . . 46
B.4. Sensibilité de la détection . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
B.5. Efficacité de l’algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4
Chapitre 1.
Introduction
Simuler un phénomène physique régi par des équations mathématiques bien connues
est toujours faisable, même si cela est souvent soumis à bon nombre d’approximations.
Mais qu’en est-il de concepts plus abstraits, comme les sensations ressenties par l’homme,
qui ne suivent aucune loi ? Les choses les plus simples à ressentir sont bien souvent les
choses les plus dures à traduire en termes de programme informatique. La caractérisation
de rythme illustre ce concept : ressentir le rythme d’une chanson est une chose naturelle
pour les humains, même les non spécialistes. Néanmoins, il ne s’agit que d’une intuition,
d’une impression que l’on ressent en écoutant une mélodie, une impression qui nous fera
dancer en rythme ou tapoter sur le coin d’une table sur les batements du morceau.
Ainsi, comment faire acquérir cette capacité à un ordinateur qui ne sait effectuer que
des opérations mathématiques ? En fait, il existe quelques algorithmes qui parviennent
à approximer, avec plus ou moins de précision, cette détection. Nous avons, au cours
de ce projet, étudié différentes méthodes d’extraction de rythme sur des chansons pré-
enregistrées.

1.1. Étendue du projet


Après un rapide tour d’horizon des nombreux algorithmes de détection qui existent
dans la littérature, nous tenterons d’en implémenter quelques-uns et étudierons leurs
limites (chap. 2). Nous appliquerons ensuite cette connaissance à l’exemple concret d’une
diffusion musicale, en essayant de faire une transition douce entre deux morceaux de
rythmes différents (chap. 3). Ces opérations seront réalisées sous Matlab, à l’aide d’une
interface graphique décrite au chap. 4. Pour conclure, nous comparerons les algorithmes
utilisés.

1.2. Que signifie BPM ?


Les beats font référence à la perception d’une pulsation mettant en valeur des périodes
de durée constante. Le tempo correpond à la fréquence à laquelle ces pulsations se pré-
sentent. C’est à cette fréquence que l’être humain tape “naturellement” du pied lorsqu’il
entend de la musique. Le BPM (beats par minute) est une unité de mesure du tempo :
elle représente le nombre de boums ou battements qu’il y a dans un morceau en une
minute.

5
Typiquement, un être humain est capable de détecter la périodicité temporelle d’une
chanson entre 40 et 150 BPM. Lorsque les beats se produisent à plus de deux secondes
d’intervalle, il les interprète comme une série d’événements isolés, plutôt qu’une séquence
unifiée et régulière. De même, en-dessous de 250 ms, les battements sont trop rapprochés.
Le but de ce projet est de mesurer le tempo d’une chanson et de l’exprimer en BPM.

6
Chapitre 2.
Algorithmes de détection du rythme
Voyons quelques algorithmes de calcul de BPM.

2.1. Intercorrélation avec un peigne de Dirac


Cet algorithme, décrit dans [Pat03], consiste à comparer le signal avec des peignes de
Dirac à différents BPM.

2.1.1. Principe et limitations théoriques


Le principe mis en oeuvre par cet algorithme est la mesure de la ressemblance maximale
entre une chanson et un peigne de Dirac. Cette mesure est effectuée grâce à l’intercorré-
lation des deux signaux γxy [β] = k=+∞ k=−∞ x[k]y[k − β].
P

L’énergie de la fonction d’intercorrélation nous fournit une idée de la ressemblance


entre le signal et le peigne de Dirac testé. Cela permet en quelque sorte de mesurer
combien le rythme du peigne est présent dans la chanson. On répète cette opération
pour des peignes de Dirac à différentes fréquences, et on regarde pour lequel d’entre eux
l’énergie est la plus grande. On notera Ey cette énergie, tandis que x[k] est le signal
représentant l’extrait considéré et y[k] est le peigne de Dirac.

+∞
X
Ey = γxy [k]2
k=−∞

Cette expression étant assez gourmande en temps de calcul, on préfère passer dans le
domaine fréquentiel pour s’affranchir du calcul de tous les décalages :

N
|X[k] · Y [k]|2
X
Ey =
k=0

2.1.2. Mise en oeuvre pratique


– On choisit 5 secondes quelque part dans le morceau.
– On calcule la transformée de Fourier X[k] du signal.
– On note BP M c le bpm instantané testé.

7
– On calcule la période Ti du peigne de Dirac correspondant à BP M c en utilisant la
formule
60
Ti = · f s.
BP Mc
– On calcule le peigne de Dirac et sa transformée de Fourier Y [k].
– On calcule finalement l’énergie d’intercorrélation en utilisant la formule :
N
X
EBP M c = X[k] · Y [k]
k=0

– Le rythme de la chanson est donné par la valeur du BPM testé pour laquelle cette
quantité est maximale.
Le code source de cet algorithme est donné en annexe, au paragraphe A.2.
La figure 2.1 illustre le fonctionnement de l’algorithme sur le morceau amber. Sur la
courbe qui donne l’énergie de la corrélation de la chanson avec les peignes, on observe
un maximum à 131 BPM, qui est le rythme de la chanson.

2.1.3. Limitations
Cet algorithme présente quelques défauts :
– il est bien trop gourmand en temps de calcul pour être éxécuté en temps réel. Le
calcul des transformées de Fourier prend énormément de temps.
– il ne fonctionnera pas du tout pour les chansons trop riches, dans lesquelles on ne
voit pas des pics se dégager.
Par contre, il présente l’avantage majeur d’être utilisable directement sur des chansons
dont le rythme varie. Par exemple, si une chanson présente deux beats par période, une
période sur 4, cet algorithme sera insensible à cette difficulté.

2.2. Autocorrélation de la chanson


Cette méthode s’inspire des travaux de Judith C. Brown [Bro03], qui a eu l’idée d’uti-
liser l’autocorrélation pour déterminer le meter d’une chanson.

2.2.1. Principe
Plutôt que de tester la ressemblance de la chanson avec un peigne de fréquence arbi-
traire, on exploite le fait que la chanson est périodique et se ressemble donc à elle-même
décalée dans le temps. Pour en trouver le rythme, on prend l’ensemble du morceau, on
le décale de 4 beats à 100 BPM, et on regarde la corrélation entre ces deux extraits. On
recommence l’opération à 101 BPM, et ainsi de suite jusqu’à une borne qu’on s’est fixée
(à 160 BPM par exemple).
On obtient ainsi la ressemblance de la chanson avec elle-même décalée. Un exemple
est donné en figure 2.2. Il suffit de repérer le maximum de cette courbe et de lire le BPM
correspondant pour avoir le rythme de la chanson.

8
Figure 2.1.: Méthode d’intercorrélation avec un peigne de Dirac

9
Figure 2.2.: Méthode d’autocorrélation

10
2.2.2. Implémentation
Le code source de cette méthode est donné en annexe, paragraphe A.2.
1. Pour chacun des BPMs à tester, calculer l’indice dont il faut décaler la chanson :
4 · 60 · f s
decalage =
BP M
2. Pour chacun de ces décalages, calculer l’autocorrélation de la chanson x[k], k =
1 . . . n avec elle-même décalée dans le temps, et normaliser par la durée de la
superposition :
k=n−decalage
X x(k) · x(k + decalage)
correl(decalage) =
k=1
n − decalage

3. Le BPM de la chanson est donné par le maximum de cette courbe.

2.2.3. Avantages et inconvénients


Cette méthode présente des avantages :
– elle est assez robuste et fonctionne sur quasiment n’importe quel type de morceau,
pour peu qu’on puisse y repérer des périodicités, et ce même s’il n’y a pas de batte-
ments à proprement parler ; de même, si la chanson présente des passages “vides”,
cela ne pose aucun problème ;
– elle est totalement autonome, et ne nécessite aucun paramètre complémentaire pour
fonctionner ;
– elle permet d’obtenir un résultat très précis.
Elle présente néanmoins un inconvénient majeur, qui est son temps d’exécution. De plus,
elle est incapable de repérer la position des beats.

2.3. Méthode de détection des crêtes


Cette méthode se base sur l’idée que la musique présente périodiquement des pics
d’énergie. Pour détecter ceux-ci, on suit la crête du signal, comme Hess le fait sur des
signaux de parole pour en déterminer le pitch ([Hes83], page 195).
Une méthode similaire, qui consiste à détecter les écarts entre l’énergie locale et
l’énergie moyenne, est décrite en annexe B.

2.3.1. Principe
L’algorithme, dont le listing est donné en annexe au paragraphe A.3, procède comme
suit :
1. On commence par faire un filtrage passe-bas de la chanson pour lisser la courbe sur
laquelle on travaille. Pour ce faire, on calcule l’énergie moyenne de la chanson en
chacun des points de calcul. Pour accélérer ce calcul, on suréchantillonne le signal.

11
2. On construit un signal “alpiniste” qui va grimper les crêtes qu’il rencontre et re-
descendre en deltaplane. En des termes plus mathématiques, si x[k] est l’énergie
du signal musical, alors h[k] le signal alpiniste est défini par

h[1] = x[1]
(
x[k] si x[k] ≥ h[k − 1] − ε
h[k] =
h[k − 1] − ε sinon (dcroissance linaire)

3. Chaque fois que le signal alpiniste h est en train d’escalader, i.e. de recopier x, on
est sur un beat. Ailleurs, on n’est pas sur un beat.
4. À la fin du morceau, on compte le nombre de tels beats et on divise par la longueur
du morceau pour connaı̂tre son tempo.

La figure 2.3 montre l’algorithme en situation sur un morceau présentant des pics nets.

2.3.2. Implémentation
L’implémentation de cet algorithme soulève néanmoins quatre problèmes, que nous
allons résoudre :
– Au début du morceau, l’algorithme considère toujours qu’on est sur un pic, puisqu’il
faut recopier x pour initialiser h. Pour éviter ce désagrément, on enregistre l’altitude
des premiers pics, et on estime qu’il ne s’agissait pas de pics si on en rencontre un
ultérieurement qui est sensiblement plus grand, par exemple un pic qui monte 40 %
plus haut.
– On a besoin d’un nombre entier de périodes pour pouvoir faire la division. Pour
obtenir ce résultat, une fois les pics repérés, on découpe le morceau de sorte à
obtenir pile un multiple de la période, en commençant le découpage juste avant le
premier (vrai) pic, et en le terminant juste avant le dernier pic. En divisant cette
durée par le nombre de beats qu’elle contient, on arrive à une mesure précise du
tempo.
– Si les pics ne sont pas suffisamment raides, c’est-à-dire si l’énergie met du temps
à augmenter, l’algorithme risque de considérer que plusieurs pics se sont présentés.
On laisse donc un peu de temps à l’alpiniste pour escalader la montagne (environ
20 ms), afin qu’il arrive au sommet sans qu’on ait l’impression de gravir plusieurs
pics.
– Si deux pics sont trop rapprochés alors qu’il ne s’agit pas de deux beats consécutifs,
la mesure est faussée. On s’affranchit de ce défaut en définissant une durée minimale
entre deux beats consécutifs, qui correspond à cette durée pour le BPM maximal
détectable.
En faisant ainsi, on parvient à obtenir des résultats cohérents avec cet algorithme, sans
rallonger de beaucoup le temps de calcul (il s’agit uniquement de branchements condi-
tionnels et de découpages).

12
Figure 2.3.: Méthode de detéction des crêtes

13
2.3.3. Avantages et inconvénients
Contrairement aux autres algorithmes, celui-ci est très rapide, au point qu’on pourrait
envisager une exécution en temps réel. Le seul calcul lourd effectué est le filtrage passe-
bas, le reste n’est que la comparaison avec des seuils.
De plus, en cas de variation brutale du rythme, on obtient le rythme moyen de la
chanson, là où les autres algorithmes donneraient un résultat sans aucun sens.
Malgré ces avantages certains, il présente des inconvénients majeurs :

• il présuppose que la chanson présente un beat par période, et est donc complète-
ment perdu si elle en présente plus ;

• la constante de décroissance ε doit être réglée pour s’adapter au morceau étudié ;

• si des beats de faible énergie se présentent, alors ils risquent de ne pas être détectés.

C’est donc un excellent algorithme pour des chansons dont le rythme est bien marqué,
mais qui sert difficilement dans les autres cas.

14
Chapitre 3.
Implémentation de “fondu calé”
Une application de cette détection de rythme est la réalisation de transitions entre des
chansons de rythme différent. Pour ce faire, on procède en plusieurs étapes :
1. détection du rythme des deux chansons ;
2. “étirement” des chansons (time stretching) pour qu’elles aient le même rythme ;
3. “calage” des chansons, i.e. superposition des beats de deux chansons ; comme elles
ont même rythme, cette superposition va se maintenir dans le temps ;
4. finalement, passage en douceur d’une chanson à l’autre (fondu).
C’est ainsi qu’opèrent les disc jockeys lorsqu’ils enchaı̂nent deux chansons.

3.1. Précision requise


Cette transition nécessite une grande précision dans le calcul du BPM.

3.1.1. Précision de la mesure du BPM


En effet, disons qu’on veut pouvoir synchroniser deux chansons sur une durée de 30
secondes. Au cours de cette durée, il faudrait qu’il n’y ait pas de différence de rythme
audible entre les deux chansons.
Une oreille non exercée est capable de détecter des décalages de battements à partir
d’un 64ème de période, autrement dit un 16ème de beat. L’indication des BPMs devrait
donc être précise à 0,0625 BPM près, disons 0,05 BPM. Avec une erreur de mesure de
0,05 BPM, on obtient, sur une durée de 30 secondes, un décalage entre beats qui vaut :

beat
0, 05 · 30sec = 0, 25beat,
min
ce qui, si on note x le tempo de la chanson en BPM, correspond à un décalage temporel

0, 25beat 15
beat 1min
= sec
x min 60sec x

Ainsi, pour une chanson à 120 BPM, une erreur de mesure de 0,05 BPM induit, sur
une durée de 30 secondes, un décalage temporel de l’ordre de 125 ms.

15
3.1.2. Qualité du modificateur de rythme
Pour accélérer/ralentir les chansons de façon à pouvoir exploiter la résolution de me-
sure avec son pas de 0,05 BPM, il s’agit d’avoir un algorithme qui permette d’étirer des
chansons de façon très précise.
Pour une chanson à 120 BPM par exemple, il s’agit de pouvoir modifier le rythme
avec un facteur 0, 0417 % si on veut pouvoir réaliser des calages sur des longues durées.

3.2. Implémentation
Décrivons les étapes de l’algorithme de fondu calé.

3.2.1. Mesure du BPM des morceaux


Dans un premier temps, on a besoin des BPMs des morceaux qu’il faut enchaı̂ner. Pour
calculer ceux-ci, on utilise un des algorithmes décrits dans le chapitre 2. Ce calcul étant
assez long, on peut l’effectuer seulement sur une partie des chansons. En particulier, on
peut se contenter d’utiliser la fin du premier morceau pour y calculer le BPM, ainsi que
le début du second morceau. En ne conservant que ces parties des chansons, on accélère
le processus de calcul, tout en s’assurant que la mesure est fiable, puisque le BPM risque
moins de varier sur des parties courtes de chansons.

3.2.2. Time stretching


On accorde ensuite le rythme des deux chansons. Pour cela, nous avons besoin d’un
algorithme dit de time stretching permettant d’étirer ou de compresser temporellement
un morceau musical ou de voix sans en déformer la tonalité (sans que Celine Dion
emprunte la voix de Barry White, par exemple).
Comme il ne s’agit que d’une question périphérique par rapport au projet initial, nous
nous sommes résolus à chercher un script déjà implémenté. Nous avons commencé par
utiliser un algorithme fourni par l’enseignant encadrant, Jean-Luc Collette, mais il s’est
vite avéré que la précision de celui-ci était insuffisante pour l’utilisation que nous voulions
en faire (cf. paragraphe 3.1.2).
Ainsi nous avons trouvé sur le net une librairie contenant un vocoder tout fait appelé
pVoc dont la précision s’est révélée satisfaisante. Le fichier utile dans ce répertoire est
stretchFile.m et nous l’avons modifié de façon à ce qu’il renvoie un vecteur et non
un fichier d’extension .wav comme c’était le cas à l’origine. stretchFile prend comme
argument un fichier d’extension .wav ainsi qu’un rapport de transformation sous forme
du quotient de la longueur finale souhaitée sur la longueur initiale du morceau.
Le fichier Matlab qui permet d’utiliser cet algorithme s’appelle mettre_au_bpm.m.

3.2.3. Superposition des morceaux


Pour superposer les morceaux, on a besoin de connaı̂tre la position des pics dans
chacun d’eux. On obtient celle-ci en cherchant le maximum de l’intercorrélation de la

16
chanson avec un peigne de Dirac au même BPM que la chanson.
Partant de là, on superpose les chansons de sorte qu’elles se recouvrent pendant la
durée souhaitée de la transition, tout en ayant leurs beats calés. Autrement dit, on fait
en sorte que les deux peignes soient confondus.

3.2.4. Fondu
Le résultat de l’opération est obtenu en gardant le début de la première chanson, accolé
au fondu de la fin de la première chanson avec le début de la deuxième, le tout suivi par
la fin de la deuxième chanson.
Le fondu est construit en sommant le fondu sortant du premier morceau avec le fondu
entrant du deuxieme morceau. Pour réaliser un fondu sortant, on multiplie terme à terme
la fin du morceau par un triangle décroissant de 1 à 0, de largeur égale à la durée du
fondu. Pour réaliser un fondu entrant, on multiplie par le triangle complémentaire, i.e.
le triangle croissant obtenu en soustrayant le premier à un vecteur de 1.

3.2.5. Reconstitution en un seul morceau


Il ne reste plus qu’à recoller les différentes parties de morceaux de musiques, c’est-à-dire
les mettre bout à bout. On commence par la partie du premier morceau située avant le
premier pic de la section finale testée, on lui accole la partie “fondu” préalablement calée
comme expliqué ci dessus, il ne reste plus alors qu’à terminer en accolant la partie du
second morceau située après l’extrait impliqué dans le fondu. Reste à écouter le morceau
ainsi synthétisé.

17
18
Chapitre 4.
Interface graphique du programme de
“fondu calé”
Nous avons réalisé une interface graphique pour la synthèse d’une transition, ce para-
graphe a pour but de décrire son utilisation.
L’interface permettant d’effectuer le “fondu calé” est très simple d’utilisation.
En lançant synchro morceau.m une fenêtre (figure : 4.1) apparait.
En cliquant sur le bouton “charger” un menu de selection du fichier se superpose à la
fenêtre initiale (figure : 4.2). On peut naviguer dans nos données pour trouver le fichier
d’extension wav désiré.
Une fois sélectionné le morceau est affiché dans une fenêtre sous le menu de sélection
avec sa durée (figure : 4.3).
On peut sur le même mode sélectionner le second morceau.
Une fois les deux pistes chargées, il ne reste plus qu’à sélectionner le Bpm visé et la
durée de transition souhaitée puis cliquer sur le bouton calculer.
Après un temps de calcul conséquent s’affiche la fenêtre figure 4.3.
Le résultat du calcul s’affiche sous forme de trois fenêtres. La première qui reprend
l’interface graphique générale présente le graphique de la partie dite de transition avec
les peignes de Dirac superposés (figure : 4.4). Deux autres fenêtres présentent l’autocor-
rélation des morceaux avec le BPM en abscisse afin de permettre d’évaluer leur cadence
initiale (figure : 4.5).

19
Fig. 4.1.: Fenêtre d’accueil

Fig. 4.2.: Sélection du morceau N˚1

20
Fig. 4.3.: Sélection terminée

Fig. 4.4.: Représentation de la transition

21
Fig. 4.5.: Autocorrélations et rythmes initiaux

22
Conclusion
Nous avons implémenté trois algorithmes de détection du tempo d’une chanson :
– la ressemblance spectrale avec un peigne de Dirac ;
– l’autocorrélation de la chanson avec elle-même ;
– la détection des pics d’énergie par crêtes.
Les limites d’utilisation de ces algorithmes sont illustrés par le tableau 4.1, qui compare
leurs possibilités. Le tableau 4.2 donne leurs performances sur deux morceaux de test.
Dans tous les cas, pour s’affranchir des variations lentes du tempo, il faut prendre un
extrait de 5 secondes dans la chanson et appliquer les algorithmes sur ce court morceau.
Dès lors on considère que le tempo de la chanson ne varie pas au cours de celle-ci ou très
peu et que cette partie de la chanson est représentative du reste au niveau tempo.

Possibilité Ressemblance peigne Autocorrélation Crête énergie


temps réel non non oui
rythme compliqué oui oui non
chanson “riche” non oui non
variation brutale du tempo non non oui
autonome = aucun réglage oui oui non

Tab. 4.1.: Comparaison des caractéristiques des algorithmes

23
Extrait utilisé amber clamar
BPM Temps de calcul BPM Temps de calcul
Autocorrélation 131 6.9s 129 6.9s
Crêtes énergie 133 0.5s 129 0.43s
Ressemblance peigne 131 48.32s 155 48.35s

Table 4.2.: Performance des algorithmes

24
Bibliographie
[Sch97] Eric D. Scheirer, Tempo and beat analysis of acoustic musical signals, Acoustical
Society of America, 1997
[Sch00] Eric D. Scheirer, Music-Listening Systems, MIT, 2000
[Bro03] Judith C. Brown, Determination of the meter of musical scores by autocorrela-
tion, J. Acoust. Soc. Am., 2003
[Pat03] Frédéric Patin, Beat Detection Algorithms, http ://[Link], 2003
[Alg] Masoud Alghoniemy and Ahmed H. Tewfik, Rhythm and periodicity detection in
polyphonic music
[McK04] Martin F. McKinney & Dirk Moelants, Extracting the perceptual tempo from
music, Universitat Pompeu Fabra, 2004
[Hes83] Wolfgang Hess, Pitch Determination of Speech Signals : Algorithms and
Devices,Springer-Verlag Berlin, 1983

25
26
Annexe A.
Code source
Cette annexe contient les codes source du projet. Les fichiers d’interface ne sont pas
inclus.

A.1. calcul bpm.m


function v a r a r g o u t = c a l c u l b p m ( v a r a r g i n )
% CALCUL BPM M− f i l e f o r c a l c u l b p m . f i g
% CALCUL BPM, by i t s e l f , c r e a t e s a new CALCUL BPM or r a i s e s t h e e x i s t i n g
% singleton ∗.
%
% H = CALCUL BPM r e t u r n s t h e h a n d l e t o a new CALCUL BPM or t h e h a n d l e t o
% the e x i s t i n g singleton ∗.
%
% CALCUL BPM( ’CALLBACK’ , h O b j e c t , eventData , h a n d l e s , . . . ) c a l l s t h e l o c a l
% f u n c t i o n named CALLBACK i n CALCUL BPM.M w i t h t h e g i v e n i n p u t arguments .
%
% CALCUL BPM( ’ Property ’ , ’ Value ’ , . . . ) c r e a t e s a new CALCUL BPM or r a i s e s t h e
% existing singleton ∗. S t a r t i n g from t h e l e f t , p r o p e r t y v a l u e p a i r s a r e
% a p p l i e d t o t h e GUI b e f o r e c a l c u l b p m O p e n i n g F u n c t i o n g e t s c a l l e d . An
% u n r e c o g n i z e d p r o p e r t y name or i n v a l i d v a l u e makes p r o p e r t y a p p l i c a t i o n
% stop . A l l i n p u t s are passed to calcul bpm OpeningFcn v i a varargin .
%
% ∗ See GUI O p t i o n s on GUIDE’ s T o o l s menu . Choose ”GUI a l l o w s o n l y one
% i n s t a n c e t o run ( s i n g l e t o n ) ”.
%
% See a l s o : GUIDE, GUIDATA, GUIHANDLES

% E d i t t h e a b o ve t e x t t o modify t h e r e s p o n s e t o h e l p c a l c u l b p m

% L a s t M o d i f i e d by GUIDE v2 . 5 09−Jun−2005 1 0 : 2 4 : 4 1

% Begin i n i t i a l i z a t i o n code − DO NOT EDIT


gui Singleton = 1;
g u i S t a t e = s t r u c t ( ’ gui Name ’ , mfilename , . . .
’ gui Singleton ’ , gui Singleton , . . .
’ gui OpeningFcn ’ , @calcul bpm OpeningFcn , . . .
’ gui OutputFcn ’ , @calcul bpm OutputFcn , . . .
’ g u i L a yo u t F c n ’ , [] , ...
’ gui Callback ’ , []);
i f nargin & i s s t r ( v a r a r g i n { 1 } )
gui State . gui Callback = str2func ( varargin {1});
end

i f nargout
[ v a r a r g o u t { 1 : nargout } ] = g u i m a i n f c n ( g u i S t a t e , v a r a r g i n { : } ) ;
else

27
gui mainfcn ( gui State , varargin { : } ) ;
end
% End i n i t i a l i z a t i o n code − DO NOT EDIT

% −−− E x e c u t e s j u s t b e f o r e c a l c u l b p m i s made v i s i b l e .
function c al cu l b pm O pe ni ng F c n ( hObject , e v e n t d a t a , h a n d l e s , v a r a r g i n )
% This f u n c t i o n has no o u t p u t a r g s , s e e OutputFcn .
% hObject handle to f i g u r e
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
% varargin command l i n e arguments t o c a l c u l b p m ( s e e VARARGIN)

% Choose d e f a u l t command l i n e o u t p u t f o r c a l c u l b p m
h a n d l e s . output = hObject ;

% Update h a n d l e s s t r u c t u r e
g u i d a t a ( hObject , h a n d l e s ) ;

% UIWAIT makes c a l c u l b p m w a i t f o r u s e r r e s p o n s e ( s e e UIRESUME)


% uiwait ( handles . fenetre ) ;

% −−− Outputs from t h i s f u n c t i o n a r e r e t u r n e d t o t h e command l i n e .


function v a r a r g o u t = calcul bpm OutputFcn ( hObject , e v e n t d a t a , h a n d l e s )
% varargout c e l l a r r a y f o r r e t u r n i n g o u t p u t a r g s ( s e e VARARGOUT) ;
% hObject handle to f i g u r e
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

% Get d e f a u l t command l i n e o u t p u t from h a n d l e s s t r u c t u r e


v a r a r g o u t {1} = h a n d l e s . output ;

% −−− E x e c u t e s on b u t t o n p r e s s i n l o a d .
function l o a d C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o l o a d ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
[ FileName , PathName ] = u i g e t f i l e ( ’ ∗ . wav ’ , ’ S e l e c t i o n n e r un f i c h i e r son ’ ) ;
i f i s e q u a l ( FileName , 0 ) | i s e q u a l ( PathName , 0 )
return
end
try
[ son , f e ] = wavread ( f u l l f i l e ( PathName , FileName ) ) ;
catch
return
end
disp ( [ ’ Chargement du f i c h i e r ’ FileName ] ) ;
h a n d l e s . nom = FileName ;
set ( h a n d l e s . f i c h i e r , ’ S t r i n g ’ , FileName ) ;
set ( h a n d l e s . duree , ’ S t r i n g ’ , [ ’ Duree : ’ d u r e e t e x t e ( length ( son ) / f e ) ] ) ;
set ( h a n d l e s . play , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . c h o i x , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . s t a r t , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . text bpm , ’ S t r i n g ’ , ’ ’ ) ;
h a n d l e s . son = son ;
handles . f e = f e ;
h a n d l e s . temps = ( 0 : s i z e ( h a n d l e s . son , 1 ) − 1 ) / h a n d l e s . f e ;
p l o t t e r s o n ( handles ) ;
g u i d a t a ( hObject , h a n d l e s ) ;

28
% −−− E x e c u t e s on b u t t o n p r e s s i n p l a y .
function p l a y C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o p l a y ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
sound ( h a n d l e s . son , h a n d l e s . f e ) ;

% −−− E x e c u t e s d u r i n g o b j e c t c r e a t i o n , a f t e r s e t t i n g a l l p r o p e r t i e s .
function c h o i x C r e a t e F c n ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o c h o i x ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles empty − h a n d l e s n ot c r e a t e d u n t i l a f t e r a l l CreateFcns c a l l e d

% Hint : popupmenu c o n t r o l s u s u a l l y have a w h i t e b a c k g r o u n d on Windows .


% See ISPC and COMPUTER.
if ispc
set ( hObject , ’ BackgroundColor ’ , ’ w h i t e ’ ) ;
else
set ( hObject , ’ BackgroundColor ’ , get ( 0 , ’ d e f a u l t U i c o n t r o l B a c k g r o u n d C o l o r ’ ) ) ;
end

% −−− E x e c u t e s on s e l e c t i o n change i n c h o i x .
function c h o i x C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o c h o i x ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

% H i n t s : c o n t e n t s = g e t ( h O b j e c t , ’ S t r i n g ’ ) r e t u r n s c h o i x c o n t e n t s as c e l l a r r a y
% c o n t e n t s { g e t ( h O b j e c t , ’ Value ’ ) } r e t u r n s s e l e c t e d item from c h o i x

% −−− E x e c u t e s on b u t t o n p r e s s i n s t a r t .
function s t a r t C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o s t a r t ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

t d e p a r t = cputime ;

t e x t e i n t r o = ’ Lancement du c a l c u l −− methode c h o i s i e : ’;

c h o i x = get ( h a n d l e s . c h o i x , ’ Value ’ ) ;
switch choix
case 1
% autocorrelation
disp ( [ t e x t e i n t r o ’ a u t o c o r r e l a t i o n ’ ] ) ;
bpm = c a l c u l a u t o c o r r e l a t i o n ( h a n d l e s . son , h a n d l e s . f e ) ;
case 2
% energie
disp ( [ t e x t e i n t r o ’ d e t e c t i o n d e s p i c s d ’ ’ e n e r g i e ( c r e t e ) ’ ] ) ;
bpm = c a l c u l c r e t e ( h a n d l e s . son , h a n d l e s . f e ) ;
case 3
% p e i g n e s de Dirac
disp ( [ t e x t e i n t r o ’ c o r r e l a t i o n a v e c d e s p e i g n e s de D i r a c ’ ] ) ;
bpm = c a l c u l p e i g n e ( h a n d l e s . son , h a n d l e s . f e ) ;
end
d u r e e = cputime − t d e p a r t ;

disp ( [ ’ Le c a l c u l a u t i l i s e ’ num2str ( d u r e e ) ’ s . de temps CPU ’ ] ) ;

% mise a j o u r de l ’ a f f i c h a g e du BPM dans l a f e n e t r e

29
set ( h a n d l e s . text bpm , ’ S t r i n g ’ , [ num2str (bpm) ’ BPM’ ] ) ,

% p l o t de l a chanson a v e c un p e i g n e en s u r i m p r e s s i o n
disp ( [ ’ Recherche du p e i g n e q u i c a d r e au mieux a v e c l a chanson a ’ . . .
num2str (bpm) ’BPM’ ] ) ;
p e i g n e = d o n n e r p e i g n e s u p e r p o s i t i o n ( h a n d l e s . son , bpm , h a n d l e s . f e ) ;
p l o t t e r s o n ( handles ) ;
hold on ;
plot ( h a n d l e s . temps , p e i g n e , ’ r ’ ) ;
hold o f f ;

% −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
function q u i t t e r C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o q u i t t e r ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
delete ( h a n d l e s . f e n e t r e ) ;

% p l o t t e h a n d l e s . son dans h a n d l e s . c o u r b e
function p l o t t e r s o n ( h a n d l e s )
axes ( h a n d l e s . c o u r b e ) ;
plot ( h a n d l e s . temps , h a n d l e s . son ) ;
ech = axis ;
axis ( [ ech ( 1 : 2 ) −1 1 ] ) ;
grid on

A.2. calcul peigne.m


% C a l c u l du BPM par a u t o c o r r e l a t i o n ( p h a s e s h i f t i n g )
% P i e r r e F r i t s c h , 8 j u i n 2005
% i n s p i r e par Bro03
%
% bpm = c a l c u l a u t o c o r r e l a t i o n ( son , f s , [ p a s f i n , [ bpm debut , bpm fin ,
% [ pas grossier ] ] ] )
%
% c a l c u l e l e BPM du v e c t e u r son e c h a n t i l l o n n e a l a f r e q u e n c e f s
% a v e c une p r e c i s i o n p a s f i n , en s u p p o s a n t que ce BPM e s t i n c l u s dans l a
% p l a g e [ bpm debut : b p m f i n ] p a r c o u r u e r a p i d e m e n t a v e c une p r e c i s i o n
% de p a s g r o s s i e r

function bpm = c a l c u l a u t o c o r r e l a t i o n ( son , f s , p a s f i n , ...


bpm debut , bpm fin , p a s g r o s s i e r )

% arguments par d e f a u t
pas fin defaut = 0.05;
bpm debut defaut = 8 5 ;
bpm fin defaut = 160;
pas grossier defaut = 1;

s w i t c h nargin
case 6
% rien a faire , youpie !
case 5
pas grossier = pas grossier defaut ;
case 3
pas grossier = pas grossier defaut ;
bpm debut = b p m d e b u t d e f a u t ;
bpm fin = b p m f i n d e f a u t ;
case 2
pas grossier = pas grossier defaut ;
bpm debut = b p m d e b u t d e f a u t ;

30
bpm fin = b p m f i n d e f a u t ;
pas fin = pas fin defaut ;
otherwise
disp ( ’ E r r e u r : pas l e bon nb d ’ ’ arguments ’ ) ;
return ;
end

% i n i t i a l i s a t i o n du c a l c u l
pas = p a s g r o s s i e r ;
trouve grossier = 0;
trouve bpm = 0 ;

%son = son . ˆ 2 ;

while ( trouve bpm == 0 )

% P l a g e de BPMs a p a r c o u r i r :
plage bpm = bpm debut : pas : bpm fin ;

% c o r r e s p o n d a n t , s u r 4 mesures , a d e s d e c a l a g e s ( en e c h a n t i l l o n s ) :
d e c a l a g e = 4 . / plage bpm ∗60∗ f s ;

c o r r e l = zeros ( s i z e ( d e c a l a g e ) ) ;

tic ;
disp ( [ ’ P a r c o u r s de l a p l a g e ’ num2str ( bpm debut ) ’ : ’ . . .
num2str ( pas ) ’ : ’ num2str ( bpm fin ) ’ : ’ ] ) ;
disp ( [ ’ C a l c u l de ’ num2str ( length ( d e c a l a g e ) ) . . .
’ a u t o c o r r e l a t i o n s en c o u r s s u r d e s v e c t e u r s de t a i l l e > ’ ...
num2str ( length ( son ) − d e c a l a g e ( end ) ) ] ) ;

% Pour chacun d e s d e c a l a g e s
f o r i = 1 : length ( d e c a l a g e )
decal = floor ( decalage ( i ) ) ;
% c a c u l e r l ’ i n t e r c o r r e l a t i o n du morceau
% a v e c l u i −meme d e c a l e de d e c a l a g e
% e t n o r m a l i s e r par l a l a r g e u r de l ’ e c h a n t i l l o n

e x t r a i t 2 = son (min( 1 + d e c a l , end ) : end , :);


d u r e e = length ( e x t r a i t 2 ) ;
e x t r a i t 1 = son ( 1 : duree , : ) ;

% Le mean e s t l a pour l e c a s d e s morceaux s t e r e o


% on s e ramene a un s e u l c a n a l
c o r r e l ( i ) = abs (mean(sum( e x t r a i t 1 . ∗ e x t r a i t 2 ) ) / d u r e e ) ;
end

t = toc ;

% R e c u p e r a t i o n du BPM max de ce p a s s a g e
[ c o r r e l m a x , i n d i c e m a x ] = max( c o r r e l ) ;
bpm = plage bpm ( i n d i c e m a x ) ;
disp ( [ ’BPM p r o c h e de ’ num2str (bpm) ’ ( t r o u v e en ’ num2str ( t ) ’ s ) ’ ] ) ;

i f t r o u v e g r o s s i e r == 0
% On v i e n t de f a i r e l e t o u r a v e c un pas g r o s s i e r
trouve grossier = 1;

% l a p r o c h a i n e f o i s on f e r a un r e f i n e m e n t
pas = p a s f i n ;

31
% a u t o u r de l a v a l e u r g r o s s i e r e t r o u v e e i c i
bpm debut = bpm − p a s g r o s s i e r + p a s f i n ;
bpm fin = bpm + p a s g r o s s i e r − p a s f i n ;

% on s a u v e g a r d e l e s r e s u l t a t s pour affichage final


c o r r e l g r o s s i e r d e b u t = c o r r e l (1 : indice max − 1 ) ;
c o r r e l g r o s s i e r f i n = c o r r e l ( indice m a x + 1 : end ) ;
b p m g r o s s i e r d e b u t = plage bpm ( 1 : indice max − 1 ) ;
b p m g r o s s i e r f i n = plage bpm ( i n d i c e m a x + 1 : end ) ;
else
% On v i e n t de f a i r e l e deuxieme passage ( f i n )
trouve bpm = 1 ;
% On r e c o n s t r u i t l ’ e n s e m b l e d e s c o r r e l a t i o n s pour l e t r a c e
correl = [ correl grossier debut correl correl grossier fin ] ;
plage bpm = [ b p m g r o s s i e r d e b u t plage bpm b p m g r o s s i e r f i n ] ;
end
end

figure
plot ( plage bpm , c o r r e l ) ;
t i t l e ( [ ’ Methode de phase s h i f t i n g : ’ num2str (bpm) ’ BPM’ ] ) ;
xlabel ( ’BPM t e s t e ’ ) ;
ylabel ( ’ a u t o c o r r e l a t i o n du morceau ’ ) ;

A.3. calcul crete.m


% C a l c u l du BPM par d e t e c t i o n d e s c r e t e s d ’ e n e r g i e
% P i e r r e F r i t s c h , 8 j u i n 2005
% i n s p i r e par Hess , p . 195
%
% bpm = c a l c u l c r e t e ( son , f s , [ c o e f f d e c r o i s s a n c e , . . .
% [ e c a r t p r e t r a i t e m e n t , [ l a r g e u r m o y e n n a g e , [ bpm max , [ d u r e e m o n t e e ] ] ] ] ] )
%
% c a l c u l e l e BPM du v e c t e u r son e c h a n t i l l o n n e a l a f r e q u e n c e f s
% on compare l a v a l e u r a chaque i n s t a n t a v e c l a v a l e u r o b t e n u e en
% d e c r o i s s a n c e l i n e a i r e avec c o e f f d e c r o i s s a n c e
%
% Au p r e a l a b l e , on c a l c u l e l a moyenne de l ’ e n e r g i e s u r d e s
% t r a n c h e s de l o n g u e u r l a r g e u r m o y e n n a g e , e t on ne f a i t ça que t o u s l e s
% e c a r t p r e t r a i t e m e n t e c h a n t i l l o n s du s i g n a l
% On s u p p o s e que l e BPM a d e t e c t e r ne d e p a s s e pas bpm max pour e l i m i n e r
% l e s f a l s e p o s i t i v e , e t on l a i s s e au s i g n a l l a p o s s i b i l i t e d ’ a t t e i n d r e
% son maximum en du ree mon t e e s e c o n d e s l o r s q u ’ i l monte .

% IL FAUT AU MOINS DEUX PICS ’ p r o p r e s ’ DANS LA CHANSON ! ! ! ! !

function bpm = c a l c u l c r e t e ( son , f s , c o e f f d e c r o i s s a n c e , . . .


e c a r t p r e t r a i t e m e n t , l a r g e u r m o y e n n a g e , bpm max , d u r e e m o n t e e )

% v a l e u r s par d e f a u t
largeur moyennage defaut = 1024;
ecart pretraitement defaut = largeur moyennage defaut /4;
coeff decroissance defaut = 0.0004;

% s i un p i c e s t 40% p l u s grand que l e p r e m i e r p i c d e t e c t e ,


% a l o r s i l e s t c o n s i d e r e comme e t a n t l e p r e m i e r p i c
coeff detection premierPic = 1.4;

% bpm maximal d e t e c t a b l e
% s e r t a c a l c u l e r l ’ e c a r t minimal e n t r e deux p i c s c o n s e c u t i f s
bpm max defaut = 1 6 0 ;

32
% d u r e e de montee d ’ un p i c , en s
duree montee defaut = 0.070;

s w i t c h nargin
case 2
coeff decroissance = coeff decroissance defaut ;
ecart pretraitement = ecart pretraitement defaut ;
largeur moyennage = largeur moyennage defaut ;
bpm max = bpm max defaut ;
duree montee = duree montee defaut ;
case 3
ecart pretraitement = ecart pretraitement defaut ;
largeur moyennage = largeur moyennage defaut ;
bpm max = bpm max defaut ;
duree montee = duree montee defaut ;
case 4
largeur moyennage = largeur moyennage defaut ;
bpm max = bpm max defaut ;
duree montee = duree montee defaut ;
case 5
bpm max = bpm max defaut ;
duree montee = duree montee defaut ;
case 6
duree montee = duree montee defaut ;
case 7
otherwise
disp ( ’ Probleme : pas l e bon nombre d ’ ’ arguments ’ ) ;
return ;
end

% P r e t r a i t e m e n t carrement p a s s e −b a s :
% on r e m p l a c e l e s i g n a l par son e n e r g i e l o c a l e
disp ( ’ P r e t r a i t e m e n t : l i s s a g e de l a c o u r b e par c a l c u l de l ’ ’ e n e r g i e l o c a l e ’ ) ;
disp ( [ ’ s u r ’ num2str ( l a r g e u r m o y e n n a g e ) ’ p o i n t s t o u s l e s ’ . . .
num2str ( e c a r t p r e t r a i t e m e n t ) ’ p o i n t s ’ ] ) ;
i f s i z e ( son , 2 ) ˜= 1
son = mean( son ’ ) ’ ; % p a s s a g e en mono
end

% on s u r e c h a n t i l l o n n e l e s i g n a l
e n e r g i e = zeros ( f l o o r ( length ( son ) / e c a r t p r e t r a i t e m e n t ) , s i z e ( son , 2 ) ) ;

% v e c t e u r temps du s i g n a l s u r e c h a n t i l l o n n e :
t = 0 : ecart pretraitement / fs : . . .
( length ( e n e r g i e ) − 1 ) ∗ e c a r t p r e t r a i t e m e n t / f s ;

% l e c a l c u l de l ’ e n e r g i e moyenne s e f a i t a u t o u r de l ’ e c h a n t i l l o n
% s u r une l a r g e u r l a r g e u r m o y e n n a g e
l a r g = floor ( largeur moyennage / 2 ) ;

tic ;
f o r i = 1 : length ( e n e r g i e )
% p o s i t i o n c o r r e s p o n d a n t e dans son
k = i ∗ ecart pretraitement ;

% c a l c u l de l ’ e n e r g i e moyenne du s i g n a l
e n e r g i e ( i , : ) = mean( son (max( 1 , k − l a r g ) : min( end , k + l a r g ) , : ) . ˆ 2 ) ;
end
d u r e e c a l c u l = toc ;
disp ( [ ’ P r e t r a i t e m e n t : ’ num2str ( length ( e n e r g i e ) ) . . .
’ v a l e u r s o b t e n u e s en ’ num2str ( d u r e e c a l c u l ) ’ s ’ ] ) ;

33
% Traitement proprement d i t
% D e t e c t i o n d e s p i c s d ’ e n e r g i e par d e c r o i s s a n c e l i n e a i r e

% e c a r t minimal e n t r e deux p i c s c o n s e c u t i f s
% exprime en nombre d ’ e c h a n t i l l o n s d ’ e n e r g i e
e c a r t m i n i m a l = round ( 60 ∗ f s / bpm max ∗ 1/ e c a r t p r e t r a i t e m e n t ) ;

% l a r g e u r de montee d ’ un p i c
% exprime en nombre d ’ e c h a n t i l l o n s d ’ e n e r g i e
largeur montee = duree montee ∗ f s ∗ e c a r t p r e t r a i t e m e n t ;

% signal alpiniste
h = zeros ( s i z e ( e n e r g i e ) ) ;

% e n r e g i s t r e m e n t d e s p i c s du s i g n a l
p i c s = zeros ( s i z e ( e n e r g i e ) ) ;

h(1) = energie (1);

% on e n r e g i s t r e l a p o s i t i o n du p r e m i e r p i c
% a i n s i que sa v a l e u r pour e l i m i n e r l e b r u i t du d e b u t
indicePremierPic = 1;
valeurPremierPic = h ( 1 ) ;

% on e n r e g i s t r e l a p o s i t i o n du d e r n i e r p i c
% pour a v o i r un nombre e n t i e r de p e r i o d e s
indiceDernierPic = 1;

% Parcours du v e c t e u r a l a r e c h e r c h e d e s montees b r u s q u e s
f o r i = 2 : length ( e n e r g i e )

h ( i ) = h ( i −1) − c o e f f d e c r o i s s a n c e ;
% Si
i f h ( i ) <= e n e r g i e ( i )
% on v i e n t de r e c o n t r e r un d e b u t de p i c
valeur de h = h( i ) ;
h( i ) = energie ( i ) ;

% Mise a j o u r de l ’ e n r e g i s t r e m e n t du p r e m i e r p i c
i f ( e n e r g i e ( i ) >= v a l e u r P r e m i e r P i c ∗ c o e f f d e t e c t i o n p r e m i e r P i c )
indicePremierPic = i ;
valeurPremierPic = energie ( i ) ;
end
pics ( i ) = 1;

% Post−t r a i t e m e n t
% S i on e s t s u r un p i c e t qu ’ i l y a eu un p i c j u s t e a v a n t
% on e s t v r a i s e m b l a b l e m e n t s u r une montee .
% on en g a r d e l e sommet
p i c s p r e c e d e n t s = p i c s (max( i − l a r g e u r m o n t e e , i − 1 ) : i − 1 ) ;
i f ( p i c s ( i ) ˜= 0 && sum( p i c s p r e c e d e n t s ) ˜= 0 )
p i c s (max( i − l a r g e u r m o n t e e , i − 1 ) : i − 1 ) = zeros ( s i z e ( p i c s p r e c e d e n t s ) ) ;
end

i f sum( p i c s (max( i − e c a r t m i n i m a l , i n d i c e P r e m i e r P i c ) : i − 1 ) ) ˜= 0
% i l y a eu un p i c recemment
% donc c e l u i −c i n ’ en e s t pas un
pics ( i ) = 0;

% on f a i t comme s i on l ’ a v a i t pas vu

34
h( i ) = valeur de h ;
else
% i l n ’ y a pas eu de p i c recemment
% donc c e l u i −c i en e s t un
% c ’ e s t peut−e t r e l e d e r n i e r p i c
indiceDernierPic = i ;
end
end

end

% RESULTAT :
% ==========
n b P i c s = sum( p i c s ( i n d i c e P r e m i e r P i c : i n d i c e D e r n i e r P i c − 1 ) ) ;
dureeTotale = ( indiceDernierPic − indicePremierPic ) ∗ ecart pretraitement / f s ;

disp ( [ num2str ( n b P i c s ) ’ p e r i o d e s u t i l i s e n t une d u r e e de ’ num2str ( d u r e e T o t a l e ) ’ s e c . ’ ]);

% une s i m p l e r e g l e de t r o i s nous d i t combien i l y en a par minute


bpm = n b P i c s / d u r e e T o t a l e ∗ 6 0 ;

figure ;
plot ( t ’ , e n e r g i e , ’ b ’ , t ’ , h , ’ r−− ’ , . . .
t ( i n d i c e P r e m i e r P i c : end ) ’ , p i c s ( i n d i c e P r e m i e r P i c : end ) ∗ v a l e u r P r e m i e r P i c ∗ 1 . 0 5 , ’g ’ );
xlabel ( ’ temps ( s ) ’ ) ;
ylabel ( ’ e n e r g i e moyenne de l a chanson e t p i c s d e t e c t e s ’ ) ;
t i t l e ( [ ’ Methode d e s c r e t e s : ’ num2str (bpm) ’ BPM’ ] ) ;

A.4. calcul peigne.m


% C a l c u l du BPM par r e s s e m b l a n c e ( i n t e r c o r r e l a t i o n ) a v e c un p e i g n e de Dirac
% P i e r r e F r i t s c h , 8 j u i n 2005
% d ’ a p r e s Pat03 , ” F i l t e r i n g rhythm d e t e c t i o n ”
%
% bpm = c a l c u l p e i g n e ( son , f s )
%
% c a l c u l e l e BPM du v e c t e u r son e c h a n t i l l o n n e a l a f r e q u e n c e f s

function bpm = c a l c u l p e i g n e ( son , f s , p a s f i n , ...


bpm debut , bpm fin , p a s g r o s s i e r )

% arguments par d e f a u t
pas fin defaut = 0.05;
bpm debut defaut = 8 5 ;
bpm fin defaut = 160;
pas grossier defaut = 1;

s w i t c h nargin
case 6
% rien a faire , youpie !
case 5
pas grossier = pas grossier defaut ;
case 3
pas grossier = pas grossier defaut ;
bpm debut = b p m d e b u t d e f a u t ;
bpm fin = b p m f i n d e f a u t ;
case 2
pas grossier = pas grossier defaut ;
bpm debut = b p m d e b u t d e f a u t ;
bpm fin = b p m f i n d e f a u t ;

35
pas fin = pas fin defaut ;
otherwise
disp ( ’ E r r e u r : pas l e bon nb d ’ ’ arguments ’ ) ;
return ;
end

% i n i t i a l i s a t i o n du c a l c u l
pas = p a s g r o s s i e r ;
trouve grossier = 0;
trouve bpm = 0 ;

% l o n g u e u r du f i c h i e r son
l o n g u e u r = length ( son ) ;

i f s i z e ( son , 2 ) ˜= 1
son = mean( son ’ ) ’ ; % p a s s a g e en mono
end

while ( trouve bpm == 0 )

% P l a g e de BPMs a p a r c o u r i r :
plage bpm = bpm debut : pas : bpm fin ;

e n e r g i e = zeros ( s i z e ( plage bpm ) ) ;

tic ;
disp ( [ ’ P a r c o u r s de l a p l a g e ’ num2str ( bpm debut ) ’ : ’ ...
num2str ( pas ) ’ : ’ num2str ( bpm fin ) ’ : ’ ] ) ;

% Pour chacun d e s BPMs


f o r i = 1 : length ( plage bpm )

% g e n e r a t i o n d ’ un p e i g n e de Dirac au bon BPM


% n e c e s s i t e de f a i r e t a i r e l e s w a r n i n g s ( i n d i c e s non e n t i e r s )
p e r i o d e = 60/ plage bpm ( i ) ∗ f s ; % p e r i o d e du p e i g n e
e t a t w a r n i n g = warning ; warning o f f ;
p e i g n e = zeros ( l o n g u e u r , 1 ) ;
p e i g n e ( 1 : p e r i o d e : l o n g u e u r ) = 1 ; % c r e a t i o n du p e i g n e
warning ( e t a t w a r n i n g ) ; % r e a c t i v a t i o n d e s warning

e n e r g i e ( i ) = sum( abs ( f f t ( son ) . ∗ f f t ( p e i g n e ) ) . ˆ 2 ) ;


end

t = toc ;

% R e c u p e r a t i o n du BPM max de ce p a s s a g e
[ e n e r g i e m a x , i n d i c e m a x ] = max( e n e r g i e ) ;
bpm = plage bpm ( i n d i c e m a x ) ;
disp ( [ ’BPM p r o c h e de ’ num2str (bpm) ’ ( t r o u v e en ’ num2str ( t ) ’ s ) ’ ] ) ;

i f t r o u v e g r o s s i e r == 0
% On v i e n t de f a i r e l e t o u r a v e c un pas g r o s s i e r
trouve grossier = 1;

% l a p r o c h a i n e f o i s on f e r a un r e f i n e m e n t
pas = p a s f i n ;

% a u t o u r de l a v a l e u r g r o s s i e r e t r o u v e e i c i
bpm debut = bpm − p a s g r o s s i e r + p a s f i n ;
bpm fin = bpm + p a s g r o s s i e r − p a s f i n ;

% on s a u v e g a r d e l e s r e s u l t a t s pour a f f i c h a g e f i n a l

36
e n e r g i e g r o s s i e r d e b u t = e n e r g i e (1 : indice max − 1 ) ;
e n e r g i e g r o s s i e r f i n = e n e r g i e ( i n d i c e m a x + 1 : end ) ;
b p m g r o s s i e r d e b u t = plage bpm ( 1 : i n d i c e m a x − 1 ) ;
b p m g r o s s i e r f i n = plage bpm ( i n d i c e m a x + 1 : end ) ;
else
% On v i e n t de f a i r e l e deuxieme p a s s a g e ( f i n )
trouve bpm = 1 ;
% On r e c o n s t r u i t l ’ e n s e m b l e d e s c o r r e l a t i o n s pour l e t r a c e
energie = [ energie grossier debut energie energie grossier fin ] ;
plage bpm = [ b p m g r o s s i e r d e b u t plage bpm b p m g r o s s i e r f i n ] ;
end
end

figure
plot ( plage bpm , e n e r g i e ) ;
t i t l e ( [ ’ Methode de r e s s e m b l a n c e a v e c un p e i g n e : ’ num2str (bpm) ’ BPM’ ] ) ;
xlabel ( ’BPM du p e i g n e de D i r a c ’ ) ;
ylabel ( ’ e n e r g i e de l a c o r r e l a t i o n du morceau a v e c l e p e i g n e ’ ) ;

A.5. donner peigne superposition.m


% Recherche de l a p o s i t i o n o p t i m a l e d ’ un p e i g n e de Dirac
% pour s u p e r p o s i t i o n au−d e s s u s d ’ une chanson de bpm connu
% P i e r r e F r i t s c h , 8 j u i n 2005
%
% p e i g n e = d o n n e r p e i g n e s u p e r p o s i t i o n ( v e c t e u r s o n , bpm , f s )

function p e i g n e = d o n n e r p e i g n e s u p e r p o s i t i o n ( v e c t e u r s o n , bpm , f s )

% l o n g u e u r du v e c t e u r son donne en e n t r e e
l o n g u e u r s o n = length ( v e c t e u r s o n ) ;

% p a s s a g e en mono s i l e son e s t en s t e r e o
i f ( s i z e ( v e c t e u r s o n , 2 ) == 2 )
v e c t e u r s o n = mean( v e c t e u r s o n ’ ) ’ ;
end

% c a l c u l de l a d u r e e e n t r e 2 b e a t s c o n s e c u t i f s a p a r t i r du BPM
p e r i o d e = 60/bpm ∗ f s ;

% d e s a c t i v a t i o n des warnings
% ( on va m a n i p u l e r d e s i n d i c e s pas e n t i e r s , mais c ’ e s t f a i t e x p r e s )
e t a t w a r n i n g = warning ;
warning o f f ;

% on s e d e b r o u i l l e pour que l e p e i g n e c o n t i e n n e un nombre e n t i e r


% de p e r i o d e s
l o n g u e u r = round ( p e r i o d e ∗ c e i l ( l o n g u e u r s o n / p e r i o d e ) ) ;

% c r e a t i o n du p e i g n e de d i r a c
p e i g n e = zeros ( l o n g u e u r , 1 ) ;
peigne ( 1 : periode : longueur ) = 1;

% r e a c t i v a t i o n d e s warning a l ’ e t a t pre−d e s a c t i v a t i o n
warning ( e t a t w a r n i n g ) ;

% on c o m p l e t e l e v e c t e u r son a v e c d e s z e r o s pour qu ’ i l a i t
% l a meme t a i l l e que l e p e i g n e e t on en g a r d e l a v a l e u r a b s o l u e
% pour qu ’ i l r e s s e m b l e d a v a n t a g e a un p e i g n e de p i c s = +1
v e c t e u r s o n = [ abs ( v e c t e u r s o n ) ’ zeros ( l o n g u e u r − l o n g u e u r s o n , 1 ) ’ ] ’ ;

37
% c a l c u l de l ’ i n t e r c o r r e l a t i o n s u r une p e r i o d e , pas l a p e i n e d ’ a l l e r
% plus loin puisque c ’ est periodique . . .
[ c , l a g s ] = xcorr ( vecteur son , peigne , c e i l ( periode ) , ’ unbiased ’ ) ;

% r e c u p e r a t i o n du max de c e t t e i n t e r c o r r e l a t i o n
[ bof , d e c a l ] = max( c ) ;

% d e c a l a g e du p e i g n e
peigne = c i r c s h i f t ( peigne , l a g s ( decal ) ) ;

% on coupe l e p e i g n e pour qu ’ i l a i t l a meme l o n g u e u r que l e f i c h i e r


% d ’ entree
peigne = peigne (1 : longueur son ) ;

A.6. synchro morceaux.m


function v a r a r g o u t = s y n c h r o m o r c e a u x ( v a r a r g i n )
% SYNCHRO MORCEAUX M− f i l e f o r sy n ch r o m or c ea u x . f i g
% SYNCHRO MORCEAUX, by i t s e l f , c r e a t e s a new SYNCHRO MORCEAUX or r a i s e s t h e e x i s t i n g
% singleton ∗.
%
% H = SYNCHRO MORCEAUX r e t u r n s t h e h a n d l e t o a new SYNCHRO MORCEAUX or t h e h a n d l e t o
% the e x i s t i n g singleton ∗.
%
% SYNCHRO MORCEAUX( ’CALLBACK’ , h O b j e c t , eventData , h a n d l e s , . . . ) c a l l s t h e l o c a l
% f u n c t i o n named CALLBACK i n SYNCHRO MORCEAUX.M w i t h t h e g i v e n i n p u t arguments .
%
% SYNCHRO MORCEAUX( ’ Property ’ , ’ Value ’ , . . . ) c r e a t e s a new SYNCHRO MORCEAUX or r a i s e s t h e
% existing singleton ∗. S t a r t i n g from t h e l e f t , p r o p e r t y v a l u e p a i r s a r e
% a p p l i e d t o t h e GUI b e f o r e s y n c h r o m o r c e a u x O p e n i n g F u n c t i o n g e t s c a l l e d . An
% u n r e c o g n i z e d p r o p e r t y name or i n v a l i d v a l u e makes p r o p e r t y a p p l i c a t i o n
% stop . A l l i n p u t s a r e p a s s e d t o synchro morceaux OpeningFcn v i a v a r a r g i n .
%
% ∗ See GUI O p t i o n s on GUIDE’ s T o o l s menu . Choose ”GUI a l l o w s o n l y one
% i n s t a n c e t o run ( s i n g l e t o n ) ”.
%
% See a l s o : GUIDE, GUIDATA, GUIHANDLES

% E d i t t h e a b o ve t e x t t o modify t h e r e s p o n s e t o h e l p sy n ch r o m or c ea u x

% L a s t M o d i f i e d by GUIDE v2 . 5 09−Jun−2005 1 5 : 2 3 : 0 8

% Begin i n i t i a l i z a t i o n code − DO NOT EDIT


gui Singleton = 1;
g u i S t a t e = s t r u c t ( ’ gui Name ’ , mfilename , . . .
’ gui Singleton ’ , gui Singleton , . . .
’ gui OpeningFcn ’ , @synchro morceaux OpeningFcn , . . .
’ gui OutputFcn ’ , @synchro morceaux OutputFcn , . . .
’ g u i L a yo u t F c n ’ , [] , ...
’ gui Callback ’ , []);
i f nargin & i s s t r ( v a r a r g i n { 1 } )
gui State . gui Callback = str2func ( varargin {1});
end

i f nargout
[ v a r a r g o u t { 1 : nargout } ] = g u i m a i n f c n ( g u i S t a t e , v a r a r g i n { : } ) ;
else
gui mainfcn ( gui State , varargin { : } ) ;
end
% End i n i t i a l i z a t i o n code − DO NOT EDIT

38
% −−− E x e c u t e s j u s t b e f o r e syn chro morc ea u x i s made v i s i b l e .
function synchro morceaux OpeningFcn ( hObject , e v e n t d a t a , h a n d l e s , v a r a r g i n )
% This f u n c t i o n has no o u t p u t a r g s , s e e OutputFcn .
% hObject handle to f i g u r e
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
% varargin command l i n e arguments t o s y n c hr o m or c ea u x ( s e e VARARGIN)

% Choose d e f a u l t command l i n e o u t p u t f o r s y n c h ro m or c ea u x
h a n d l e s . output = hObject ;

% Update h a n d l e s s t r u c t u r e
g u i d a t a ( hObject , h a n d l e s ) ;

% UIWAIT makes sy n chro morceau x w a i t f o r u s e r r e s p o n s e ( s e e UIRESUME)


% uiwait ( handles . figure1 ) ;

% −−− Outputs from t h i s f u n c t i o n a r e r e t u r n e d t o t h e command l i n e .


function v a r a r g o u t = synchro morceaux OutputFcn ( hObject , e v e n t d a t a , h a n d l e s )
% varargout c e l l a r r a y f o r r e t u r n i n g o u t p u t a r g s ( s e e VARARGOUT) ;
% hObject handle to f i g u r e
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

% Get d e f a u l t command l i n e o u t p u t from h a n d l e s s t r u c t u r e


v a r a r g o u t {1} = h a n d l e s . output ;

% −−− E x e c u t e s on b u t t o n p r e s s i n l o a d 1 .
function l o a d 1 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o l o a d 1 ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
[ FileName , PathName ] = u i g e t f i l e ( ’ ∗ . wav ’ , ’ S e l e c t i o n n e r un f i c h i e r son ’ ) ;
i f i s e q u a l ( FileName , 0 ) | i s e q u a l ( PathName , 0 )
return
end
try
[ son , f e ] = wavread ( f u l l f i l e ( PathName , FileName ) ) ;
catch
return
end
disp ( [ ’ Chargement du f i c h i e r ’ FileName ] ) ;
h a n d l e s . nom = FileName ;
set ( h a n d l e s . f i c h i e r 1 , ’ S t r i n g ’ , [ FileName ’ ( ’ d u r e e t e x t e ( length ( son ) / f e ) ’ ) ’ ] ) ;
set ( h a n d l e s . play1 , ’ V i s i b l e ’ , ’ on ’ ) ;
h a n d l e s . son1 = son ;
handles . fe1 = f e ;
h a n d l e s . temps1 = ( 0 : s i z e ( h a n d l e s . son1 , 1 ) − 1 ) / h a n d l e s . f e 1 ;
pl o tt er s on 1 ( handles ) ;
set ( h a n d l e s . l o a d 2 , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . f i c h i e r 2 , ’ V i s i b l e ’ , ’ on ’ ) ;
g u i d a t a ( hObject , h a n d l e s ) ;

% −−− E x e c u t e s on b u t t o n p r e s s i n p l a y 1 .
function p l a y 1 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o p l a y 1 ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

39
sound ( h a n d l e s . son1 , h a n d l e s . f e 1 ) ;

% −−− E x e c u t e s on b u t t o n p r e s s i n l o a d 2 .
function l o a d 2 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o l o a d 2 ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
[ FileName , PathName ] = u i g e t f i l e ( ’ ∗ . wav ’ , ’ S e l e c t i o n n e r un f i c h i e r son ’ ) ;
i f i s e q u a l ( FileName , 0 ) | i s e q u a l ( PathName , 0 )
return
end
try
[ son , f e ] = wavread ( f u l l f i l e ( PathName , FileName ) ) ;
catch
return
end
disp ( [ ’ Chargement du f i c h i e r ’ FileName ] ) ;
h a n d l e s . nom = FileName ;
set ( h a n d l e s . f i c h i e r 2 , ’ S t r i n g ’ , [ FileName ’ ( ’ d u r e e t e x t e ( length ( son ) / f e ) ’ ) ’ ] ) ;
set ( h a n d l e s . play2 , ’ V i s i b l e ’ , ’ on ’ ) ;
h a n d l e s . son2 = son ;
handles . fe2 = f e ;
h a n d l e s . temps2 = ( 0 : s i z e ( h a n d l e s . son2 , 1 ) − 1 ) / h a n d l e s . f e 2 ;
p lo tt er s on 2 ( handles ) ;
set ( h a n d l e s . t e x t 8 , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . duree , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . t e x t 7 , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . target bpm , ’ V i s i b l e ’ , ’ on ’ ) ;
set ( h a n d l e s . s t a r t , ’ V i s i b l e ’ , ’ on ’ ) ;
g u i d a t a ( hObject , h a n d l e s ) ;

% −−− E x e c u t e s on b u t t o n p r e s s i n p l a y 2 .
function p l a y 2 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o p l a y 2 ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
sound ( h a n d l e s . son2 , h a n d l e s . f e 2 ) ;

% −−− E x e c u t e s d u r i n g o b j e c t c r e a t i o n , a f t e r s e t t i n g a l l p r o p e r t i e s .
function t a r g e t b p m C r e a t e F c n ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o t a r g e t b p m ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles empty − h a n d l e s n o t c r e a t e d u n t i l a f t e r a l l CreateFcns c a l l e d

% Hint : e d i t c o n t r o l s u s u a l l y have a w h i t e b a c k g r o u n d on Windows .


% See ISPC and COMPUTER.
if ispc
set ( hObject , ’ BackgroundColor ’ , ’ w h i t e ’ ) ;
else
set ( hObject , ’ BackgroundColor ’ , get ( 0 , ’ d e f a u l t U i c o n t r o l B a c k g r o u n d C o l o r ’ ) ) ;
end

function t a r g e t b p m C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o t a r g e t b p m ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

% H i n t s : g e t ( h O b j e c t , ’ S t r i n g ’ ) r e t u r n s c o n t e n t s o f t a r g e t b p m as t e x t
% s t r 2 d o u b l e ( g e t ( h O b j e c t , ’ S t r i n g ’ ) ) r e t u r n s c o n t e n t s o f t a r g e t b p m as a d o u b l e

% −−− E x e c u t e s on b u t t o n p r e s s i n s t a r t .

40
function s t a r t C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o s t a r t ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
% lance l e calcul
bpm = str2num ( get ( h a n d l e s . target bpm , ’ S t r i n g ’ ) ) ;
d u r e e = str2num ( get ( h a n d l e s . duree , ’ S t r i n g ’ ) ) ;

[ h a n d l e s . debut1 , h a n d l e s . f i n 1 , h a n d l e s . debut2 , h a n d l e s . f i n 2 ] . . .
= t r a n s i t i o n ( h a n d l e s . son1 , h a n d l e s . f e 1 , h a n d l e s . son2 , h a n d l e s . f e 2 , . . .
bpm , d u r e e ) ;
set ( h a n d l e s . play3 , ’ V i s i b l e ’ , ’ on ’ ) ;
axes ( h a n d l e s . a x e s 3 ) ;
temps = 0 : 1/ h a n d l e s . f e 1 : ( length ( h a n d l e s . debut2 ) − 1 ) / h a n d l e s . f e 1 ;
plot ( temps , h a n d l e s . f i n 1 , ’ r ’ , temps , h a n d l e s . debut2 , ’ b ’ ) ;
xlabel ( ’ temps ’ ) ;
ylabel ( ’ canaux s u p e r p o s e s ’ ) ;
g u i d a t a ( hObject , h a n d l e s ) ;
p l a y 3 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )

% −−− E x e c u t e s on b u t t o n p r e s s i n p l a y 3 .
function p l a y 3 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o p l a y 3 ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
d u r e e = length ( h a n d l e s . debut2 ) ;

% C o n s t r u c t i o n du fondu
i f s i z e ( h a n d l e s . debut2 , 2 ) == 1
t r i a n g l e e n t r a n t = ( 0 : 1 / ( duree − 1 ) : 1 ) ’ ;
else
t r i a n g l e e n t r a n t ( : , 1 ) = ( 0 : 1 / ( duree − 1 ) : 1 ) ’ ;
t r i a n g l e e n t r a n t ( : , 2 ) = ( 0 : 1 / ( duree − 1 ) : 1 ) ’ ;
end
t r i a n g l e s o r t a n t = ones ( size ( t r i a n g l e e n t r a n t ) ) − t r i a n g l e e n t r a n t ;

mix = t r i a n g l e s o r t a n t . ∗ h a n d l e s . f i n 1 + t r i a n g l e e n t r a n t . ∗ h a n d l e s . debut2 ;

sound ( [ h a n d l e s . debut1 ’ mix ’ h a n d l e s . f i n 2 ’ ] , h a n d l e s . f e 1 ) ;

function p l o t t e r s o n 1 ( h a n d l e s )
axes ( h a n d l e s . a x e s 1 ) ;
plot ( h a n d l e s . temps1 , h a n d l e s . son1 ) ;
ech = axis ;
axis ( [ ech ( 1 : 2 ) −1 1 ] ) ;
grid on

function p l o t t e r s o n 2 ( h a n d l e s )
axes ( h a n d l e s . a x e s 2 ) ;
plot ( h a n d l e s . temps2 , h a n d l e s . son2 ) ;
ech = axis ;
axis ( [ ech ( 1 : 2 ) −1 1 ] ) ;
grid on

% −−− E x e c u t e s d u r i n g o b j e c t c r e a t i o n , a f t e r s e t t i n g a l l p r o p e r t i e s .
function d u r e e C r e a t e F c n ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o d u r e e ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles empty − h a n d l e s n ot c r e a t e d u n t i l a f t e r a l l CreateFcns c a l l e d

41
% Hint : e d i t c o n t r o l s u s u a l l y have a w h i t e b a c k g r o u n d on Windows .
% See ISPC and COMPUTER.
if ispc
set ( hObject , ’ BackgroundColor ’ , ’ w h i t e ’ ) ;
else
set ( hObject , ’ BackgroundColor ’ , get ( 0 , ’ d e f a u l t U i c o n t r o l B a c k g r o u n d C o l o r ’ ) ) ;
end

function d u r e e C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o d u r e e ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

% H i n t s : g e t ( h O b j e c t , ’ S t r i n g ’ ) r e t u r n s c o n t e n t s o f d u r e e as t e x t
% s t r 2 d o u b l e ( g e t ( h O b j e c t , ’ S t r i n g ’ ) ) r e t u r n s c o n t e n t s o f d u r e e as a d o u b l e

% −−− E x e c u t e s d u r i n g o b j e c t c r e a t i o n , a f t e r s e t t i n g a l l p r o p e r t i e s .
function e d i t 2 C r e a t e F c n ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o d u r e e ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles empty − h a n d l e s n o t c r e a t e d u n t i l a f t e r a l l CreateFcns c a l l e d

% Hint : e d i t c o n t r o l s u s u a l l y have a w h i t e b a c k g r o u n d on Windows .


% See ISPC and COMPUTER.
if ispc
set ( hObject , ’ BackgroundColor ’ , ’ w h i t e ’ ) ;
else
set ( hObject , ’ BackgroundColor ’ , get ( 0 , ’ d e f a u l t U i c o n t r o l B a c k g r o u n d C o l o r ’ ) ) ;
end

function e d i t 2 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o d u r e e ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)

% H i n t s : g e t ( h O b j e c t , ’ S t r i n g ’ ) r e t u r n s c o n t e n t s o f d u r e e as t e x t
% s t r 2 d o u b l e ( g e t ( h O b j e c t , ’ S t r i n g ’ ) ) r e t u r n s c o n t e n t s o f d u r e e as a d o u b l e

% −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
function U n t i t l e d 1 C a l l b a c k ( hObject , e v e n t d a t a , h a n d l e s )
% hObject h a n d l e t o U n t i t l e d 1 ( s e e GCBO)
% eventdata r e s e r v e d − t o be d e f i n e d i n a f u t u r e v e r s i o n o f MATLAB
% handles s t r u c t u r e w i t h h a n d l e s and u s e r d a t a ( s e e GUIDATA)
delete ( h a n d l e s . f e n e t r e ) ;

A.7. transition.m
% R e a l i s e une t r a n s i t i o n e n t r e deux morceaux
% P i e r r e F r i t s c h , 8 j u i n 2005
%
% [ debu t1 , p a s s a g e 1 2 , f i n 2 ] = t r a n s i t i o n ( morceau1 , morceau2 , bpm , d u r e e )
%
% C a l c u l e l e BPM d e s deux morceaux , a j u s t e l e u r BPM e t l e s a s s e m b l e
% s u r une d u r e e d u r e e

42
function [ debut1 , f i n 1 , debut2 , f i n 2 ] = t r a n s i t i o n ( morceau1 , f s 1 , morceau2 , f s 2 , bpm , d u r e e )

t = cputime ;

disp ( ’TRAITEMENT DU MORCEAU DE DEPART ’ ) ;


% On c a l c u l e l e BPM du morceau 1 s u r sa f i n
bpm1 = c a l c u l a u t o c o r r e l a t i o n ( morceau1 (max( end − 5 ∗ f s 1 , 1 ) : end , : ) , f s 1 ) ;
% Ajustement de l a v i t e s s e d e s deux morceaux
nouveau1 = mettre au bpm ( morceau1 , f s 1 , bpm1 , bpm ) ;

% on c h e r c h e l a p o s i t i o n du d e r n i e r b e a t du morceau 1
% e t on g a r d e l a d u r e e qu ’ i l r e s t e a p r e s
p e i g n e 1 = d o n n e r p e i g n e s u p e r p o s i t i o n ( nouveau1 , bpm , f s 1 ) ;
reste = 0;
while p e i g n e 1 ( end − r e s t e ) == 0
reste = reste + 1;
i f r e s t e == length ( p e i g n e 1 )
disp ( ’ Duree t r o p c o u r t e ; i m p o s s i b l e de c a l e r l e s morceaux ’ ) ;
return ;
end
end

disp ( ’ ’ ) ;
disp ( ’TRAITEMENT DU MORCEAU D ’ ’ARRIVEE ’ ) ;
% BPM du morceau 2 s u r son d e b u t
bpm2 = c a l c u l a u t o c o r r e l a t i o n ( morceau2 ( 1 : min( end , 5 ∗ f s 2 ) , : ) , f s 2 ) ;
nouveau2 = mettre au bpm ( morceau2 , f s 2 , bpm2 , bpm ) ;
p e i g n e 2 = d o n n e r p e i g n e s u p e r p o s i t i o n ( nouveau2 , bpm , f s 2 ) ;

disp ( ’ c o i n ’ ) ;

% e t l ’ e n d r o i t où c e l u i va s e c a l e r s u r l e morceau 2
% ( p r e s de d u r e e a p r e s l e d e b u t du morceau 2)
i n d i c e = min( d u r e e ∗ f s 2 , length ( p e i g n e 2 ) ) ;
while p e i g n e 2 ( i n d i c e ) == 0
indice = indice − 1;
i f i n d i c e == 0
disp ( ’ Duree t r o p c o u r t e ! Chansons i m p o s s i b l e s a c a l e r ’ )
return
end
end

% d u r e e e f f e c t i v e de l a t r a n s i t i o n
% pour que l e s deux chansons s o i e n t c a l e e s
duree effective = indice + reste ;

debut1 = nouveau1 ( 1 : end − d u r e e e f f e c t i v e ) ;


f i n 1 = nouveau1 ( end − d u r e e e f f e c t i v e + 1 : end ) ;

debut2 = nouveau2 ( 1 : d u r e e e f f e c t i v e ) ;
f i n 2 = nouveau2 ( d u r e e e f f e c t i v e + 1 : end ) ;

t = cputime − t ;
disp ( [ ’ Duree e f f e c t i v e de l a t r a n s i t i o n : ’ num2str ( d u r e e e f f e c t i v e / f s 1 ) ] ) ;
disp ( [ ’ I l a f a l l u ’ num2str ( t ) ’ s e c . CPU pour c e c a l c u l ’ ] ) ;

43
44
Annexe B.
Algorithme basé sur la mesure de l’énergie
Cet algorithme est emprunté à [Pat03]. Nous ne l’avons pas implémenté.

B.1. Principe
Tout signal sonore audible perçu par l’oreille humaine est converti en un signal élec-
trique qui sera analysé par le cerveau. En pratrique, plus l’énergie transportée par le
son est importante, plus le son va paraı̂tre fort. Ainsi un son sera perçu comme un beat
seulement si son énergie instantanée est largement supérieure à l’énergie moyenne reçue
par l’oreille aux instants précedents et suivants, c’est à dire si le cerveau détecte une
variation brutale de l’énergie du son. Selon ce modèle on va calculer l’énergie moyenne
du signal et la comparer avec l’énergie instantanée.

B.2. Première analyse


On note (an ) et (bn ) les échantillons de l’extrait (stéréophonique) pris avec une période
d’échantillonnage Te . (an ) représente la voie de gauche tandis que (bn ) représente celle
de droite. L’énergie instantanée sera par exemple prise comme l’énergie contenue dans
1024 échantillons (ce qui représente environ 5 centièmes de seconde). L’énergie moyenne
ne doit pas être calculée sur les chansons entières car celles-ci contiennent souvent des
variations de rythme et surtout d’intensité. On peut calculer l’énergie moyenne sur 44032
échantillons ce qui représente approximativement 1 seconde de musique. Cela est rendu
possible par la supposition que l’oreille humaine ne se souvient que d’une seconde de son
pour la détection de beat.
L’algorithme peut être décrit de la manière suivante :
1. Calcul de l’énergie instantanée :
i0 +1024
X
e = estereo = edroite + egauche = ak [k]2 + b[k]2
k=i0

2. Calcul de l’énergie moyenne locale : le tampon dans lequel on va stocker les 44032
derniers échantillons va contenir 2 listes, correspondant aux 2 voies, c’est-à-dire
B[0] et B[1] :
1024 44032
X
< E >= B[0][i]2 + B[1][i]2
44100 i=0

45
3. Suite du procédé :
– on deplace les éléments du tampon de 1024 indices vers la droite afin de faire de
la place pour les 1024 échantillons arrivants ;
– on place ces 1024 échantillons en haut du tampon ;
– on compare e à C· < E > avec C constante, pour déterminer si l’on est ou non
en présence d’un beat ;
– si e est plus grand que C· < E >, on a affaire à un beat.
En général une bonne valeur pour la constante est C ' 1, 3.

B.3. Quelques optimisations directes


On peut déjà améliorer l’algorithme simplement en gardant la valeur instantanée de
l’énergie calculée sur 1024 échantillons plutôt que la valeur des 1024 échantillons. On
passe ainsi de 44032 valeurs à 44 valeurs déjà calculées sur 1024 échantillons.
Il est possible de calculer l’énergie moyenne sur un temps supérieur à une seconde
(mais il faut toujours rester sous les 3 secondes). On peut aussi reproduire l’algorithme
plus souvent, par exemple tous les 512 échantillons et plus tous les 1024.
Au niveau algorithmique , ces améliorations se traduisent par :
43
1 X
< E >= · E[i]
43 i=0

À chaque étape, on empile la nouvelle valeur de l’énergie instantanée e dans E[0] et


on supprime E[43] en décalant toutes les valeurs vers la droite.

B.4. Sensibilité de la détection


Le principal problème de cet algorithme est le choix de la constante C.
Par exemple, si on a affaire a de la techno ou a du rap, deux types de musique dans
lesquels les beats sont assez intenses, alors C doit être assez élevée, de l’ordre de 1,4. Si
on a affaire à du rock, c’est à dire à un son beaucoup plus riche, les beats sont moins
distincts et C doit prendre une valeur de l’ordre de 1,1 soit une valeur beaucoup plus
faible.
C peut être calculée en calculant la variance de l’énergie contenue dans le tampon. La
variance va quantifier le caractère plus ou moins affirmé des beats et nous permettre de
calculer la valeur de C. Plus la variance est importante, plus l’algo doit être sensible et
plus la valeur de C doit être faible. La variance peut se calculer avec la formule suivante :
43
1 X
V = · (E[i]− < E >)2
43 i=0
On peut choisir une relation linéaire liant C et V . Par exemple, quand V vaut 200, C
vaut 1 ; et quand V vaut 25, alors C vaut 1,45. De là :

C = (−0.0025714 · V ) + 1.5142857

46
B.5. Efficacité de l’algorithme
L’algorihme avec ajustement de la constante C est très efficace sur le rap et la techno.
La richesse des autres types de musique a souvent tendance à prendre ce programme en
défaut.

47

Vous aimerez peut-être aussi