Mercurial > hg > drum-timing-analyser
comparison DrumTimingLoader_OF/src/RecordedMultipleAudio.cpp @ 2:50ba55abea8c
updating files to newer version
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Sat, 23 Nov 2013 15:49:27 +0000 |
parents | 82352cfc0b23 |
children |
comparison
equal
deleted
inserted
replaced
1:106bc2d4f702 | 2:50ba55abea8c |
---|---|
1 /* | 1 /* |
2 * RecordedMultipleAudio.cpp | 2 * RecordedMultipleAudio.cpp |
3 * MultipleAudioMathcher | 3 * Drum Timing Analyser |
4 * | 4 * |
5 * Created by Andrew on 31/01/2012. | 5 * Created by Andrew on 31/01/2012. |
6 * Copyright 2012 QMUL. All rights reserved. | 6 * Copyright 2012 QMUL. All rights reserved. |
7 * | 7 * |
8 */ | 8 */ |
9 | 9 |
10 #include "RecordedMultipleAudio.h" | 10 #include "RecordedMultipleAudio.h" |
11 | 11 |
12 const bool printExportInfo = false; | |
13 | |
12 RecordedMultipleAudio::RecordedMultipleAudio(){ | 14 RecordedMultipleAudio::RecordedMultipleAudio(){ |
13 | 15 |
14 infoFilepath = "../../../data/errorData.txt"; | 16 infoFilepath = "../../../data/errorData.txt"; |
17 | |
18 exactOnsetFilePath = "../../../data/exactOnsetTimes.txt"; | |
19 kickRelativeTempoFilePath = "../../../data/kickRelativeTempoTimes.txt"; | |
20 kickRelativeErrorsFilePath = "../../../data/kickRelativeErrorTimes.txt"; | |
21 kickRelativeClickFilePath = "../../../data/kickRelativeClickTimes.txt"; | |
22 | |
23 drumTimerTempoFilePath = "../../../data/drummerTimerTempoTimes.txt"; | |
24 drumTimerErrorsFilePath = "../../../data/drummerTimerErrorTimes.txt"; | |
25 drumTimerClickFilePath = "../../../data/drummerTimerClickTimes.txt"; | |
26 | |
15 //infoFilepath = "/Users/andrew/errorData.txt"; | 27 //infoFilepath = "/Users/andrew/errorData.txt"; |
16 | 28 |
17 timingOffset = 0; | 29 timingOffset = 0; |
30 playPositionSeconds = 3.4; | |
18 } | 31 } |
19 | 32 |
20 void RecordedMultipleAudio::loadTestAudio(){ | 33 void RecordedMultipleAudio::loadTestAudio(){ |
21 | 34 |
35 int multitrackToLoad = 7; | |
22 | 36 |
23 numberOfAudioTracks = 2; | 37 numberOfAudioTracks = 2; |
24 | 38 |
25 printf("loaded max val is %f\n", loadedAudioFiles[0].fileLoader.onsetDetect.onsetDetector.maximumDetectionValue); | 39 printf("loaded max val is %f\n", loadedAudioFiles[0].fileLoader.onsetDetect.onsetDetector.maximumDetectionValue); |
26 | 40 |
27 int multitrackToLoad = 5; | 41 |
42 | |
28 setDifferentMultitracks(multitrackToLoad);//command to load this set of audio files - see below | 43 setDifferentMultitracks(multitrackToLoad);//command to load this set of audio files - see below |
29 | 44 |
30 drumTimingAnalyser.phaseCost = 1000;//v high - i.e. dont do phase | 45 drumTimingAnalyser.phaseCost = 1000;//v high - i.e. dont do phase |
46 | |
31 | 47 |
32 drawWindow = 1; | 48 drawWindow = 1; |
33 trackScreenHeight = 0.25; | 49 trackScreenHeight = 0.25; |
34 | 50 |
35 | 51 |
80 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/kick_bip.wav"; | 96 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/kick_bip.wav"; |
81 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/snare_bip.wav"; | 97 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/snare_bip.wav"; |
82 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/PennyArcade_take4_beats.txt"; | 98 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/PennyArcade_take4_beats.txt"; |
83 break; | 99 break; |
84 | 100 |
101 /* | |
85 case 5: | 102 case 5: |
86 roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/neuamnn_bip.wav"; | 103 roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/neuamnn_bip.wav"; |
87 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/kick_bip.wav"; | 104 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/kick_bip.wav"; |
88 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/snare_bip.wav"; | 105 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/snare_bip.wav"; |
89 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/PennyArcade_take5_beats.txt"; | 106 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/PennyArcade_take5_beats.txt"; |
90 break; | 107 break; |
91 | 108 */ |
109 case 5: | |
110 roomfilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/neuamnn_bip.wav"; | |
111 kickfilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/kick_bip.wav"; | |
112 snarefilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/snare_bip.wav"; | |
113 sonicVizBeatsFilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/PennyArcade_take5_beats.txt"; | |
114 break; | |
115 | |
116 | |
117 case 6: | |
118 roomfilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBreak.wav"; | |
119 kickfilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBreak.wav"; | |
120 snarefilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBreak.wav"; | |
121 sonicVizBeatsFilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBeats.txt"; | |
122 break; | |
123 | |
124 case 7: | |
125 roomfilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/Take23_mono.wav"; | |
126 kickfilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/Take23_mono.wav"; | |
127 snarefilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/Take23_mono.wav"; | |
128 sonicVizBeatsFilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/IsaakTake23MonoBeats.txt"; | |
129 break; | |
92 | 130 |
93 | 131 |
94 } | 132 } |
95 if (kickfilename != NULL){ | 133 if (kickfilename != NULL){ |
96 | 134 printf("Loading Kick file: %s\n", kickfilename); |
97 loadAudioTrack(kickfilename, 0); | 135 loadAudioTrack(kickfilename, 0); |
98 } | 136 } |
99 | 137 |
100 if (roomfilename != NULL){ | 138 if (roomfilename != NULL){ |
101 printf("roomfilename: %s\n", roomfilename); | 139 printf("loading room: %s\n", roomfilename); |
102 loadAudioTrack(roomfilename, 1); | 140 loadAudioTrack(roomfilename, 1); |
103 } | 141 } |
104 | 142 |
105 if (snarefilename != NULL) | 143 if (snarefilename != NULL){ |
144 printf("Loading Snare file: %s\n", kickfilename); | |
106 loadAudioTrack(snarefilename, 2); | 145 loadAudioTrack(snarefilename, 2); |
146 } | |
107 | 147 |
108 if (sonicVizBeatsFilename.c_str() != NULL){ | 148 if (sonicVizBeatsFilename.c_str() != NULL){ |
149 printf("Reading sonic viz beats: %s\n", sonicVizBeatsFilename.c_str()); | |
109 readInBeatsFile(sonicVizBeatsFilename); | 150 readInBeatsFile(sonicVizBeatsFilename); |
110 printBeatTimes(); | 151 printBeatTimes(); |
111 checkFileErrors(0); | 152 checkFileErrors(0); |
112 checkFileErrors(2); | 153 checkFileErrors(2); |
113 findBeatOnsets(); | 154 findBeatOnsets(); |
155 | |
156 exportErrorInformation(); | |
157 exportExactOnsetTimes(); | |
158 | |
159 exportKickRelativeTempoTimes(); | |
160 exportKickRelativeErrorTimes(); | |
161 exportKickRelativeClickTimes(); | |
162 | |
163 exportDrumTimerTempoTimes(); | |
164 exportDrumTimerErrorTimes(); | |
165 exportDrumTimerClickTimes(); | |
114 } | 166 } |
115 } | 167 } |
116 | 168 |
117 void RecordedMultipleAudio::loadAudioTrack(std::string name, const int& channel){ | 169 void RecordedMultipleAudio::loadAudioTrack(std::string name, const int& channel){ |
118 //kick - track type 0 | 170 //kick - track type 0 |
175 iss.clear(); | 227 iss.clear(); |
176 | 228 |
177 | 229 |
178 }//end while | 230 }//end while |
179 | 231 |
180 // printBeatTimes(); | 232 |
181 printf("There are %i BEAT annotations\n", (int)beatTimes.size()); | 233 printf("There are %i BEAT annotations\n", (int)beatTimes.size()); |
182 | 234 |
183 } | 235 } |
184 | 236 |
185 void RecordedMultipleAudio::printBeatTimes(){ | 237 void RecordedMultipleAudio::printBeatTimes(){ |
189 } | 241 } |
190 | 242 |
191 | 243 |
192 void RecordedMultipleAudio::checkFileErrors(int channel){ | 244 void RecordedMultipleAudio::checkFileErrors(int channel){ |
193 int beatIndex = 0; | 245 int beatIndex = 0; |
194 int cutoff = 50;//ms width to check | 246 int cutoff = 60;//ms width to check |
195 for (int i = 0;i < loadedAudioFiles[channel].onsetTimesMillis.size();i++){ | 247 for (int i = 0;i < loadedAudioFiles[channel].onsetTimesMillis.size();i++){ |
248 | |
249 printf("onset time %i ms %i frames ", (int)loadedAudioFiles[channel].onsetTimesMillis[i], (int)loadedAudioFiles[channel].onsetTimesFrames[i]); | |
250 | |
196 while (beatIndex < beatTimes.size() && 1000.0*beatTimes[beatIndex] < loadedAudioFiles[channel].onsetTimesMillis[i] - cutoff) { | 251 while (beatIndex < beatTimes.size() && 1000.0*beatTimes[beatIndex] < loadedAudioFiles[channel].onsetTimesMillis[i] - cutoff) { |
197 beatIndex++; | 252 beatIndex++; |
198 } | 253 } |
199 double error = (1000.0*beatTimes[beatIndex] - loadedAudioFiles[channel].onsetTimesMillis[i]); | 254 double error = (1000.0*beatTimes[beatIndex] - loadedAudioFiles[channel].onsetTimesMillis[i]); |
200 if (fabs(error) < cutoff){ | 255 if (fabs(error) < cutoff){ |
203 else | 258 else |
204 printf("Pos: %i Beat Time %f Snare Time %f Error %f\n", beatIndex%4, 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); | 259 printf("Pos: %i Beat Time %f Snare Time %f Error %f\n", beatIndex%4, 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); |
205 | 260 |
206 }else{ | 261 }else{ |
207 if (channel == 0) | 262 if (channel == 0) |
208 printf("Out of Beat: Kick Time %f beat error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); | 263 printf("Ch.0 Out of Beat: Kick Time %f beat error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); |
209 else | 264 else |
210 printf("Out of Beat: %f Snare Time %f best error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); | 265 printf("Ch.2 Out of Beat: %f Snare Time %f best error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); |
211 | 266 |
212 } | 267 } |
213 } | 268 } |
214 } | 269 } |
215 | 270 |
233 for (int k = 0;k < beatTimes.size();k++){ | 288 for (int k = 0;k < beatTimes.size();k++){ |
234 beatFound = false; | 289 beatFound = false; |
235 double newBeatTime = beatTimes[k]*1000.0; | 290 double newBeatTime = beatTimes[k]*1000.0; |
236 int beatPosition = k % 4; | 291 int beatPosition = k % 4; |
237 OnsetInformation information; | 292 OnsetInformation information; |
293 double bestBeatDifference = 1000;//i.e. high | |
238 switch (beatPosition) { | 294 switch (beatPosition) { |
239 case 0: case 2://check for kick when it is on the `one' or 'three' (0 or 2 in our metrical position) | 295 case 0: case 2://check for kick when it is on the `one' or 'three' (0 or 2 in our metrical position) |
240 // printf("check %i kindex %i\n", beatPosition, kickIndex); | 296 // printf("check %i kindex %i\n", beatPosition, kickIndex); |
241 while (kickIndex < loadedAudioFiles[0].onsetTimesMillis.size() && loadedAudioFiles[0].onsetTimesMillis[kickIndex] < newBeatTime - cutoff){ | 297 while (kickIndex < loadedAudioFiles[0].onsetTimesMillis.size() && loadedAudioFiles[0].onsetTimesMillis[kickIndex] < newBeatTime - cutoff){ |
242 kickIndex++; | 298 kickIndex++; |
243 kickTime = loadedAudioFiles[0].onsetTimesMillis[kickIndex]; | 299 kickTime = loadedAudioFiles[0].onsetTimesMillis[kickIndex]; |
244 // printf("checking beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0)); | 300 // printf("checking beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0)); |
245 if (fabs(kickTime - beatTimes[k]*1000.0) < cutoff){ | 301 if (fabs(kickTime - beatTimes[k]*1000.0) < cutoff && fabs(kickTime - beatTimes[k]*1000.0) < bestBeatDifference){ |
246 beatFound = true; | 302 beatFound = true; |
247 printf("beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0)); | 303 printf("beat[%i] pos %i time %f kick %f error %f\n", k, beatPosition, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0)); |
248 | 304 |
249 information.error = (kickTime - beatTimes[k]*1000.0);//FOR NOW ONLY | 305 information.error = (kickTime - beatTimes[k]*1000.0);//FOR NOW ONLY |
250 information.metricalPosition = beatPosition; | 306 information.metricalPosition = beatPosition; |
251 information.type = 0; | 307 information.type = 0; |
252 information.exactOnsetTime = kickTime; | 308 information.exactOnsetTime = kickTime; |
309 bestBeatDifference = fabs(kickTime - beatTimes[k]*1000.0); | |
253 // exactBeatPositions.push_back(kickTime); | 310 // exactBeatPositions.push_back(kickTime); |
254 } | 311 } |
255 } | 312 } |
256 | 313 |
257 break; | 314 break; |
258 case 1: case 3://snare | 315 case 1: case 3://snare |
259 while (snareIndex < loadedAudioFiles[1].onsetTimesMillis.size() && loadedAudioFiles[1].onsetTimesMillis[snareIndex] < newBeatTime - cutoff ){ | 316 while (snareIndex < loadedAudioFiles[1].onsetTimesMillis.size() && loadedAudioFiles[1].onsetTimesMillis[snareIndex] < newBeatTime - cutoff ){ |
260 snareIndex++; | 317 snareIndex++; |
261 snareTime = loadedAudioFiles[1].onsetTimesMillis[snareIndex]; | 318 snareTime = loadedAudioFiles[1].onsetTimesMillis[snareIndex]; |
262 if (fabs(snareTime - beatTimes[k]*1000.0) < cutoff){ | 319 if (fabs(snareTime - beatTimes[k]*1000.0) < cutoff && fabs(snareTime - beatTimes[k]*1000.0) < bestBeatDifference){ |
263 beatFound = true; | 320 beatFound = true; |
264 // snareErrors.push_back((beatTimes[k]*1000.0 - snareTime)); | 321 // snareErrors.push_back((beatTimes[k]*1000.0 - snareTime)); |
265 information.error = (snareTime - beatTimes[k]*1000.0); | 322 information.error = (snareTime - beatTimes[k]*1000.0); |
266 information.metricalPosition = beatPosition;//.push_back(beatPosition); | 323 information.metricalPosition = beatPosition;//.push_back(beatPosition); |
267 information.type = 1; | 324 information.type = 1; |
268 information.exactOnsetTime = snareTime; | 325 information.exactOnsetTime = snareTime; |
269 printf("beat[%i] %f snare %f error %f\n", k, beatTimes[k]*1000.0, snareTime, (snareTime - beatTimes[k]*1000.0)); | 326 bestBeatDifference = fabs(snareTime - beatTimes[k]*1000.0); |
327 printf("beat[%i] pos %i tim e%f snare %f error %f\n", k, beatPosition, beatTimes[k]*1000.0, snareTime, (snareTime - beatTimes[k]*1000.0)); | |
270 // exactBeatPositions.push_back(snareTime); | 328 // exactBeatPositions.push_back(snareTime); |
271 } | 329 } |
272 } | 330 } |
273 | 331 |
274 break; | 332 break; |
287 }//end for all beat annotations | 345 }//end for all beat annotations |
288 | 346 |
289 correctExactBeatTiming();//get rid of the first onset time | 347 correctExactBeatTiming();//get rid of the first onset time |
290 | 348 |
291 calculateTimingAnalysis(); | 349 calculateTimingAnalysis(); |
350 | |
351 | |
352 //so our exact beat times are then information.exactOnsetTime | |
292 | 353 |
293 } | 354 } |
294 | 355 |
295 #pragma mark -doTimingAnalysis | 356 #pragma mark -doTimingAnalysis |
296 void RecordedMultipleAudio::correctExactBeatTiming(){ | 357 void RecordedMultipleAudio::correctExactBeatTiming(){ |
318 | 379 |
319 getErrorTimesFromAnalysis(); | 380 getErrorTimesFromAnalysis(); |
320 | 381 |
321 alternativeKickRelativeAnalysis(); | 382 alternativeKickRelativeAnalysis(); |
322 | 383 |
323 exportErrorInformation(); | |
324 | |
325 displayKickRelativeMedianErrors();//NB messes ther order of these | 384 displayKickRelativeMedianErrors();//NB messes ther order of these |
326 | 385 |
327 //this was how we did it in multimatch program | 386 //this was how we did it in multimatch program |
328 // timer.processPathHistory(); | 387 // timer.processPathHistory(); |
329 // timer.calculateTempoLimits(); | 388 // timer.calculateTempoLimits(); |
337 //gets the errors from the drum timing analyser (i.e. ISMIR paper code) and attributes these to the onsets | 396 //gets the errors from the drum timing analyser (i.e. ISMIR paper code) and attributes these to the onsets |
338 for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){ | 397 for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){ |
339 onsetInfo[i].error = drumTimingAnalyser.timingData[i][5]; | 398 onsetInfo[i].error = drumTimingAnalyser.timingData[i][5]; |
340 onsetInfo[i].clickTime = drumTimingAnalyser.timingData[i][1] + timingOffset;//this is where teh timing analyser placed the click times | 399 onsetInfo[i].clickTime = drumTimingAnalyser.timingData[i][1] + timingOffset;//this is where teh timing analyser placed the click times |
341 errorsByMetricalPosition[onsetInfo[i].metricalPosition].push_back(onsetInfo[i].error); | 400 errorsByMetricalPosition[onsetInfo[i].metricalPosition].push_back(onsetInfo[i].error); |
342 printf("beat %i metrical posn %i exact beat time %f error %i\n", i, onsetInfo[i].metricalPosition, onsetInfo[i].exactOnsetTime, (int)onsetInfo[i].error); | 401 printf("beat %i metrical posn %i exact onset time %f click time %i error %i\n", i, onsetInfo[i].metricalPosition, onsetInfo[i].exactOnsetTime, |
402 onsetInfo[i].clickTime, (int)onsetInfo[i].error); | |
343 } | 403 } |
344 displayMedianErrors(); | 404 displayMedianErrors(); |
345 } | 405 } |
346 | 406 |
347 | 407 |
350 //this sees kicks as ON the beat, looks at relative error of the three other beats if we chop the bar evenly | 410 //this sees kicks as ON the beat, looks at relative error of the three other beats if we chop the bar evenly |
351 | 411 |
352 double recentBeatTime, currentTempo; | 412 double recentBeatTime, currentTempo; |
353 kickRelativeErrors.clear(); | 413 kickRelativeErrors.clear(); |
354 kickRelativeClickTimes.clear(); | 414 kickRelativeClickTimes.clear(); |
415 kickRelativeTempo.clear(); | |
355 | 416 |
356 for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){ | 417 for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){ |
357 int beatPosition = i%4; | 418 int beatPosition = i%4; |
358 if (beatPosition == 0){ | 419 if (beatPosition == 0){//then divide kicks and get even division |
359 recentBeatTime = onsetInfo[i].exactOnsetTime; | 420 recentBeatTime = onsetInfo[i].exactOnsetTime; |
360 if (i+4 < onsetInfo.size()) | 421 if (i+4 < onsetInfo.size()) |
361 currentTempo = (onsetInfo[i+4].exactOnsetTime - onsetInfo[i].exactOnsetTime)/4.0; | 422 currentTempo = (onsetInfo[i+4].exactOnsetTime - onsetInfo[i].exactOnsetTime)/4.0; |
362 printf("new beat time %f tempo %f\n", recentBeatTime, currentTempo); | 423 printf("new beat time %f tempo %f\n", recentBeatTime, currentTempo); |
363 } | 424 } |
364 double error = onsetInfo[i].exactOnsetTime - (recentBeatTime + beatPosition*currentTempo); | 425 double error = onsetInfo[i].exactOnsetTime - (recentBeatTime + beatPosition*currentTempo); |
365 printf("Beat %i KR Predicted Beat %f Actual exact %f KRerror %f DTerror %i\n", beatPosition, (recentBeatTime + beatPosition*currentTempo), onsetInfo[i].exactOnsetTime, error, (int)onsetInfo[i].error); | 426 printf("Beat %i KR Predicted Beat: %f Onset: %f KRerror %f DTerror %i\n", beatPosition, (recentBeatTime + beatPosition*currentTempo), onsetInfo[i].exactOnsetTime, error, (int)onsetInfo[i].error); |
366 kickRelativeErrors.push_back(error); | 427 kickRelativeErrors.push_back(error); |
367 kickRelativeClickTimes.push_back(recentBeatTime + beatPosition*currentTempo); | 428 kickRelativeClickTimes.push_back(recentBeatTime + beatPosition*currentTempo); |
368 } | 429 kickRelativeTempo.push_back(currentTempo); |
369 } | 430 } |
370 | 431 } |
371 #pragma label -exportInfo | 432 |
433 #pragma mark -exportInfo | |
372 void RecordedMultipleAudio::exportErrorInformation(){ | 434 void RecordedMultipleAudio::exportErrorInformation(){ |
373 printf("Export final timing information\n"); | 435 printf("Export final timing information\n"); |
374 | 436 |
375 ofstream ofs(infoFilepath.c_str()); | 437 ofstream ofs(infoFilepath.c_str()); |
376 for (int i = 0;i < onsetInfo.size() && kickRelativeErrors.size();i++){// drumTimingAnalyser.timingData.size() | 438 for (int i = 0;i < onsetInfo.size() && kickRelativeErrors.size();i++){// drumTimingAnalyser.timingData.size() |
379 ofs << kickRelativeClickTimes[i] << "," << kickRelativeErrors[i];//the click and error for beats evenly between kicks | 441 ofs << kickRelativeClickTimes[i] << "," << kickRelativeErrors[i];//the click and error for beats evenly between kicks |
380 ofs << endl; | 442 ofs << endl; |
381 } | 443 } |
382 | 444 |
383 } | 445 } |
446 | |
447 | |
448 void RecordedMultipleAudio::exportExactOnsetTimes(){ | |
449 printf("Export exact beat times\n"); | |
450 | |
451 ofstream ofs(exactOnsetFilePath.c_str()); | |
452 for (int i = 0;i < onsetInfo.size();i++){// drumTimingAnalyser.timingData.size() | |
453 ofs << onsetInfo[i].exactOnsetTime/1000.0 << endl; | |
454 if (printExportInfo) | |
455 printf("exporting exact beat times %f\n", onsetInfo[i].exactOnsetTime); | |
456 } | |
457 } | |
458 | |
459 void RecordedMultipleAudio::exportKickRelativeTempoTimes(){ | |
460 printf("Export kick relative Tempo times\n"); | |
461 | |
462 ofstream ofs(kickRelativeTempoFilePath.c_str()); | |
463 for (int i = 0;i < kickRelativeTempo.size() && i < onsetInfo.size();i++){ | |
464 ofs << onsetInfo[i].exactOnsetTime << "\t" << kickRelativeTempo[i] << endl; | |
465 if (printExportInfo) | |
466 printf("exporting tempo[%i]: onset %f %f\n", i, onsetInfo[i].exactOnsetTime, kickRelativeTempo[i]); | |
467 } | |
468 } | |
469 | |
470 void RecordedMultipleAudio::exportKickRelativeErrorTimes(){ | |
471 printf("Export kick relative Error times\n"); | |
472 | |
473 ofstream ofs(kickRelativeErrorsFilePath.c_str()); | |
474 for (int i = 0;i < kickRelativeErrors.size() && i < onsetInfo.size();i++){ | |
475 ofs << onsetInfo[i].exactOnsetTime << "\t" << kickRelativeErrors[i] << endl; | |
476 if (printExportInfo) | |
477 printf("exporting tempo[%i]: onset %f %f\n", i, onsetInfo[i].exactOnsetTime, kickRelativeErrors[i]); | |
478 } | |
479 } | |
480 | |
481 void RecordedMultipleAudio::exportKickRelativeClickTimes(){ | |
482 printf("Export kick relative click times\n"); | |
483 | |
484 ofstream ofs(kickRelativeClickFilePath.c_str()); | |
485 for (int i = 0;i < kickRelativeClickTimes.size();i++){ | |
486 ofs << kickRelativeClickTimes[i]/1000.0 << endl; | |
487 if (printExportInfo) | |
488 printf("exporting KD click [%i]:%f\n", i,kickRelativeClickTimes[i]); | |
489 } | |
490 } | |
491 | |
492 | |
493 void RecordedMultipleAudio::exportDrumTimerTempoTimes(){ | |
494 printf("Export drum timing tempo times\n"); | |
495 | |
496 ofstream ofs(drumTimerTempoFilePath.c_str()); | |
497 for (int i = 0;i < drumTimingAnalyser.timingData.size() && i < onsetInfo.size();i++){ | |
498 ofs << onsetInfo[i].exactOnsetTime << "\t" << drumTimingAnalyser.timingData[i][0] << endl; | |
499 if (printExportInfo) | |
500 printf("exporting tempo[%i]: onset %f tempo %i\n", i, onsetInfo[i].exactOnsetTime, drumTimingAnalyser.timingData[i][0]); | |
501 } | |
502 } | |
503 | |
504 | |
505 void RecordedMultipleAudio::exportDrumTimerErrorTimes(){ | |
506 printf("Export drum timing Error times\n"); | |
507 | |
508 ofstream ofs(drumTimerErrorsFilePath.c_str()); | |
509 for (int i = 0;i < drumTimingAnalyser.timingData.size() && i < onsetInfo.size();i++){ | |
510 ofs << onsetInfo[i].exactOnsetTime << "\t" << drumTimingAnalyser.timingData[i][5] << endl; | |
511 if (printExportInfo) | |
512 printf("exporting [%i]: onset %f error %i\n", i, onsetInfo[i].exactOnsetTime, drumTimingAnalyser.timingData[i][5]); | |
513 } | |
514 } | |
515 | |
516 | |
517 void RecordedMultipleAudio::exportDrumTimerClickTimes(){ | |
518 printf("Export drum timing Click times\n"); | |
519 | |
520 ofstream ofs(drumTimerClickFilePath.c_str()); | |
521 for (int i = 0;i < onsetInfo.size();i++){ | |
522 ofs << onsetInfo[i].clickTime/1000.0 << endl; | |
523 if (printExportInfo) | |
524 printf("exporting click[%i] %i\n", i, onsetInfo[i].clickTime); | |
525 } | |
526 } | |
527 | |
528 | |
529 | |
530 | |
531 | |
532 | |
384 | 533 |
385 void RecordedMultipleAudio::printKickRelativeErrors(){ | 534 void RecordedMultipleAudio::printKickRelativeErrors(){ |
386 for (int i = 0;i < kickRelativeErrors.size();i++){ | 535 for (int i = 0;i < kickRelativeErrors.size();i++){ |
387 printf("KR error [%i] : %.1f\n", i, kickRelativeErrors[i]); | 536 printf("KR error [%i] : %.1f\n", i, kickRelativeErrors[i]); |
388 } | 537 } |
454 loadedAudioFiles[i].draw(); | 603 loadedAudioFiles[i].draw(); |
455 } | 604 } |
456 } else { | 605 } else { |
457 drumTimingAnalyser.drawTempoCurve(); | 606 drumTimingAnalyser.drawTempoCurve(); |
458 } | 607 } |
608 | |
609 // ofDrawBitmapString(ofToString(playPositionSeconds),20, 40); | |
459 } | 610 } |
460 | 611 |
461 #pragma mark -update | 612 #pragma mark -update |
462 void RecordedMultipleAudio::updatePosition(){ | 613 void RecordedMultipleAudio::updatePosition(){ |
463 for (int i = 0;i < numberOfAudioTracks;i++) | 614 for (int i = 0;i < numberOfAudioTracks;i++) |
464 loadedAudioFiles[i].updateToPlayPosition(); | 615 loadedAudioFiles[i].updateToPlayPosition(); |
616 | |
617 playPositionSeconds = samplesToSeconds(loadedAudioFiles[0].fileLoader.audioHolder.playPosition); | |
618 drumTimingAnalyser.updatePlayIndex(playPositionSeconds); | |
619 | |
620 | |
621 } | |
622 | |
623 double RecordedMultipleAudio::samplesToSeconds(const double& samples){ | |
624 return samples/44100.0; | |
465 } | 625 } |
466 | 626 |
467 void RecordedMultipleAudio::updatePositionToMillis(const double& millis){ | 627 void RecordedMultipleAudio::updatePositionToMillis(const double& millis){ |
468 for (int i = 0;i < numberOfAudioTracks;i++) | 628 for (int i = 0;i < numberOfAudioTracks;i++) |
469 loadedAudioFiles[i].updateToMillisPosition(millis); | 629 loadedAudioFiles[i].updateToMillisPosition(millis); |
471 | 631 |
472 void RecordedMultipleAudio::updatePlaybackPositionToMillis(const double& millis){ | 632 void RecordedMultipleAudio::updatePlaybackPositionToMillis(const double& millis){ |
473 for (int i = 0;i < numberOfAudioTracks;i++) | 633 for (int i = 0;i < numberOfAudioTracks;i++) |
474 loadedAudioFiles[i].updatePlaybackPositionToMillis(millis); | 634 loadedAudioFiles[i].updatePlaybackPositionToMillis(millis); |
475 } | 635 } |
476 | |
477 void RecordedMultipleAudio::switchScreens(){ | |
478 for (int i = 0;i < numberOfAudioTracks;i++) | |
479 loadedAudioFiles[i].switchScreens(); | |
480 } | |
481 | |
482 | 636 |
483 void RecordedMultipleAudio::togglePlay(){ | 637 void RecordedMultipleAudio::togglePlay(){ |
484 for (int i = 0;i < numberOfAudioTracks;i++) | 638 for (int i = 0;i < numberOfAudioTracks;i++) |
485 loadedAudioFiles[i].togglePlay(); | 639 loadedAudioFiles[i].togglePlay(); |
486 } | 640 } |
494 void RecordedMultipleAudio::printInfo(){ | 648 void RecordedMultipleAudio::printInfo(){ |
495 loadedAudioFiles[0].fileLoader.onsetDetect.printChromaInfo(); | 649 loadedAudioFiles[0].fileLoader.onsetDetect.printChromaInfo(); |
496 loadedAudioFiles[0].printEvents(); | 650 loadedAudioFiles[0].printEvents(); |
497 } | 651 } |
498 | 652 |
653 #pragma mark -ScreenFunctions | |
499 void RecordedMultipleAudio::windowResized(const int& w, const int& h){ | 654 void RecordedMultipleAudio::windowResized(const int& w, const int& h){ |
500 for (int i = 0;i < numberOfAudioTracks;i++) | 655 for (int i = 0;i < numberOfAudioTracks;i++) |
501 loadedAudioFiles[i].windowResized(w, h); | 656 loadedAudioFiles[i].windowResized(w, h); |
502 } | 657 } |
503 | 658 |
520 if (drawWindow == 1) | 675 if (drawWindow == 1) |
521 drumTimingAnalyser.zoomOut();//numberOfPointsPerPage *= 2; | 676 drumTimingAnalyser.zoomOut();//numberOfPointsPerPage *= 2; |
522 | 677 |
523 } | 678 } |
524 | 679 |
525 | 680 void RecordedMultipleAudio::switchScreens(){ |
681 for (int i = 0;i < numberOfAudioTracks;i++) | |
682 loadedAudioFiles[i].switchScreens(); | |
683 } | |
684 |