comparison Tempogram.cpp @ 1:3fd1a41b089b

* Now displaying some output. Needs testing to see if bugs are present.
author Carl Bussey <c.bussey@se10.qmul.ac.uk>
date Wed, 09 Jul 2014 10:26:51 +0100
parents 31d2a7e07786
children 1d0b7dcea27f
comparison
equal deleted inserted replaced
0:31d2a7e07786 1:3fd1a41b089b
15 using namespace std; 15 using namespace std;
16 16
17 Tempogram::Tempogram(float inputSampleRate) : 17 Tempogram::Tempogram(float inputSampleRate) :
18 Plugin(inputSampleRate), 18 Plugin(inputSampleRate),
19 m_blockSize(0), 19 m_blockSize(0),
20 m_stepSize(0),
20 compressionConstant(1000), //make param 21 compressionConstant(1000), //make param
21 previousY(NULL), 22 previousY(NULL),
22 currentY(NULL), 23 currentY(NULL),
23 tN(1024), //make param 24 tN(1024), //make param
24 thopSize(512), //make param 25 thopSize(512), //make param
95 } 96 }
96 97
97 size_t 98 size_t
98 Tempogram::getPreferredStepSize() const 99 Tempogram::getPreferredStepSize() const
99 { 100 {
100 //23 ms?
101 return 0; // 0 means "anything sensible"; in practice this 101 return 0; // 0 means "anything sensible"; in practice this
102 // means the same as the block size for TimeDomain 102 // means the same as the block size for TimeDomain
103 // plugins, or half of it for FrequencyDomain plugins 103 // plugins, or half of it for FrequencyDomain plugins
104 } 104 }
105 105
172 172
173 void 173 void
174 Tempogram::setParameter(string identifier, float value) 174 Tempogram::setParameter(string identifier, float value)
175 { 175 {
176 if (identifier == "C") { 176 if (identifier == "C") {
177 compressionConstant = value;// set the actual value of your parameter 177 compressionConstant = value; // set the actual value of your parameter
178 } 178 }
179 if (identifier == "tN") { 179 if (identifier == "tN") {
180 tN = value; 180 tN = value;
181 } 181 }
182 } 182 }
208 { 208 {
209 OutputList list; 209 OutputList list;
210 210
211 // See OutputDescriptor documentation for the possibilities here. 211 // See OutputDescriptor documentation for the possibilities here.
212 // Every plugin must have at least one output. 212 // Every plugin must have at least one output.
213 213
214 OutputDescriptor d; 214 OutputDescriptor d;
215 d.identifier = "output"; 215 d.identifier = "tempogram";
216 d.name = "Cyclic Tempogram"; 216 d.name = "Cyclic Tempogram";
217 d.description = "Cyclic Tempogram"; 217 d.description = "Cyclic Tempogram";
218 d.unit = ""; 218 d.unit = "";
219 d.hasFixedBinCount = false; 219 d.hasFixedBinCount = true;
220 //d.binCount = 1; 220 d.binCount = tN;
221 d.hasKnownExtents = false; 221 d.hasKnownExtents = false;
222 d.isQuantized = false; 222 d.isQuantized = false;
223 d.sampleType = OutputDescriptor::VariableSampleRate; 223 d.sampleType = OutputDescriptor::FixedSampleRate;
224 d.sampleRate = 0.0; 224 float d_sampleRate = m_inputSampleRate/(m_stepSize * thopSize);
225 d.sampleRate = d_sampleRate > 0.0 && !isnan(d_sampleRate) ? d_sampleRate : 0.0;
225 d.hasDuration = false; 226 d.hasDuration = false;
226 list.push_back(d); 227 list.push_back(d);
227 228
229 d.identifier = "nc";
230 d.name = "Novelty Curve";
231 d.description = "Novelty Curve";
232 d.unit = "";
233 d.hasFixedBinCount = true;
234 d.binCount = 1;
235 d.hasKnownExtents = false;
236 d.isQuantized = false;
237 d.sampleType = OutputDescriptor::FixedSampleRate;
238 d_sampleRate = m_inputSampleRate/m_stepSize;
239 d.sampleRate = d_sampleRate > 0 && !isnan(d_sampleRate) ? d_sampleRate : 0.0;
240 d.hasDuration = false;
241 list.push_back(d);
242
228 return list; 243 return list;
229 } 244 }
230 245
231 bool 246 bool
232 Tempogram::initialise(size_t channels, size_t stepSize, size_t blockSize) 247 Tempogram::initialise(size_t channels, size_t stepSize, size_t blockSize)
234 if (channels < getMinChannelCount() || 249 if (channels < getMinChannelCount() ||
235 channels > getMaxChannelCount()) return false; 250 channels > getMaxChannelCount()) return false;
236 251
237 // Real initialisation work goes here! 252 // Real initialisation work goes here!
238 m_blockSize = blockSize; 253 m_blockSize = blockSize;
254 m_stepSize = stepSize;
239 currentY = new float[m_blockSize]; 255 currentY = new float[m_blockSize];
240 previousY = new float[m_blockSize]; 256 previousY = new float[m_blockSize];
241 257
242 return true; 258 return true;
243 } 259 }
253 { 269 {
254 size_t n = m_blockSize/2 + 1; 270 size_t n = m_blockSize/2 + 1;
255 271
256 FeatureSet featureSet; 272 FeatureSet featureSet;
257 Feature feature; 273 Feature feature;
258 feature.hasTimestamp = false;
259 274
260 const float *in = inputBuffers[0]; 275 const float *in = inputBuffers[0];
261 276
262 //Calculate log magnitude 277 //Calculate log magnitude
263 float sum = 0; 278 float sum = 0;
310 Tempogram::FeatureSet 325 Tempogram::FeatureSet
311 Tempogram::getRemainingFeatures() 326 Tempogram::getRemainingFeatures()
312 { 327 {
313 //Make sure this is called at the beginning of the function 328 //Make sure this is called at the beginning of the function
314 initialiseForGRF(); 329 initialiseForGRF();
330 FeatureSet featureSet;
315 331
316 vector<float> noveltyCurveLocalAverage(ncLength); 332 vector<float> noveltyCurveLocalAverage(ncLength);
317 333
318 FIRFilter *filter = new FIRFilter(ncLength, hannN); 334 FIRFilter *filter = new FIRFilter(ncLength, hannN);
319 filter->process(&noveltyCurve[0], hannWindow, &noveltyCurveLocalAverage[0]); 335 filter->process(&noveltyCurve[0], hannWindow, &noveltyCurveLocalAverage[0]);
320 delete filter; 336 delete filter;
321 337
322 for(int i = 0; i < ncLength; i++){ 338 for(int i = 0; i < ncLength; i++){
323 noveltyCurve[i] -= noveltyCurveLocalAverage[i]; 339 noveltyCurve[i] -= noveltyCurveLocalAverage[i];
324 noveltyCurve[i] = noveltyCurve[i] >= 0 ? noveltyCurve[i] : 0; 340 noveltyCurve[i] = noveltyCurve[i] >= 0 ? noveltyCurve[i] : 0;
341 Feature ncFeature;
342 ncFeature.values.push_back(noveltyCurve[i]);
343 featureSet[1].push_back(ncFeature);
325 } 344 }
326 345
327 int i=0; 346 int i=0;
328 WindowFunction::hanning(hannWindowtN, tN); 347 WindowFunction::hanning(hannWindowtN, tN);
329 348
330 int index; 349 int index;
331 int start = floor(tN/2 + 0.5); 350 int frameBeginOffset = floor(tN/2 + 0.5);
332 int timestampInc = floor((((float)ncTimestamps[1].nsec - ncTimestamps[0].nsec)/1e9)*(thopSize) + 0.5); 351 int timestampInc = floor((((float)ncTimestamps[1].nsec - ncTimestamps[0].nsec)/1e9)*(thopSize) + 0.5);
333 //cout << timestampInc << endl; 352 //cout << timestampInc << endl;
334 353
335 FeatureSet featureSet;
336
337 while(i < ncLength){ 354 while(i < ncLength){
338 Feature feature; 355 Feature feature;
339 Vamp::RealTime timestamp;
340 356
341 for (int n = start; n < tN; n++){ 357 for (int n = frameBeginOffset; n < tN; n++){
342 index = i + n - tN/2; 358 index = i + n - tN/2;
343 assert (index >= 0); 359 assert (index >= 0);
344 360
345 if(index < ncLength){ 361 if(index < ncLength){
346 fftInput[n] = noveltyCurve[i + n] * hannWindowtN[n]; 362 fftInput[n] = noveltyCurve[i + n] * hannWindowtN[n];
349 fftInput[n] = 0.0; //pad the end with zeros 365 fftInput[n] = 0.0; //pad the end with zeros
350 } 366 }
351 //cout << fftInput[n] << endl; 367 //cout << fftInput[n] << endl;
352 } 368 }
353 if (i+tN/2 > ncLength){ 369 if (i+tN/2 > ncLength){
354 timestamp = Vamp::RealTime::fromSeconds(ncTimestamps[i].sec + timestampInc); 370 feature.timestamp = Vamp::RealTime::fromSeconds(ncTimestamps[i].sec + timestampInc);
355 } 371 }
356 else{ 372 else{
357 timestamp = ncTimestamps[i + tN/2]; 373 feature.timestamp = ncTimestamps[i + tN/2];
358 } 374 }
359 375
360 FFT::forward(tN, fftInput, NULL, fftOutputReal, fftOutputImag); 376 FFT::forward(tN, fftInput, NULL, fftOutputReal, fftOutputImag);
361 377
362 //TODO: sample at logarithmic spacing 378 //TODO: sample at logarithmic spacing
363 for(int k = 0; k < tN; k++){ 379 for(int k = 0; k < tN; k++){
364 double fftOutputPower = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power? 380 float fftOutputPower = (fftOutputReal[k]*fftOutputReal[k] + fftOutputImag[k]*fftOutputImag[k]); //Magnitude or power?
365 assert (!isinf(fftOutputPower));
366 381
367 feature.values.push_back(fftOutputPower); 382 feature.values.push_back(fftOutputPower);
368 } 383 }
369 384
370 i += thopSize; 385 i += thopSize;
371 start = 0; 386 frameBeginOffset = 0;
372 387
373 feature.timestamp = timestamp;
374 feature.hasTimestamp = true; 388 feature.hasTimestamp = true;
375 featureSet[0].push_back(feature); 389 featureSet[0].push_back(feature);
376 } 390 }
377 391
378 //Make sure this is called at the end of the function 392 //Make sure this is called at the end of the function