comparison src/AudioEventMatcher.cpp @ 3:5e188c0035b6

checking the offsets of the arrays
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Wed, 01 Feb 2012 16:05:26 +0000
parents 179c09199b3c
children 45b5cf9be377
comparison
equal deleted inserted replaced
2:179c09199b3c 3:5e188c0035b6
11 11
12 12
13 const int matchWindowWidth = 6000; 13 const int matchWindowWidth = 6000;
14 14
15 AudioEventMatcher::AudioEventMatcher(){ 15 AudioEventMatcher::AudioEventMatcher(){
16 16 bayesPositionWindow.setToRelativeSize(0, 0.4, 1, 0.2);
17 bayesTempoWindow.setToRelativeSize(0, 0.6, 1, 0.2); 17 bayesTempoWindow.setToRelativeSize(0, 0.8, 1, 0.2);
18 bayesPositionWindow.setToRelativeSize(0, 0.8, 1, 0.2); 18 bayesLikelihoodWindow.setToRelativeSize(0, 0.6, 1, 0.2);
19 19
20 setArraySizes(); 20 setArraySizes();
21
22 usingRealTime = false;
23 bayesianStruct.realTimeMode = &usingRealTime;
21 } 24 }
22 25
23 26
24 void AudioEventMatcher::setArraySizes(){ 27 void AudioEventMatcher::setArraySizes(){
25 bayesianStruct.resetSpeedSize(200); 28 bayesianStruct.resetSpeedSize(200);
30 bayesianStruct.resetSize(matchWindowWidth); 33 bayesianStruct.resetSize(matchWindowWidth);
31 bayesianStruct.setPositionDistributionScalar(1); 34 bayesianStruct.setPositionDistributionScalar(1);
32 35
33 } 36 }
34 37
38 void AudioEventMatcher::startPlaying(){
39 bayesianStruct.setStartPlaying();
40 //bayesianStruct.posterior.printArray();
41 }
42
35 void AudioEventMatcher::draw(){ 43 void AudioEventMatcher::draw(){
36 //ofRect(20, 20, 300, 200); 44 ofSetColor(20,200,200);
45 bayesPositionWindow.drawOutline();
46 bayesTempoWindow.drawOutline();
37 47
38 recordedTracks.drawTracks(); 48 recordedTracks.drawTracks();
39 49
40 ofSetColor(255); 50 ofSetColor(255);
41 // bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow); 51 // bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow);
42 52
43 double screenWidthMillis = recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.framesToMillis(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.amplitudeNumber); 53 double screenWidthMillis = recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.framesToMillis(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.amplitudeNumber);
44 54
45 55 bayesianStruct.likelihood.drawVector(bayesianStruct.likelihood.getRealTermsAsIndex(0), bayesianStruct.likelihood.getRealTermsAsIndex(screenWidthMillis), bayesLikelihoodWindow);
46 bayesianStruct.likelihood.drawVector(0, screenWidthMillis, bayesTempoWindow); 56
57 bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow);
58
59 bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow);
60
61 string tmpStr = "zero is "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(0));
62 tmpStr += " offsetis "+ofToString(bayesianStruct.posterior.offset);
63 tmpStr += " screenWidth = "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis));
64 ofDrawBitmapString(tmpStr, 20,140);
65 tmpStr = "best est "+ofToString(bayesianStruct.bestEstimate);
66 ofDrawBitmapString(tmpStr, 20, 180);
67
68 ofDrawBitmapString("screenamp "+ofToString(screenWidthMillis), 20, 100);
69
47 70
48 } 71 }
49 72
50 73
51 void AudioEventMatcher::newPitchEvent(const double& pitchIn, const double& timeIn){ 74 void AudioEventMatcher::newPitchEvent(const double& pitchIn, const double& timeIn){
52 liveInput.addPitchEvent(pitchIn, timeIn); 75 liveInput.addPitchEvent(pitchIn, timeIn);
53 recordedTracks.matchNewPitchEvent(0, pitchIn, timeIn); 76 matchNewPitchEvent(0, pitchIn, timeIn);
54 } 77 }
55 78
56 void AudioEventMatcher::newKickEvent(const double& timeIn){ 79 void AudioEventMatcher::newKickEvent(const double& timeIn){
80 // liveInput.addKickEvent(time);
57 matchNewOnsetEvent(0, timeIn); 81 matchNewOnsetEvent(0, timeIn);
58 } 82 }
59 83
60 84
61 void AudioEventMatcher::newSnareEvent(const double& timeIn){ 85 void AudioEventMatcher::newSnareEvent(const double& timeIn){
62 matchNewOnsetEvent(0, timeIn); 86 matchNewOnsetEvent(0, timeIn);
63 } 87 }
64 88
65 //Needs just to set bounds for the matching process, not have TimeIn 89 //Needs just to set bounds for the matching process, not have TimeIn
66 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){ 90 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){
91
92
67 //start at beginning but OPTIMISE later 93 //start at beginning but OPTIMISE later
68 double likelihoodToNoise = 0.5; 94 double onsetLikelihoodToNoise = 0.5;
69 95
70 double likelihoodWidth = 40; 96 double likelihoodWidth = 40;
71 97
72 bayesianStruct.likelihood.offset = bayesianStruct.prior.offset; 98 bayesianStruct.likelihood.offset = bayesianStruct.prior.offset;
73 bayesianStruct.likelihood.zero();//set to zero 99 bayesianStruct.likelihood.zero();//set to zero
89 115
90 } 116 }
91 } 117 }
92 } 118 }
93 119
120 // bayesianStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesianStruct.likelihood.length);
121 bayesianStruct.likelihood.addConstant(numberOfMatchesFound*(1-onsetLikelihoodToNoise)/(onsetLikelihoodToNoise*bayesianStruct.likelihood.length));
122
94 bayesianStruct.likelihood.renormalise(); 123 bayesianStruct.likelihood.renormalise();
95 124
96 //bayesStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesStruct.likelihood.length); 125
97 126 }
98 127
99 } 128
129
130 void AudioEventMatcher::matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){
131 //start at beginning but OPTIMISE later
132
133
134 updateBayesianDistributions(timeIn);
135
136 ///set offsets
137 // bayesianStruct.likelihood.offset = bayesianStruct.prior.offset;
138 double pitchLikelihoodToNoise = 0.5;
139 int numberOfMatches = 0;
140 bayesianStruct.likelihood.zero();//set to zero
141
142 double quantity = 0;
143 if (channel <= recordedTracks.numberOfAudioTracks){
144 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){
145
146 if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) {
147 quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 40);
148 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity);
149 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true;
150 numberOfMatches++;
151 }
152 else{
153 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = false;
154 }
155
156 }
157 }
158
159 bayesianStruct.likelihood.addConstant(numberOfMatches*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length));
160
161 recordedTracks.recentPitch = pitchIn;
162 }
163
164 double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){
165
166 double distance = abs(pitchOne - pitchTwo);
167 if (distance < scale)
168 distance = 1 - (distance/scale);
169 else
170 distance = 0;
171
172 // printf("[pitch distance %f vs %f = %f\n", pitchOne, pitchTwo, distance);
173 return distance;
174
175 }
176
177
178 bool AudioEventMatcher::checkMatch(const double& recordedPitch, const double& livePitch){
179 if (abs(recordedPitch - livePitch) < 40)
180 return true;
181 else
182 return false;
183 }
184
100 185
101 186
102 void AudioEventMatcher::windowResized(const int& w, const int& h){ 187 void AudioEventMatcher::windowResized(const int& w, const int& h){
103 recordedTracks.windowResized(w,h); 188 recordedTracks.windowResized(w,h);
104 } 189 bayesTempoWindow.resized(w,h);
190 bayesPositionWindow.resized(w,h);
191 }
192
193
194
195 void AudioEventMatcher::updateBayesianDistributions(const double& newEventTime){
196 //MOVE INTO bayesianStruct?? XX
197
198
199
200 //NEED TO CHECK HERE THAT THEY HAVE THE SAME OFFSETS
201 bayesianStruct.prior.copyFromDynamicVector(bayesianStruct.posterior);//try the otehr way
202
203 //bayesianStruct.copyPriorToPosterior();
204 //need to get new MAP position and set the offset of the arrays
205 //currently bestEstimate is the approx for the new MAP position
206
207 double timeDifference = newEventTime - bayesianStruct.lastEventTime;
208 printf("updating distributions at time %f diff %f\n", newEventTime, timeDifference);
209
210 //addnoise to the tempo distribution
211 //bayesianStruct.decaySpeedDistribution(timeDifference);
212
213 if (timeDifference > 50){
214 bayesianStruct.addGaussianNoiseToSpeedPosterior(timeDifference * 10.0 / 100.);
215 }
216
217 bayesianStruct.updateBestEstimate(timeDifference);
218
219 bayesianStruct.lastBestEstimateUpdateTime = newEventTime;//getTimeNow(timePlayed);
220
221 bayesianStruct.setNewDistributionOffsets(max(0., bayesianStruct.bestEstimate - (bayesianStruct.prior.scalar*bayesianStruct.prior.arraySize/2)));
222
223 bayesianStruct.crossUpdateArrays(bayesianStruct.posterior, bayesianStruct.relativeSpeedPosterior, timeDifference);
224
225 bayesianStruct.posterior.offset = max(0., bayesianStruct.bestEstimate - (bayesianStruct.prior.scalar*bayesianStruct.prior.arraySize/2));// bayesianStruct.prior.offset = max(0., bayesianStruct.bestEstimate - (bayesianStruct.prior.scalar*bayesianStruct.prior.arraySize/2));
226
227 bayesianStruct.lastEventTime = newEventTime;//bayesianStruct.lastEventTime = ofGetElapsedTimeMillis();
228 }