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