Mercurial > hg > silvet
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 |