wolffd@0
|
1 function demo1pitch
|
wolffd@0
|
2
|
wolffd@0
|
3 % Demo 1:Pitch extraction
|
wolffd@0
|
4 % Aims: To study the diverse tools available in the toolbox for pitch
|
wolffd@0
|
5 %extraction.
|
wolffd@0
|
6 % In the following exercises, we will try to extract the pitch contents of various audio files using diverse techniques. All the audio files are included in the ?MIRtoolbox_Demos? folder.
|
wolffd@0
|
7
|
wolffd@0
|
8 %% 1. Analyis of a single chord
|
wolffd@0
|
9
|
wolffd@0
|
10 % Load the audio file 'Amin3.wav'.
|
wolffd@0
|
11 a = miraudio('Amin3')
|
wolffd@0
|
12 %and play it:
|
wolffd@0
|
13 mirplay(a)
|
wolffd@0
|
14
|
wolffd@0
|
15 % Observe the periodicities contained in the signal by computing the autocorrelation function:
|
wolffd@0
|
16 ac = mirautocor(a)
|
wolffd@0
|
17 % The autocorrelation function can also be displayed in the frequency domain (?Freq?), and the frequency range can be specified, for instance between 75 and 2400 Hz:
|
wolffd@0
|
18 ac = mirautocor(ac, 'Freq','Min',75,'Hz','Max',2400,'Hz')
|
wolffd@0
|
19
|
wolffd@0
|
20 % The peaks of the curve indicates the most important periodicities:
|
wolffd@0
|
21 pac = mirpeaks(ac)
|
wolffd@0
|
22 % But the two peaks at the start and end of the curves are meaningless, so should be removed:
|
wolffd@0
|
23 pac = mirpeaks(ac, 'NoBegin','NoEnd')
|
wolffd@0
|
24
|
wolffd@0
|
25 % The corresponding pitch height are given by:
|
wolffd@0
|
26 p = mirpitch(pac)
|
wolffd@0
|
27
|
wolffd@0
|
28 % The actual numerical data (here, the frequency of each pitch) is given by:
|
wolffd@0
|
29 mirgetdata(p)
|
wolffd@0
|
30
|
wolffd@0
|
31 % The resulting pitches can be finally played:
|
wolffd@0
|
32 mirplay(p)
|
wolffd@0
|
33
|
wolffd@0
|
34 % So far, the results do not seem very convincing, do they?
|
wolffd@0
|
35
|
wolffd@0
|
36 pause, close all
|
wolffd@0
|
37
|
wolffd@0
|
38 %% 2. Improving the analysis
|
wolffd@0
|
39
|
wolffd@0
|
40 % Clearly, we need to refine the methods in order to retrieve the notes played in the chord. First of all, the autocorrelation function can be ?generalized?, i.e., ?compressed? by a factor of, for instance, 0.5 (cf. MIRtoolbox User?s Manual at the mirautocor section for an explanation of the 'Compres' option):
|
wolffd@0
|
41 ac = mirautocor(a,'Compres',.5)
|
wolffd@0
|
42
|
wolffd@0
|
43 % The rest of the computation can actually be performed using the shortcut:
|
wolffd@0
|
44 [p pac] = mirpitch(ac)
|
wolffd@0
|
45
|
wolffd@0
|
46 % Look and listen to the results.
|
wolffd@0
|
47 mirgetdata(p)
|
wolffd@0
|
48 mirplay(p)
|
wolffd@0
|
49
|
wolffd@0
|
50 % Does it sound better? What is the problem this time?
|
wolffd@0
|
51
|
wolffd@0
|
52 pause, close all
|
wolffd@0
|
53
|
wolffd@0
|
54 %% 3. Improving the analysis, again
|
wolffd@0
|
55
|
wolffd@0
|
56 % In fact, the autocorrelation function contains a lot of harmonics that need to be removed. For that purpose, the autocorrelation function can be ?enhanced? (cf. MIRtoolbox User?s Manual at the mirautocor section for an explanation of the 'Enhanced' option):
|
wolffd@0
|
57 ac = mirautocor(ac,'Enhanced')
|
wolffd@0
|
58
|
wolffd@0
|
59 % Carry out the rest of the computation as in section 2.2.
|
wolffd@0
|
60 [p pac] = mirpitch(ac)
|
wolffd@0
|
61 mirgetdata(p)
|
wolffd@0
|
62 mirplay(p)
|
wolffd@0
|
63
|
wolffd@0
|
64 % What do you think of the results?
|
wolffd@0
|
65
|
wolffd@0
|
66 pause, close all
|
wolffd@0
|
67
|
wolffd@0
|
68 %% 4. Improving the analysis, still
|
wolffd@0
|
69
|
wolffd@0
|
70 % An additional improvement consists in first decomposing the audio into two channels using the command:
|
wolffd@0
|
71 fb = mirfilterbank(a,'2Channels')
|
wolffd@0
|
72
|
wolffd@0
|
73 % Compute the autocorrelation on each channel:
|
wolffd@0
|
74 ac = mirautocor(fb,'Compres',.5)
|
wolffd@0
|
75
|
wolffd@0
|
76 % The autocorrelation of each channel can then be summed together:
|
wolffd@0
|
77 ac = mirsum(ac)
|
wolffd@0
|
78
|
wolffd@0
|
79 % And the enhancement can be performed afterwards:
|
wolffd@0
|
80 ac = mirautocor(ac,'Enhanced')
|
wolffd@0
|
81
|
wolffd@0
|
82 % And the rest of the computation follows the same principle than before.
|
wolffd@0
|
83 [p ac] = mirpitch(ac)
|
wolffd@0
|
84
|
wolffd@0
|
85 % The result should be better this way.
|
wolffd@0
|
86 mirgetdata(p)
|
wolffd@0
|
87 mirplay(p)
|
wolffd@0
|
88
|
wolffd@0
|
89 % Hopefully, the whole chain of operation can be performed automatically using the simple command:
|
wolffd@0
|
90 [p ac] = mirpitch(a)
|
wolffd@0
|
91 [p ac] = mirpitch(a,'Cepstrum')
|
wolffd@0
|
92 [p ac] = mirpitch(a,'AutocorSpectrum')
|
wolffd@0
|
93
|
wolffd@0
|
94 pause, close all
|
wolffd@0
|
95
|
wolffd@0
|
96 %% 5. Frame-based analysis
|
wolffd@0
|
97
|
wolffd@0
|
98 % Let?s analyze a longer musical sequence, such as ragtime.wav:
|
wolffd@0
|
99 a = miraudio('ragtime');
|
wolffd@0
|
100 mirplay(a)
|
wolffd@0
|
101
|
wolffd@0
|
102 % A direct analysis of the recording using the previous command
|
wolffd@0
|
103 [p ac] = mirpitch(a)
|
wolffd@0
|
104 % is not concluding, as it tries to find the pitches contained in the whole signal.
|
wolffd@0
|
105 mirgetdata(p)
|
wolffd@0
|
106 mirplay(p)
|
wolffd@0
|
107
|
wolffd@0
|
108 % It is better to estimate the pitch content frame-by-frame:
|
wolffd@0
|
109 [p ac] = mirpitch(a,'Frame')
|
wolffd@0
|
110 mirgetdata(p)
|
wolffd@0
|
111
|
wolffd@0
|
112 % Don?t forget to listen to the results.
|
wolffd@0
|
113 mirplay(p)
|
wolffd@0
|
114
|
wolffd@0
|
115 pause, close all
|
wolffd@0
|
116
|
wolffd@0
|
117 %% 6. Segment-based analysis
|
wolffd@0
|
118
|
wolffd@0
|
119 % But it might get more sense to first decompose the signal into notes, using the commands:
|
wolffd@0
|
120 o = mironsets(a,'Attacks')
|
wolffd@0
|
121 % (The 'Attacks' option enables to segment at the beginning of each note
|
wolffd@0
|
122 % attack phase, i.e., where the energy is minimum, instead of segmenting where the energy is maximum.)
|
wolffd@0
|
123 mirplay(o)
|
wolffd@0
|
124
|
wolffd@0
|
125 sg = mirsegment(a,o)
|
wolffd@0
|
126 mirplay(sg)
|
wolffd@0
|
127
|
wolffd@0
|
128 % and to compute the pitch on each successive segment:
|
wolffd@0
|
129 [p ac] = mirpitch(sg)
|
wolffd@0
|
130 mirgetdata(p)
|
wolffd@0
|
131
|
wolffd@0
|
132 % Again, don?t forget to listen to the results.
|
wolffd@0
|
133 mirplay(p)
|
wolffd@0
|
134
|
wolffd@0
|
135 pause, close all
|
wolffd@0
|
136
|
wolffd@0
|
137 %% 7. Monody analysis
|
wolffd@0
|
138
|
wolffd@0
|
139 % Conclude with the analysis of a Finnish folk song, Läksin minä kesäyönä, whose excerpt is recorded in the file ?laksin.wav?. As the melody is sung by one voice only, you can use the ?Mono? option in mirpitch.
|
wolffd@0
|
140 mirplay('laksin')
|
wolffd@0
|
141 o = mironsets('laksin','Attacks','Contrast',.1)
|
wolffd@0
|
142 mirplay(o)
|
wolffd@0
|
143 sg = mirsegment('laksin',o)
|
wolffd@0
|
144 mirplay(sg)
|
wolffd@0
|
145 p = mirpitch(sg,'mono')
|
wolffd@0
|
146 mirgetdata(p)
|
wolffd@0
|
147 mirplay(p) |