BPM
BPM
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
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
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.
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.
+∞
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
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.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
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 ;
• 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.
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é.
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.
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
20
Fig. 4.3.: Sélection terminée
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.
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
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.
% 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
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 ) ;
% −−− 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
% −−− 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 ;
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
% 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 ;
% 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
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 ;
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 ’ ) ;
% 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;
% 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 ) ) ;
% 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 ;
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’ ] ) ;
% 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
% P l a g e de BPMs a p a r c o u r i r :
plage bpm = bpm debut : pas : bpm fin ;
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 ) ’ : ’ ] ) ;
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 ’ ) ;
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 ;
% 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 ) ) ;
% 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
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 ) ;
% −−− 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
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 ;
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
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 ;
% 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 ;
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.
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.
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