comparison src/Silvet.cpp @ 40:303c06efa8d2

Return a sketch of notes from pitch activation matrix
author Chris Cannam
date Sat, 05 Apr 2014 13:18:55 +0100
parents 2b254fc68e81
children b49597c93132
comparison
equal deleted inserted replaced
39:2b254fc68e81 40:303c06efa8d2
26 #include <cstdio> 26 #include <cstdio>
27 27
28 using std::vector; 28 using std::vector;
29 using std::cerr; 29 using std::cerr;
30 using std::endl; 30 using std::endl;
31 using Vamp::RealTime;
31 32
32 static int processingSampleRate = 44100; 33 static int processingSampleRate = 44100;
33 static int processingBPO = 60; 34 static int processingBPO = 60;
34 static int processingHeight = 545; 35 static int processingHeight = 545;
35 static int processingNotes = 88; 36 static int processingNotes = 88;
166 167
167 OutputDescriptor d; 168 OutputDescriptor d;
168 d.identifier = "transcription"; 169 d.identifier = "transcription";
169 d.name = "Transcription"; 170 d.name = "Transcription";
170 d.description = ""; //!!! 171 d.description = ""; //!!!
171 d.unit = "Hz"; 172 d.unit = "MIDI Pitch";
172 d.hasFixedBinCount = true; 173 d.hasFixedBinCount = true;
173 d.binCount = 2; 174 d.binCount = 2;
174 d.binNames.push_back("Frequency"); 175 d.binNames.push_back("Note");
175 d.binNames.push_back("Velocity"); 176 d.binNames.push_back("Velocity");
176 d.hasKnownExtents = false; 177 d.hasKnownExtents = false;
177 d.isQuantized = false; 178 d.isQuantized = false;
178 d.sampleType = OutputDescriptor::VariableSampleRate; 179 d.sampleType = OutputDescriptor::VariableSampleRate;
179 d.sampleRate = m_inputSampleRate / (m_cq ? m_cq->getColumnHop() : 256); 180 d.sampleRate = m_inputSampleRate / (m_cq ? m_cq->getColumnHop() : 256);
287 m_filterA.push_back(new MedianFilter<double>(40)); 288 m_filterA.push_back(new MedianFilter<double>(40));
288 m_filterB.push_back(new MedianFilter<double>(40)); 289 m_filterB.push_back(new MedianFilter<double>(40));
289 } 290 }
290 m_columnCount = 0; 291 m_columnCount = 0;
291 m_reducedColumnCount = 0; 292 m_reducedColumnCount = 0;
293 m_transcribedColumnCount = 0;
294 m_startTime = RealTime::zeroTime;
292 } 295 }
293 296
294 Silvet::FeatureSet 297 Silvet::FeatureSet
295 Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp) 298 Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
296 { 299 {
300 if (m_columnCount == 0) {
301 m_startTime = timestamp;
302 }
303
297 vector<double> data; 304 vector<double> data;
298 for (int i = 0; i < m_blockSize; ++i) data.push_back(inputBuffers[0][i]); 305 for (int i = 0; i < m_blockSize; ++i) {
306 data.push_back(inputBuffers[0][i]);
307 }
299 308
300 if (m_resampler) { 309 if (m_resampler) {
301 data = m_resampler->process(data.data(), data.size()); 310 data = m_resampler->process(data.data(), data.size());
302 } 311 }
303 312
329 338
330 int width = filtered.size(); 339 int width = filtered.size();
331 340
332 int iterations = 12; 341 int iterations = 12;
333 342
343 // we have 25 columns per second
344 double columnDuration = 1.0 / 25.0;
345
334 for (int i = 0; i < width; ++i) { 346 for (int i = 0; i < width; ++i) {
347
348 RealTime t = m_startTime +
349 RealTime::fromSeconds(m_transcribedColumnCount * columnDuration);
350
351 ++m_transcribedColumnCount;
335 352
336 double sum = 0.0; 353 double sum = 0.0;
337 for (int j = 0; j < processingHeight; ++j) { 354 for (int j = 0; j < processingHeight; ++j) {
338 sum += filtered[i][j]; 355 sum += filtered[i][j];
339 } 356 }
347 } 364 }
348 365
349 vector<double> pitches = em.getPitchDistribution(); 366 vector<double> pitches = em.getPitchDistribution();
350 Feature f; 367 Feature f;
351 for (int j = 0; j < (int)pitches.size(); ++j) { 368 for (int j = 0; j < (int)pitches.size(); ++j) {
352 f.values.push_back(float(pitches[j])); 369 f.values.push_back(float(pitches[j] * sum));
353 } 370 }
354 fs[m_pitchOutputNo].push_back(f); 371 fs[m_pitchOutputNo].push_back(f);
372
373 //!!! fake notes
374 for (int j = 0; j < (int)pitches.size(); ++j) {
375 if (pitches[j] * sum > 5) {
376 cerr << "pitch " << j << " level: " << pitches[j] * sum << endl;
377 Feature nf;
378 nf.hasTimestamp = true;
379 nf.timestamp = t;
380 nf.hasDuration = true;
381 nf.duration = RealTime::fromSeconds(columnDuration);
382 nf.values.push_back(j + 21);
383 float velocity = pitches[j] * sum * 2;
384 if (velocity > 127.f) velocity = 127.f;
385 nf.values.push_back(velocity);
386 fs[m_notesOutputNo].push_back(nf);
387 }
388 }
355 389
356 //!!! now do something with the results from em! 390 //!!! now do something with the results from em!
357 em.report(); 391 em.report();
358 } 392 }
359 393