Mercurial > hg > multitrack-audio-matcher
comparison src/AudioEventMatcher.cpp @ 10:cbadb9d05d29
Using timestamps for the scrolling alignment time
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Sat, 04 Feb 2012 19:59:27 +0000 |
parents | bc62266af280 |
children | 9a2b008c4706 |
comparison
equal
deleted
inserted
replaced
9:bc62266af280 | 10:cbadb9d05d29 |
---|---|
63 | 63 |
64 updateBestAlignmentPosition(); | 64 updateBestAlignmentPosition(); |
65 } | 65 } |
66 | 66 |
67 void AudioEventMatcher::updateBestAlignmentPosition(){ | 67 void AudioEventMatcher::updateBestAlignmentPosition(){ |
68 //THIS DEALS WITH WHERE WE ARE NOW! ON THE SCREEN | |
69 //DIFFERENT TO WHEN EVENTS COME IN AS THEY ARE TIMESTAMPED - SO EG A PITCH EVENT MAY ARRIVE 16 CHROMA FRAMES LATER - BIG DIFFERENCE | |
70 | |
71 int newTime = ofGetElapsedTimeMillis() - startTime; | |
72 // double tmp = bayesianStruct.posterior.getIndexInRealTerms(bayesianStruct.posterior.MAPestimate);; | |
73 // double timetmp = (newTime - lastAlignmentTime); | |
74 // double speedtmp = bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate); | |
75 | |
68 currentAlignmentPosition = bayesianStruct.posterior.getIndexInRealTerms(bayesianStruct.posterior.MAPestimate); | 76 currentAlignmentPosition = bayesianStruct.posterior.getIndexInRealTerms(bayesianStruct.posterior.MAPestimate); |
69 currentAlignmentPosition += (ofGetElapsedTimeMillis() - lastAlignmentTime) * bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate); | 77 currentAlignmentPosition += (newTime - lastAlignmentTime) * bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate); |
78 | |
79 // printf("ALIGN pos %f time diff %f (now %f , last %f)speed %f :: ALIGN BEST %f\n", tmp, timetmp, (double)ofGetElapsedTimeMillis(), lastAlignmentTime, speedtmp, currentAlignmentPosition); | |
70 } | 80 } |
71 | 81 |
72 void AudioEventMatcher::draw(){ | 82 void AudioEventMatcher::draw(){ |
73 //draw some outlines in blue | 83 //draw some outlines in blue |
74 ofSetColor(20,200,200); | 84 ofSetColor(20,200,200); |
151 ofDrawBitmapString("recent event "+ofToString(recentEventTime[i]), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.x + 20, recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.y + recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.height - 10); | 161 ofDrawBitmapString("recent event "+ofToString(recentEventTime[i]), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.x + 20, recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.y + recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.height - 10); |
152 } | 162 } |
153 | 163 |
154 int priorStartIndex = recentPrior.getRealTermsAsIndex(screenStartTimeMillis); | 164 int priorStartIndex = recentPrior.getRealTermsAsIndex(screenStartTimeMillis); |
155 int priorEndIndex = recentPrior.getRealTermsAsIndex(screenEndTimeMillis); | 165 int priorEndIndex = recentPrior.getRealTermsAsIndex(screenEndTimeMillis); |
156 ofSetColor(0,200,200); | 166 ofSetColor(0,200,200);//recent prior |
157 recentPrior.drawConstrainedVector(priorStartIndex, priorEndIndex, 0, ofGetWidth(), bayesPositionWindow); | 167 recentPrior.drawConstrainedVector(priorStartIndex, priorEndIndex, 0, ofGetWidth(), bayesPositionWindow); |
158 | 168 |
159 // bayesianStruct.prior.addTriangularShape(100, 20, 0.4); | 169 ofSetColor(255,0,100);//purple prior |
160 ofSetColor(255,0,100); | |
161 bayesianStruct.prior.drawConstrainedVector(bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis), bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), bayesLikelihoodWindow); | 170 bayesianStruct.prior.drawConstrainedVector(bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis), bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), bayesLikelihoodWindow); |
162 | 171 |
163 } | 172 } |
164 | 173 |
165 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ | 174 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ |
166 if (pitchIn > 0){ | 175 if (pitchIn > 0){ |
167 liveInput.addPitchEvent(pitchIn, timeIn); | 176 liveInput.addPitchEvent(pitchIn, timeIn); |
168 | 177 |
169 //tmp print stuff | 178 //printPosteriorMAPinfo(); |
170 printf("New pitch MAP post estimate now %i, ", bayesianStruct.posterior.MAPestimate); | 179 |
171 double tmp = bayesianStruct.posterior.getMAPestimate(); | |
172 printf(" getting it %f and offset %f == %f ms\n", tmp, bayesianStruct.posterior.offset, bayesianStruct.posterior.getIndexInRealTerms(tmp)); | |
173 | |
174 matchNewPitchEvent(channel, pitchIn, timeIn);//main pitch matching fn | 180 matchNewPitchEvent(channel, pitchIn, timeIn);//main pitch matching fn |
175 | 181 |
176 likelihoodVisualisation[1] = bayesianStruct.likelihood; | 182 likelihoodVisualisation[1] = bayesianStruct.likelihood; |
177 | 183 |
178 recentPitch = pitchIn;//for drawing | 184 recentPitch = pitchIn;//for drawing |
179 recentTime = timeIn; | 185 recentTime = timeIn; |
180 } | 186 } |
181 | |
182 | 187 |
183 } | 188 } |
184 | 189 |
185 void AudioEventMatcher::newKickEvent(const double& timeIn){ | 190 void AudioEventMatcher::newKickEvent(const double& timeIn){ |
186 // liveInput.addKickEvent(timeIn); | 191 // liveInput.addKickEvent(timeIn); |
207 } | 212 } |
208 | 213 |
209 //Needs just to set bounds for the matching process, not have TimeIn | 214 //Needs just to set bounds for the matching process, not have TimeIn |
210 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){ | 215 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){ |
211 | 216 |
212 | |
213 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets | 217 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets |
214 | 218 |
215 //start at beginning but OPTIMISE later | 219 //start at beginning but OPTIMISE later |
216 double onsetLikelihoodToNoise = 0.3; | 220 double onsetLikelihoodToNoise = 0.3; |
217 | 221 |
218 double likelihoodWidth = 40; | 222 double likelihoodWidth = 40; |
219 | 223 |
222 | 226 |
223 double quantity = 1;//likelihoodToNoiseRatio / numberOfMatches; | 227 double quantity = 1;//likelihoodToNoiseRatio / numberOfMatches; |
224 int numberOfMatchesFound = 0; | 228 int numberOfMatchesFound = 0; |
225 | 229 |
226 | 230 |
227 double startTime = bayesianStruct.likelihood.offset; | 231 double startMatchingTime = bayesianStruct.likelihood.offset; |
228 double endTime = bayesianStruct.likelihood.offset + matchWindowWidth; | 232 double endMatchingTime = bayesianStruct.likelihood.offset + matchWindowWidth; |
229 | 233 |
230 if (channel <= recordedTracks.numberOfAudioTracks){ | 234 if (channel <= recordedTracks.numberOfAudioTracks){ |
231 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ | 235 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ |
232 double millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime; | 236 double millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime; |
233 if (millisTime >= startTime && millisTime <= endTime){ | 237 if (millisTime >= startMatchingTime && millisTime <= endMatchingTime){ |
234 bayesianStruct.likelihood.addGaussianShapeFromRealTime(millisTime, likelihoodWidth, quantity); | 238 bayesianStruct.likelihood.addGaussianShapeFromRealTime(millisTime, likelihoodWidth, quantity); |
235 numberOfMatchesFound++; | 239 numberOfMatchesFound++; |
236 // printf("Adding Gaussian for onset at time %f offset %f\n", millisTime, bayesianStruct.likelihood.offset); | 240 // printf("Adding Gaussian for onset at time %f offset %f\n", millisTime, bayesianStruct.likelihood.offset); |
237 | 241 |
238 } | 242 } |
243 bayesianStruct.likelihood.addConstant(numberOfMatchesFound*(1-onsetLikelihoodToNoise)/(onsetLikelihoodToNoise*bayesianStruct.likelihood.length)); | 247 bayesianStruct.likelihood.addConstant(numberOfMatchesFound*(1-onsetLikelihoodToNoise)/(onsetLikelihoodToNoise*bayesianStruct.likelihood.length)); |
244 bayesianStruct.likelihood.renormalise(); | 248 bayesianStruct.likelihood.renormalise(); |
245 | 249 |
246 bayesianStruct.calculatePosterior(); | 250 bayesianStruct.calculatePosterior(); |
247 | 251 |
248 lastAlignmentTime = ofGetElapsedTimeMillis(); | 252 lastAlignmentTime = timeIn;//use TIMESTAMP |
249 recentEventTime[channel] = ofGetElapsedTimeMillis() - startTime; | 253 recentEventTime[channel] = timeIn;//ofGetElapsedTimeMillis() - startTime; |
250 | 254 |
251 } | 255 } |
252 | 256 |
253 | 257 |
254 | 258 |
255 void AudioEventMatcher::matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ | 259 void AudioEventMatcher::matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ |
256 //start at beginning but OPTIMISE later | 260 //start at beginning but OPTIMISE later |
257 | 261 /*printf("TIME %i\n", ofGetElapsedTimeMillis()); |
258 | 262 //tmp debug |
263 updateBestAlignmentPosition(); | |
264 printf("current alignment best estimate %f\n", currentAlignmentPosition); | |
265 */ | |
259 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets | 266 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets |
260 | 267 |
261 //set the lielihoods by matching the pitched note | 268 //set the lielihoods by matching the pitched note |
262 | 269 |
263 double pitchLikelihoodToNoise = 0.7;//more noise | 270 double pitchLikelihoodToNoise = 0.7;//more noise |
293 //bayesianStruct.likelihood.addConstant(1); | 300 //bayesianStruct.likelihood.addConstant(1); |
294 | 301 |
295 bayesianStruct.calculatePosterior(); | 302 bayesianStruct.calculatePosterior(); |
296 } | 303 } |
297 | 304 |
298 lastAlignmentTime = ofGetElapsedTimeMillis(); | 305 lastAlignmentTime = timeIn;//has to use the STAMPED time |
299 recentEventTime[channel] = ofGetElapsedTimeMillis() - startTime; | 306 recentEventTime[channel] = timeIn; |
300 } | 307 } |
301 | 308 |
302 double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){ | 309 double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){ |
303 | 310 |
304 double distance = abs(pitchOne - pitchTwo); | 311 double distance = abs(pitchOne - pitchTwo); |
326 recordedTracks.windowResized(w,h); | 333 recordedTracks.windowResized(w,h); |
327 bayesTempoWindow.resized(w,h); | 334 bayesTempoWindow.resized(w,h); |
328 bayesPositionWindow.resized(w,h); | 335 bayesPositionWindow.resized(w,h); |
329 } | 336 } |
330 | 337 |
331 | 338 /* |
332 | 339 |
340 void printPosteriorMAPinfo(){ //tmp print stuff | |
341 printf("New pitch MAP post estimate now %i, ", bayesianStruct.posterior.MAPestimate); | |
342 double tmp = bayesianStruct.posterior.getMAPestimate(); | |
343 printf(" getting it %f and offset %f == %f ms\n", tmp, bayesianStruct.posterior.offset, bayesianStruct.posterior.getIndexInRealTerms(tmp)); | |
344 | |
345 } | |
346 */ | |
347 |