Mercurial > hg > multitrack-audio-matcher
comparison src/AudioEventMatcher.cpp @ 8:572564b7cb85
added calculation posterior into both onset and pitch processes
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Fri, 03 Feb 2012 13:28:59 +0000 |
parents | 33dedfe32893 |
children | bc62266af280 |
comparison
equal
deleted
inserted
replaced
7:33dedfe32893 | 8:572564b7cb85 |
---|---|
17 setArraySizes(); | 17 setArraySizes(); |
18 | 18 |
19 usingRealTime = false; | 19 usingRealTime = false; |
20 bayesianStruct.realTimeMode = &usingRealTime; | 20 bayesianStruct.realTimeMode = &usingRealTime; |
21 recentPitch = 0; | 21 recentPitch = 0; |
22 currentAlignmentPosition = 0; | |
22 } | 23 } |
23 | 24 |
24 void AudioEventMatcher::setWindowDimensions(){ | 25 void AudioEventMatcher::setWindowDimensions(){ |
25 double startHeight = recordedTracks.numberOfAudioTracks * recordedTracks.trackScreenHeight; | 26 double startHeight = recordedTracks.numberOfAudioTracks * recordedTracks.trackScreenHeight; |
26 double heightAvailable = 1 - startHeight; | 27 double heightAvailable = 1 - startHeight; |
44 | 45 |
45 } | 46 } |
46 | 47 |
47 void AudioEventMatcher::startPlaying(){ | 48 void AudioEventMatcher::startPlaying(){ |
48 bayesianStruct.setStartPlaying(); | 49 bayesianStruct.setStartPlaying(); |
50 currentAlignmentPosition = 0; | |
51 startTime = ofGetElapsedTimeMillis(); | |
49 //bayesianStruct.posterior.printArray(); | 52 //bayesianStruct.posterior.printArray(); |
53 } | |
54 | |
55 void AudioEventMatcher::updateBestAlignmentPosition(){ | |
56 currentAlignmentPosition = bayesianStruct.posterior.offset + bayesianStruct.posterior.getIndexInRealTerms(bayesianStruct.posterior.MAPestimate); | |
57 currentAlignmentPosition += (ofGetElapsedTimeMillis() - lastAlignmentTime) * bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate); | |
50 } | 58 } |
51 | 59 |
52 void AudioEventMatcher::draw(){ | 60 void AudioEventMatcher::draw(){ |
53 //draw some outlines in blue | 61 //draw some outlines in blue |
54 ofSetColor(20,200,200); | 62 ofSetColor(20,200,200); |
62 | 70 |
63 ofSetColor(255); | 71 ofSetColor(255); |
64 // bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow); | 72 // bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow); |
65 | 73 |
66 drawBayesianDistributions(); | 74 drawBayesianDistributions(); |
75 | |
67 // bayesianStruct.posterior.drawVector(0, bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); | 76 // bayesianStruct.posterior.drawVector(0, bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); |
68 | 77 |
69 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); | 78 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); |
70 | 79 |
71 // bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow); | 80 // bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow); |
86 | 95 |
87 bayesianStruct.posterior.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesPositionWindow); | 96 bayesianStruct.posterior.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesPositionWindow); |
88 | 97 |
89 string tmpString = "start "+ofToString(screenStartTimeMillis)+" (index "+ofToString(startIndex)+"), end "+ofToString(screenEndTimeMillis); | 98 string tmpString = "start "+ofToString(screenStartTimeMillis)+" (index "+ofToString(startIndex)+"), end "+ofToString(screenEndTimeMillis); |
90 ofDrawBitmapString(tmpString, bayesPositionWindow.x+20, bayesPositionWindow.y+20); | 99 ofDrawBitmapString(tmpString, bayesPositionWindow.x+20, bayesPositionWindow.y+20); |
91 | 100 |
92 | 101 // bayesianStruct.likelihood.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesLikelihoodWindow); |
93 | 102 |
94 bayesianStruct.likelihood.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesLikelihoodWindow); | |
95 | |
96 | |
97 //bayesianStruct.likelihood.drawVector(bayesianStruct.likelihood.getRealTermsAsIndex(0), bayesianStruct.likelihood.getRealTermsAsIndex(screenWidthMillis), bayesLikelihoodWindow); | |
98 | |
99 bayesianStruct.relativeSpeedPosterior.drawConstrainedVector(0, bayesianStruct.relativeSpeedPosterior.arraySize, 0, ofGetWidth(), bayesTempoWindow); | 103 bayesianStruct.relativeSpeedPosterior.drawConstrainedVector(0, bayesianStruct.relativeSpeedPosterior.arraySize, 0, ofGetWidth(), bayesTempoWindow); |
100 | 104 |
101 string tmpStr = "zero is "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(0)); | 105 string tmpStr = "zero is "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(0)); |
102 tmpStr += " offsetis "+ofToString(bayesianStruct.posterior.offset); | 106 tmpStr += " offsetis "+ofToString(bayesianStruct.posterior.offset); |
103 tmpStr += " screenWidth = "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis)); | 107 tmpStr += " screenWidth = "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis)); |
104 ofDrawBitmapString(tmpStr, 20,140); | 108 ofDrawBitmapString(tmpStr, 20,140); |
105 tmpStr = "best est "+ofToString(bayesianStruct.bestEstimate); | 109 tmpStr = "best est "+ofToString(bayesianStruct.bestEstimate); |
106 ofDrawBitmapString(tmpStr, 20, 180); | 110 ofDrawBitmapString(tmpStr, 20, 180); |
107 | 111 |
108 ofDrawBitmapString("screenamp "+ofToString(screenWidthMillis), 20, 100); | 112 ofDrawBitmapString("screenwidth "+ofToString(screenWidthMillis), 20, 800); |
109 | 113 |
110 | 114 ofSetColor(0,255,0); |
115 double currentEstimateIndex = (currentAlignmentPosition - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis; | |
116 ofLine(currentEstimateIndex, bayesPositionWindow.y, currentEstimateIndex, bayesPositionWindow.y + bayesPositionWindow.height); | |
111 | 117 |
112 //draw track by track likelihoods | 118 //draw track by track likelihoods |
113 for (int i = 0; i <recordedTracks.numberOfAudioTracks;i++){ | 119 for (int i = 0; i <recordedTracks.numberOfAudioTracks;i++){ |
114 ofSetColor(200,255,50); | 120 ofSetColor(200,255,50); |
115 likelihoodVisualisation[i].drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window); | 121 likelihoodVisualisation[i].drawConstrainedVector(likelihoodVisualisation[i].getRealTermsAsIndex(screenStartTimeMillis), likelihoodVisualisation[i].getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window); |
116 } | 122 ofSetColor(255); |
123 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); | |
124 } | |
125 | |
126 int priorStartIndex = recentPrior.getRealTermsAsIndex(screenStartTimeMillis); | |
127 int priorEndIndex = recentPrior.getRealTermsAsIndex(screenEndTimeMillis); | |
128 ofSetColor(0,200,200); | |
129 recentPrior.drawConstrainedVector(priorStartIndex, priorEndIndex, 0, ofGetWidth(), bayesPositionWindow); | |
130 | |
131 // bayesianStruct.prior.addTriangularShape(100, 20, 0.4); | |
132 ofSetColor(255,0,100); | |
133 bayesianStruct.prior.drawConstrainedVector(bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis), bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), bayesLikelihoodWindow); | |
117 | 134 |
118 } | 135 } |
119 | 136 |
120 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ | 137 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ |
121 if (pitchIn > 0){ | 138 if (pitchIn > 0){ |
131 likelihoodVisualisation[1] = bayesianStruct.likelihood; | 148 likelihoodVisualisation[1] = bayesianStruct.likelihood; |
132 | 149 |
133 recentPitch = pitchIn;//for drawing | 150 recentPitch = pitchIn;//for drawing |
134 recentTime = timeIn; | 151 recentTime = timeIn; |
135 } | 152 } |
153 | |
154 | |
136 } | 155 } |
137 | 156 |
138 void AudioEventMatcher::newKickEvent(const double& timeIn){ | 157 void AudioEventMatcher::newKickEvent(const double& timeIn){ |
139 // liveInput.addKickEvent(timeIn); | 158 // liveInput.addKickEvent(timeIn); |
140 matchNewOnsetEvent(0, timeIn); | 159 matchNewOnsetEvent(0, timeIn); |
164 | 183 |
165 | 184 |
166 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets | 185 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets |
167 | 186 |
168 //start at beginning but OPTIMISE later | 187 //start at beginning but OPTIMISE later |
169 double onsetLikelihoodToNoise = 0.3; | 188 double onsetLikelihoodToNoise = 0.5; |
170 | 189 |
171 double likelihoodWidth = 40; | 190 double likelihoodWidth = 40; |
172 | 191 |
173 bayesianStruct.likelihood.offset = bayesianStruct.prior.offset; | 192 bayesianStruct.likelihood.offset = bayesianStruct.prior.offset; |
174 bayesianStruct.likelihood.zero();//set to zero | 193 bayesianStruct.likelihood.zero();//set to zero |
192 } | 211 } |
193 } | 212 } |
194 | 213 |
195 // bayesianStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesianStruct.likelihood.length); | 214 // bayesianStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesianStruct.likelihood.length); |
196 bayesianStruct.likelihood.addConstant(numberOfMatchesFound*(1-onsetLikelihoodToNoise)/(onsetLikelihoodToNoise*bayesianStruct.likelihood.length)); | 215 bayesianStruct.likelihood.addConstant(numberOfMatchesFound*(1-onsetLikelihoodToNoise)/(onsetLikelihoodToNoise*bayesianStruct.likelihood.length)); |
197 | |
198 bayesianStruct.likelihood.renormalise(); | 216 bayesianStruct.likelihood.renormalise(); |
199 | 217 |
200 | 218 bayesianStruct.calculatePosterior(); |
219 | |
220 lastAlignmentTime = ofGetElapsedTimeMillis(); | |
221 recentEventTime[channel] = ofGetElapsedTimeMillis() - startTime; | |
201 | 222 |
202 } | 223 } |
203 | 224 |
204 | 225 |
205 | 226 |
206 void AudioEventMatcher::matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ | 227 void AudioEventMatcher::matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ |
207 //start at beginning but OPTIMISE later | 228 //start at beginning but OPTIMISE later |
208 | 229 |
209 | 230 |
210 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets | 231 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets |
211 | 232 |
212 //set the lielihoods by matching the pitched note | 233 //set the lielihoods by matching the pitched note |
213 | 234 |
214 double pitchLikelihoodToNoise = 0.6;//more noise | 235 double pitchLikelihoodToNoise = 0.5;//more noise |
215 int numberOfMatches = 0; | 236 int numberOfMatches = 0; |
216 bayesianStruct.likelihood.zero();//set to zero | 237 bayesianStruct.likelihood.zero();//set to zero |
217 | 238 |
218 double quantity = 0; | 239 double quantity = 0; |
219 if (channel <= recordedTracks.numberOfAudioTracks){ | 240 if (channel <= recordedTracks.numberOfAudioTracks){ |
230 } | 251 } |
231 | 252 |
232 } | 253 } |
233 } | 254 } |
234 | 255 |
256 recentPrior = bayesianStruct.prior; | |
257 | |
258 | |
235 if (numberOfMatches > 0){//no point updating unless there is a match | 259 if (numberOfMatches > 0){//no point updating unless there is a match |
236 | 260 |
237 bayesianStruct.likelihood.addConstant(numberOfMatches*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length)); | 261 bayesianStruct.likelihood.addConstant(numberOfMatches*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length)); |
238 | 262 |
239 //tmp set likelihood constant and calculate using that | 263 //tmp set likelihood constant and calculate using that |
241 //bayesianStruct.likelihood.addConstant(1); | 265 //bayesianStruct.likelihood.addConstant(1); |
242 | 266 |
243 bayesianStruct.calculatePosterior(); | 267 bayesianStruct.calculatePosterior(); |
244 } | 268 } |
245 | 269 |
270 lastAlignmentTime = ofGetElapsedTimeMillis(); | |
271 recentEventTime[channel] = ofGetElapsedTimeMillis() - startTime; | |
246 } | 272 } |
247 | 273 |
248 double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){ | 274 double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){ |
249 | 275 |
250 double distance = abs(pitchOne - pitchTwo); | 276 double distance = abs(pitchOne - pitchTwo); |