Vous êtes sur la page 1sur 21

Traiter le signal audio numrique avec Matlab ou Scilab

Jean-Paul Stromboni, Polytech'Nice Sophia, Dpt Sciences Informatiques, SI3 Dure 50 minutes, avec Matlab/Scilab, un vido projecteur, et des hauts parleurs

Aprs ce chapitre, vous devrez savoir comment :


utiliser lenvironnement de MATLAB : fentre de commande, diteur de scripts, appel de fonction et savoir passer Scilab utiliser les langages de scripts de MATLAB et de Scilab excuter des scripts et des fonctions MATLAB (et Scilab) synthtiser des signaux audio numriques composs dharmoniques et dots denveloppes, reproduire le timbre dinstruments de musique tracer des chronogrammes, des spectres, des spectrogrammes,

Le TD n3 utilise Matlab ou Scilab pour :


Synthtiser des signaux audio, reprsenter les chronogrammes, lire et crire au format Wave, calculer et afficher le spectre, etc
2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 1

Utiliser MATLAB (ou Scilab) est un objectif du cours S.S.I.I.


MATLAB (pour MATrix LABoratory) de Mathworks, est un logiciel rput dans le domaine du calcul scientifique. Le dpartement S.I. possde 25 licences MATLAB sur le rseau local de lcole utiliser en travaux dirigs (cf. procdure dinstallation) Pour utiliser hors de lcole, on suggre dinstaller galement Scilab ( tlcharger sur http://www.scilab.org) outil libre, gratuit et multiplateforme trs semblable MATLAB (il est intressant de comparer). Pour apprendre MATLAB, on analyse des exemples tirs de : http://www-gmm.insa-toulouse.fr/~guillaum/AM/ avec laccord de Philippe Guillaume, Professeur l'INSA de Toulouse, et auteur de louvrage : 'Musique et Acoustique : de linstrument lordinateur', collection Herms, diteur Lavoisier.

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 2

Se reprer dans lenvironnement MATLAB (celui de Scilab plus simple contient la plupart des outils de calcul et de trac)
dossier travail

fentre plot

Publish in html fentre edit

fentre de commande .m file

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 3

Utiliser la fentre de commande de Matlab (traduire en Scilab)


>> % en Matlab, le prompt est >> >> N=3 % avec ou sans caractre ';' ? N = 3 >> N=3; >> n >> Message=[S.I.,num2str(N),.]; >> disp(Message) >> help disp % aide succincte % il y a un diteur de ligne de commande % on a droit aux commandes de shell >> pwd, ls, dir, cd % lancer une application MSDOS !notepad % excuter le script MATLAB sinus.m >> sinus % sinus.m doit tre dans le PATH >> format long % 10 chiffres dcimaux % effacer la fentre Command Window >> clc % noter linstruction eval >> eval([la,num2str(3),=440])
// En SCILAB, le prompt est // est un commentaire N=3 N=3; N n Message=[date,string(28), septembre]

disp(Message) help disp // il y a un diteur de ligne commande pwd, dir, cd // lancer une application Windows ou Unix unix(notepad.exe) excuter un script ou une fonction Scilab exec(sinus.sce) // fichiers .sce et .sci sinus // %pi format(20) %pi clc execstr(la3= 440;); la3

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 4

Analyse du script tir du fichier sinus.m et traduction en Scilab


% arpge de sons sinusodaux (Matlab) clear all; close all; Fe = 22050; h = 1/Fe; f0 = 220; T = 1.5; N = 13; fr = f0*[1:1:N]; am = 1; x = []; for k = 1:N % cration d'une enveloppe tr = T*[0 .02 .98 1]; yr = [0 1 1 0]; env = envelop(tr,yr,Fe); % cration du signal sinusodal th = 0:h:T; s = sin(2*pi*fr(k)*th); % application de lenveloppe // arpge de sons sinusodaux (Scilab) clear all; close all; Fe = 22050; h = 1/Fe; f0 = 220; T = 1.5; N = 13; fr = f0*(1:N); am = 1; exec('envelop.sce'); x = []; for k = 1:N tr = T*[0 .02 .98 1]; yr = [0 1 1 0]; env = envelop(tr,yr,Fe); th = 0:h:T; y = sin(2*%pi*fr(k)*th).*env; x = [x, am*y]; T = T*.8; am = am*.8; end plot2d(x) sound(x,Fe); wavwrite(x,Fe,'./scilabsinus.wav');

y = s.*env;
% concatnation x = [x, am*y]; T = T*.8; am = am*.8; end plot(x) wavplay(x, Fe); wavwrite(x, Fe, './sinus.wav');

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 5

Analyser la fonction Matlab cloche tire du fichier cloche.m


function s = cloche(f1,T,Fe) % s = cloche(f1,T,Fe) % imitation d'une cloche % f1 = frquence du principal % Fe = frquence d'chantillonnage % T = dure du son %----------------------------------------h = 1/Fe; th = 0:h:T; f = f1*[0.5 1 1.188 1.530 2.0000 2.470 2.607 ... 2.650 2.991 3.367 4.137 4.487 4.829 5.385 ... 5.863 6.709 8.077 8.547 9.017 9.530 ... 11.026 12.393]; a = [350 950 500 150 700 100 250 370 1000 180 ... 300 100 150 300 100 100 50 20 10 ... 35 5 15]; s = synthad(a,f,0*f,T,Fe); t = T*[0 .001 .01 .4 .6 .9 1]; a = [0 .6 1 .4 .2 .1 0]; env = envelop(t,a,Fe); s = s.*env; End % optionnel

Ligne den tte Commentaire accessible dans laide

vecteur des frquences harmoniques vecteur des amplitudes des composantes frquentielles

allure de la courbe d'enveloppe a(t) a


1 0.6

0.4

0.6

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 6

Analyser la fonction synthad tire du fichier synthad.m


function s = synthad(a,f,p,T,Fe) % s = synthad(a,f,p,T,Fe) % synthse additive % cette fonction cre un son de duree T, % compose des partiels f(n), d'amplitude a(n) % et de phase a l'origine p(n). % Fe est la frquence d'chantillonnage %--------------------------------------% cration du vecteur temps discret dt = 1/Fe; t = 0:dt:T; n = length(t); % cration du son, une boucle ajoute une a une % les composantes frquentielles s = zeros(1,n); K = length(f); for k = 1:K s = s+a(k)*sin(2*pi*f(k)*t+p(k)); end % normalisation pour que les valeurs % restent dans l'intervalle [-0.99 0.99] s = .99*s/max(abs(s));

cumul des harmoniques trouvs dans les vecteurs a : amplitude, f : frquence et p : phase

maximum de s ramen 0.99*max(abs(s))

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 7

Analyser la fonction envelop utilise dans sinus.m et cloche.m


function env = envelop(t,a,Fe) % enveloppe parametree par t et a = env(t), % t contient une liste d'instants t_k % a contient la liste des amplitudes a_k aux instants t_k % env est le son echantillonne a la frequence Fe, % affine par morceaux, tel que env(t_k) = a_k %-------------------------------------------------------lt = length(t); T = t(lt); h = 1/Fe; th = 0:h:T; % test validite de t if t(1) >= T error('t incompatible dans envelop'); end % test compatibilite t et a if lt ~= length(a) error('t et a de longueurs diffrentes'); end % au cas ou t ne serait pas strictement croissant : for k = 2:lt-1 if (t(k) <= t(k-1)) | (t(k) >= t(lt)) t(k) = (t(k-1)+t(lt))/2; end end n = length(th); env = zeros(1,n); ni = lt-1; c = zeros(1,ni+1); b = c; h2 = 0; for k = 1:ni h1 = h2+1; h2 = 1+floor(t(k+1)/h); cb = [t(k) 1; t(k+1) 1]\[a(k) ; a(k+1)]; c = cb(1); b = cb(2); env(h1:h2) = c*th(h1:h2)+b; end env = .99*env/max(env);

a a(k+1) a(k) t(k) t(k+1) t

a= c*t+b pour t(k) < t <t(k+1) Que valent c et b ? Rsoudre a(k)=c*t(k)+b a(k+1)=c*t(k+1)+b
A\B calcule la solution x de A*x = B on s'en sert ici pour trouver les coefficients directeurs c et b de l'enveloppe entre t(k) et t(k+1)

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 8

Utiliser la fonction cloche dans le script gammes


Que ralise le script gammes ? Comment procde ton pour crer la gamme ?
% tir du fichier gammes.m clear all % clavier azerty : notes = ['a','z','e','r','t','y','u','i','o','p', 'q','s', 'd']; Fe = 22050; f0 = 440; % la3 est la premire note temp = 2.^((0:12)/12); % fr = f0*temp; % frquence des notes de la3 la4 T = 1.5; % dure des notes for k = 1:13 % on cre des notes de flute note = notes(k); eval([note '= cloche(fr(k),T,Fe);']); %ou flute end % et on joue : disp('pour jouer, rentrez une note parmi :'); disp('entrer a z e r t y u i o p q s ou d, suivi de enter'); x = 0; % taper x pour terminer note = [1,1]; % length(note)= ? while length(note) >1 note = input('note suivante? (x pour terminer)'); if length(note) == 1 disp('termine'); break end soundsc(note,Fe); % met l'amplitude l'chelle end

efface tout vecteur ligne de caractres continuateur de ligne

a note pour k=1 Pour k=1, eval excute : a = cloche(fr(1),T,fe);

soundsc ramne le signal entre -1 et 1 et le joue

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 9

Et si vous prfrez la flute, comment utiliser le fichier flute.m?


function s = flute(f1,T,Fe) % s = flute(f1,T,Fe) % son flute %---------------------------------------------------h = 1/Fe; th = 0:h:T; nt = length(th); a = [1000 50 80 10 5 2 .1 1]; nh = length(a); N = 1:nh; % synthse additive du spectre f = N*f1; s = synthad(a,f,0*f,T,Fe); % enveloppe t = T*[0 .1 .2 .9 1]; a = [0 .8 1 .8 0]; env = envelop(t,a,Fe); s = s.*env; % ajout de souffle br = bruit(T,Fe); fn = f1/Fe*2; wn = (fn*[.8 1]).^(2); b = fir1(50,wn); br = filter(b,1,br); t = T*[0 .05 .8 1]; a = [0 1 .5 0]; env = envelop(t,a,Fe); br = br.*env; s = s+br/7; s = s/(max(abs(s)));

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 10

Traduction de gammes.m en Scilab dans gammes.sce


//----------------------------//-------------------------------// on fabrique une gamme chromatique au clavier //------------------------------------------------------------clear all getf("envelop.sci"); getf("synthad.sci"); getf("cloche.sci"); // clavier azerty : notes = ['a','z' 'e' 'r' 't' 'y' 'u' 'i' 'o' 'p' 'q' 's' 'd']; Fe = 22050; f0 = 440; // la3 est la premire note temp = 2.^((0:12)/12); // fr = f0*temp; // frquence des notes de la3 la4 T = 1.5; // dure des notes for k = 1:13 // on cre des notes de flute note = notes(k); execstr( strcat([note,'= cloche(fr(k),T,Fe);'])); // ou flute, ou orgue end // et on joue : disp('pour jouer, rentrez une note parmi :'); disp('entrer a z e r t y u i o p q s ou d, suivi de enter'); x = 0; // taper x pour terminer note = a; // length(note)= ? while length(note) >1 note = input('note suivante ?'); if length(note) == 1 disp('termine'); break end sound(note,Fe); // met l'amplitude du son l'chelle end

La fonction getf obsolte est remplace par exec exec("envelop.sci"); // par exemple

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 11

Utiliser le type cell de Matlab, exemple de creegammes.m


%% crer des notes et des airs avec les cellules gamme={'do','dod','re','red','mi','fa','fad','sol','sold','la','lad','si'}; dt=power(2,1/12); for g=1:5 frla=110*2^(g-1); for n=1:length(gamme) eval([gamme{n},num2str(g),'=frla*dt^(n-10);']) end end %%crer une mlodie jouer(la3,.3,1); jouer(si3,.3,0.75); jouer(dod4,.3,0.5); jouer(mi4,.3,.5); jouer(re4,.3,.5); jouer(re4,.3,.5); jouer(fad4,.3,1); jouer(mi4,.3,1); jouer(mi4,.6,1); jouer(la4,.4,1); jouer(sold4,.4,1); jouer(la4,.8,1);

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 12

Voici la fonction jouer utilise par le script creegammes (jouer.m)


function note=jouer(fr,Dur,amp,Fs) % jouer possde 4 arguments, fr est la frquence de la note % dur sa dure en seconde, ampl son amplitude initiale, et Fs % la frquence d'chantillonnage. L'enveloppe est linaire. % Par dfaut, fr= 440Hz, Dur= 1s, amp= 1, et Fs= 8000Hz. % En l'absence d'argument de sortie, la note cre est joue. f=440; D=1; a=1; fe=8000; switch nargin case 1 f=fr; case 2 f=fr; D=Dur; case 3 f=fr; D=Dur; a=amp; case 4 f=fr; D=Dur; a=amp; fe=Fs; end % construire la note t=[0:1/fe:D]; note=a*sin(2*pi*f*t).*(1-t/D); if nargout==0 wavplay(note,fe) end

Traduction Scilab de jouer.m dans jouer.sce :


Function note=jouer(fr, Dur, amp, Fs) // fr est la frquence de la note, Dur est sa dure en seconde, // ampl est son amplitude, Fs la frquence d'chantillonnage. // enveloppe linaire, fr=440Hz, Dur=1s, amp=1, Fs=8kHz nbin=argn(2); //nbout=argn(1);//marche pas, toujours gal 1 ??? f=440; D=1; a=1; fe=8000; select nbin case 1 then f=fr; case 2 then f=fr; D=Dur; case 3 then f=fr; D=Dur; a=amp; case 4 then f=fr; D=Dur; a=amp; fe=Fs; end t=[0:1/fe:D]; note=a*sin(2*%pi*f*t).*(1-t/D); // tester nbout pour reproduire nargout endfunction

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 13

calculer et afficher le spectre avec Matlab


%% paramtrage N=1024 Fe=44100 D=2; f1=880; %% son de cloche s=cloche(f1,D,Fe); wavplay(s,Fe) %% spectre fr=[0:N-1]*Fe/N; sp=abs(fft(s,N))/N; plot(fr(1:N/2),sp(1:N/2)) grid xlabel('frquence Hz') ylabel('spectre') title(['spectre', num2str(N), ... ' points'])

spectre1024 points 0.1 0.08 0.06 0.04 0.02 0

spectre

1 2 frquence Hz

3 x 10
4

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 14

Afficher le spectrogramme avec Matlab


%% spectrogramme d'un arpge s=cloche(f1,D,Fe); s=[s,cloche(5*f1/8,D,Fe),... cloche(3*f1/4,D,Fe)]; wavplay(s,Fe) spectrogram(s,N,0,N,Fe,'yaxis') colorbar % cf. spectrogramme ci-contre %% idem pour un accord acc= cloche(f1,D,Fe)+ ... cloche(5*f1/4,D,Fe)+ ... cloche(3*f1/2,D,Fe); acc= 0.99*acc/max(abs(acc)); wavplay(acc,Fe) spectrogram(acc,N,0,N,Fe,'yaxis') colorbar % non trac
x 10 2
4

-40

-60 1.5 -80 Frequency (Hz)

-100

-120 0.5 -140 0

3 Time

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 15

Traduire le fichier creegammes.m en Scilab (creegammes.sce)


//crer des notes et des airs avec les cellules gamme=['do','dod','re','red','mi','fa','fad','sol','sold','la','lad','si']; [nl,nc]=size(gamme); dt=2^(1/12); for g=1:5, frla=110*2^(g-1); for n=1:nc, execstr([gamme(n)+string(g)+'=frla*dt^(n-10);']) end end //crer une mlodie exec('jouer.sce'); s=jouer(la3,.3,1); s=[s,jouer(si3,.3,0.75)]; s=[s,jouer(dod4,.3,0.5)]; s=[s,jouer(mi4,.3,.5)]; s=[s,jouer(re4,.3,.5)]; s=[s,jouer(re4,.3,.5)]; s=[s,jouer(fad4,.3,1)]; s=[s,jouer(mi4,.3,1)]; s=[s,jouer(mi4,.4,1)]; s=[s,jouer(la4,.4,1)]; s=[s,jouer(sold4,.4,1)]; s=[s,jouer(la4,.4,1)]; sound(s,8000); savewave('majoie.wav',s,8000)

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 16

Traduction en Scilab des deux functions synthad et envelop


function s = synthad(a,f,p,T,Fe) // s = synthad(a,f,p,T,Fe) // synthese additive // cette fonction cree un son de duree T, // compose des partiels f(n), d'amplitude a(n) // et de phase a l'origine p(n). // Fe est la frequence d'echantillonnage //--------------------------------------------// creation du vecteur temps discret dt = 1/Fe; t = 0:dt:T; n = length(t); // creation du son, boucle pour ajouter une a une // les composantes frequentielles s = zeros(1,n); K = length(f); for k = 1:K s = s+a(k)*sin(2*%pi*f(k)*t+p(k)); end // normalisation pour que les valeurs soient // toutes dans l'intervalle [-0.99 0.99] s = .99*s/max(abs(s)); endfunction

function [env] = envelop(t,a,Fe) lt = length(t); T = t(lt); h = 1/Fe; th = 0:h:T; if t(1) >= T // test de validite de t error('t incompatible dans envelop'); end if lt ~= length(a) // test de compatibilit de t et a error('t et a de longueur diffrente dans envelop'); end // au cas o t ne serait pas strictement croissant : for k = 2:lt-1 if (t(k) <= t(k-1)) | (t(k) >= t(lt)) t(k) = (t(k-1)+t(lt))/2; end end n = length(th); env = zeros(1,n); ni = lt-1; c = zeros(1,ni+1); b = c; h2 = 0; for k = 1:ni h1 = h2+1; h2 = 1+floor(t(k+1)/h); cb = [t(k) 1; t(k+1) 1]\[a(k) ; a(k+1)]; c = cb(1); b = cb(2); env(h1:h2) = c*th(h1:h2)+b; end env = .99*env/max(env); endfunction

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 17

Traduire pour Scilab le script Matlab dans cloche.m


function s = cloche(f1,T,Fe) // s = cloche(f1,T,Fe) // imitation d'une cloche // f1 = frquence fondamentale // Fe = frquence dchantillonnage // T = dure du son //--------------------------------------------h = 1/Fe; th = 0:h:T; f = f1*[0.5 1 1.188 1.530 2.0000 2.470 2.607 2.650 2.991 ... 3.367 4.137 4.487 4.829 5.385 5.863 6.709 8.077 ... 8.547 9.017 9.530 11.026 12.393]; a = [350 950 500 150 700 100 250 370 1000 180 300 ... 100 150 300 100 100 50 20 10 ... 35 5 15]; s = synthad(a,f,0*f,T,Fe); t = T*[0 .001 .01 .4 .6 .9 1]; a = [0 .6 1 .4 .2 .1 0]; env = envelop(t,a,Fe); s = s.*env; endfunction 2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 18

Analyser le script ci-dessous, et rpondre aux questions poses


function [sdet,fe]=note(fr, dure,a, fe) % la fonction permet de crer une note sinusodale damplitude a % de frquence fr et de dure dure avec la frquence dchantillonnage fe % par dfaut, fr=440Hz, si a n'est pas prcis, a=0.75, % dure=1 si non prcis, si fe n'est pas prcis, fe=44100Hz % une enveloppe exponentielle est attache la note cre % la note est joue s'il n'y a pas d'argument de sortie % Noter : ce commentaire apparat dans laide : help note if nargin==0, fr=440;dure=1;a=1; fe=44100; end if nargin ==1, dure=1;a=1;fe=44100; end if nargin ==2, a=1;fe=44100; end if nargin ==3, fe=44100; end temps=[0: 1/fe : dure]; env=exp(-temps/(dure/3)); sdet= a*cos(2*pi*temps*fr).*env; if nargout==0, wavplay(sdet, fe), stem(temps, sdet) xlabel('temps (s)'), ylabel('note'),grid end end % optionnel

note.m Quel doit tre le nom du fichier qui le contient ? On saisit >> note; % dans la fentre de commande, quel est le rsultat ? On saisit s=note; % Quel est le rsultat ? Comment utiliser note pour crer un arpge puis pour crer un accord ?
arpege= [note(440), note(5*440/4), note(3*440/2), note(880,2,.5)]; accord= note(440)+note(5*440/4)+note(3*440/2);

2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 19

Lditeur de scripts de MATLAB


Taper edit, ou File/New/m-file, ou utiliser la barre doutils. % est le commentaire %% permet de dcouper le script en cellules excutables une par une Publish in html permet de faire un compte rendu en html des rsultats du Execute Cell script (images comprises) F9 evaluate selection F5 run Lexcution du script ead.m depuis command window : >> ead seulement si le dossier contenant ead.m est dans le Path, ou dans le current directory File/Set Path, modifie le path :
suivi de Add Folder puis Save, et Close Fichiers .sce, ou .sci, ou .txt, ou Les fichiers scripts doivent tre dans le rpertoire de travail, ou il faut prciser leur chemin
Publish html

Dock

En Scilab, faire exec(fichierScript).


2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 20

Ajouter une fonction nouvelle dans MATLAB


Matlab contient dj des fonctions, telles que plot(), wavread() l'utilisateur peut en ajouter, qui doivent respecter les mmes rgles :
Si la fonction est nomme 'notepure', le fichier script doit se nommer 'notepure.m' notepure.m doit se trouver dans le Path !! On appelle notepure depuis un script ou aprs le prompt de commande avec :
notepure(la3.wav, 0.5, 440, 1.5); s = notepure(si.wav, 0.5, 440, 1.5);

Le nombre d'arguments donns l'appel d'une fonction peut varier, c'est Matlab qui gre :
plot(t,s), plot(s), ou encore h=plot(t,s1,t,s2)

Les deux variables 'nargin' et 'nargout' transmettent la fonction appele le nombre d'arguments dentre et de sortie spcifis lors de l'appel. Dans Scilab, il faut excuter linstruction exec(monFichierScript) pour pouvoir appeler les fonctions dfinies dans monFichierScript la dernire ligne endfunction est obligatoire
2011-12, S.S.I.I., SI3, sance 3, Traiter le signal audio numrique avec Matlab ou Scilab, page 21