Mercurial > hg > multitrack-audio-matcher
comparison src/AudioEventMatcher.cpp @ 7:33dedfe32893
kick, snare and bass windowed. Likelihoods in dedicated screen regions
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Thu, 02 Feb 2012 21:55:51 +0000 |
parents | 746a5af43c02 |
children | 572564b7cb85 |
comparison
equal
deleted
inserted
replaced
6:746a5af43c02 | 7:33dedfe32893 |
---|---|
11 | 11 |
12 | 12 |
13 const int matchWindowWidth = 6000; | 13 const int matchWindowWidth = 6000; |
14 | 14 |
15 AudioEventMatcher::AudioEventMatcher(){ | 15 AudioEventMatcher::AudioEventMatcher(){ |
16 bayesPositionWindow.setToRelativeSize(0, 0.4, 1, 0.2); | 16 |
17 bayesTempoWindow.setToRelativeSize(0, 0.8, 1, 0.2); | |
18 bayesLikelihoodWindow.setToRelativeSize(0, 0.6, 1, 0.2); | |
19 | |
20 setArraySizes(); | 17 setArraySizes(); |
21 | 18 |
22 usingRealTime = false; | 19 usingRealTime = false; |
23 bayesianStruct.realTimeMode = &usingRealTime; | 20 bayesianStruct.realTimeMode = &usingRealTime; |
24 } | 21 recentPitch = 0; |
25 | 22 } |
23 | |
24 void AudioEventMatcher::setWindowDimensions(){ | |
25 double startHeight = recordedTracks.numberOfAudioTracks * recordedTracks.trackScreenHeight; | |
26 double heightAvailable = 1 - startHeight; | |
27 heightAvailable /= 3.0; | |
28 | |
29 bayesPositionWindow.setToRelativeSize(0, startHeight, 1, heightAvailable); | |
30 bayesLikelihoodWindow.setToRelativeSize(0, startHeight + 1*heightAvailable, 1, heightAvailable); | |
31 bayesTempoWindow.setToRelativeSize(0, startHeight + 2*heightAvailable, 1, heightAvailable); | |
32 | |
33 | |
34 } | |
26 | 35 |
27 void AudioEventMatcher::setArraySizes(){ | 36 void AudioEventMatcher::setArraySizes(){ |
28 bayesianStruct.resetSpeedSize(200); | 37 bayesianStruct.resetSpeedSize(200); |
29 bayesianStruct.setRelativeSpeedScalar(0.01); | 38 bayesianStruct.setRelativeSpeedScalar(0.01); |
30 bayesianStruct.setSpeedPrior(1.0); | 39 bayesianStruct.setSpeedPrior(1.0); |
46 bayesPositionWindow.drawOutline(); | 55 bayesPositionWindow.drawOutline(); |
47 bayesTempoWindow.drawOutline(); | 56 bayesTempoWindow.drawOutline(); |
48 | 57 |
49 //draw the scrolling audio tracks | 58 //draw the scrolling audio tracks |
50 recordedTracks.drawTracks(); | 59 recordedTracks.drawTracks(); |
60 | |
61 | |
51 | 62 |
52 ofSetColor(255); | 63 ofSetColor(255); |
53 // bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow); | 64 // bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow); |
54 | 65 |
55 drawBayesianDistributions(); | 66 drawBayesianDistributions(); |
57 | 68 |
58 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); | 69 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); |
59 | 70 |
60 // bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow); | 71 // bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow); |
61 | 72 |
73 ofDrawBitmapString("pitch "+ofToString(recentPitch, 2)+", Time "+ofToString(recentTime, 0), 20, 20); | |
62 } | 74 } |
63 | 75 |
64 void AudioEventMatcher::drawBayesianDistributions(){ | 76 void AudioEventMatcher::drawBayesianDistributions(){ |
65 | 77 |
66 | 78 |
94 ofDrawBitmapString(tmpStr, 20, 180); | 106 ofDrawBitmapString(tmpStr, 20, 180); |
95 | 107 |
96 ofDrawBitmapString("screenamp "+ofToString(screenWidthMillis), 20, 100); | 108 ofDrawBitmapString("screenamp "+ofToString(screenWidthMillis), 20, 100); |
97 | 109 |
98 | 110 |
111 | |
112 //draw track by track likelihoods | |
113 for (int i = 0; i <recordedTracks.numberOfAudioTracks;i++){ | |
114 ofSetColor(200,255,50); | |
115 likelihoodVisualisation[i].drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window); | |
116 } | |
117 | |
99 } | 118 } |
100 | 119 |
101 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ | 120 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ |
121 if (pitchIn > 0){ | |
102 liveInput.addPitchEvent(pitchIn, timeIn); | 122 liveInput.addPitchEvent(pitchIn, timeIn); |
103 | 123 |
104 //tmp print stuff | 124 //tmp print stuff |
105 printf("New pitch MAP post estimate now %i, ", bayesianStruct.posterior.MAPestimate); | 125 printf("New pitch MAP post estimate now %i, ", bayesianStruct.posterior.MAPestimate); |
106 double tmp = bayesianStruct.posterior.getMAPestimate(); | 126 double tmp = bayesianStruct.posterior.getMAPestimate(); |
107 printf(" getting it %f and offset %f == %f ms\n", tmp, bayesianStruct.posterior.offset, bayesianStruct.posterior.getIndexInRealTerms(tmp)); | 127 printf(" getting it %f and offset %f == %f ms\n", tmp, bayesianStruct.posterior.offset, bayesianStruct.posterior.getIndexInRealTerms(tmp)); |
108 | 128 |
109 matchNewPitchEvent(channel, pitchIn, timeIn); | 129 matchNewPitchEvent(channel, pitchIn, timeIn);//main pitch matching fn |
130 | |
131 likelihoodVisualisation[1] = bayesianStruct.likelihood; | |
132 | |
133 recentPitch = pitchIn;//for drawing | |
134 recentTime = timeIn; | |
135 } | |
110 } | 136 } |
111 | 137 |
112 void AudioEventMatcher::newKickEvent(const double& timeIn){ | 138 void AudioEventMatcher::newKickEvent(const double& timeIn){ |
113 // liveInput.addKickEvent(timeIn); | 139 // liveInput.addKickEvent(timeIn); |
114 matchNewOnsetEvent(0, timeIn); | 140 matchNewOnsetEvent(0, timeIn); |
141 likelihoodVisualisation[0] = bayesianStruct.likelihood; | |
115 } | 142 } |
116 | 143 |
117 void AudioEventMatcher::newKickEvent(const int& channel, const double& timeIn){ | 144 void AudioEventMatcher::newKickEvent(const int& channel, const double& timeIn){ |
118 // liveInput.addKickEvent(timeIn); | 145 // liveInput.addKickEvent(timeIn); |
119 matchNewOnsetEvent(channel, timeIn); | 146 matchNewOnsetEvent(channel, timeIn); |
147 likelihoodVisualisation[0] = bayesianStruct.likelihood; | |
120 } | 148 } |
121 | 149 |
122 | 150 |
123 void AudioEventMatcher::newSnareEvent(const double& timeIn){ | 151 void AudioEventMatcher::newSnareEvent(const double& timeIn){ |
124 matchNewOnsetEvent(2, timeIn); | 152 matchNewOnsetEvent(2, timeIn); |
153 likelihoodVisualisation[2] = bayesianStruct.likelihood; | |
154 } | |
155 | |
156 | |
157 void AudioEventMatcher::newSnareEvent(const int& channel, const double& timeIn){ | |
158 matchNewOnsetEvent(channel, timeIn); | |
159 likelihoodVisualisation[2] = bayesianStruct.likelihood; | |
125 } | 160 } |
126 | 161 |
127 //Needs just to set bounds for the matching process, not have TimeIn | 162 //Needs just to set bounds for the matching process, not have TimeIn |
128 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){ | 163 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){ |
129 | 164 |
172 //start at beginning but OPTIMISE later | 207 //start at beginning but OPTIMISE later |
173 | 208 |
174 | 209 |
175 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets | 210 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets |
176 | 211 |
177 ///set offsets | 212 //set the lielihoods by matching the pitched note |
178 // bayesianStruct.likelihood.offset = bayesianStruct.prior.offset; | 213 |
179 double pitchLikelihoodToNoise = 0.2;//more noise | 214 double pitchLikelihoodToNoise = 0.6;//more noise |
180 int numberOfMatches = 0; | 215 int numberOfMatches = 0; |
181 bayesianStruct.likelihood.zero();//set to zero | 216 bayesianStruct.likelihood.zero();//set to zero |
182 | 217 |
183 double quantity = 0; | 218 double quantity = 0; |
184 if (channel <= recordedTracks.numberOfAudioTracks){ | 219 if (channel <= recordedTracks.numberOfAudioTracks){ |
185 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ | 220 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ |
186 | 221 |
187 if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) { | 222 if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) { |
188 quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 20); | 223 quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 10); |
189 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity); | 224 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity); |
190 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true; | 225 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true; |
191 numberOfMatches++; | 226 numberOfMatches++; |
192 } | 227 } |
193 else{ | 228 else{ |
196 | 231 |
197 } | 232 } |
198 } | 233 } |
199 | 234 |
200 if (numberOfMatches > 0){//no point updating unless there is a match | 235 if (numberOfMatches > 0){//no point updating unless there is a match |
236 | |
201 bayesianStruct.likelihood.addConstant(numberOfMatches*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length)); | 237 bayesianStruct.likelihood.addConstant(numberOfMatches*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length)); |
202 | 238 |
203 //tmp set likelihood constant and calculate using that | 239 //tmp set likelihood constant and calculate using that |
204 //bayesianStruct.likelihood.zero(); | 240 //bayesianStruct.likelihood.zero(); |
205 //bayesianStruct.likelihood.addConstant(1); | 241 //bayesianStruct.likelihood.addConstant(1); |
206 | 242 |
207 bayesianStruct.calculatePosterior(); | 243 bayesianStruct.calculatePosterior(); |
208 } | 244 } |
209 | 245 |
210 } | 246 } |
211 | 247 |