comparison src/Silvet.cpp @ 246:70773820e719 norm eval-norm-u4

Use flattendynamics code within Silvet
author Chris Cannam
date Tue, 22 Jul 2014 16:11:20 +0100
parents b5a8836dd2a4
children 6b7e78cf96c9
comparison
equal deleted inserted replaced
245:4411aff3df52 246:70773820e719
18 18
19 #include <cq/CQSpectrogram.h> 19 #include <cq/CQSpectrogram.h>
20 20
21 #include "MedianFilter.h" 21 #include "MedianFilter.h"
22 #include "constant-q-cpp/src/dsp/Resampler.h" 22 #include "constant-q-cpp/src/dsp/Resampler.h"
23 #include "flattendynamics-ladspa.h"
23 24
24 #include <vector> 25 #include <vector>
25 26
26 #include <cstdio> 27 #include <cstdio>
27 28
36 37
37 Silvet::Silvet(float inputSampleRate) : 38 Silvet::Silvet(float inputSampleRate) :
38 Plugin(inputSampleRate), 39 Plugin(inputSampleRate),
39 m_instruments(InstrumentPack::listInstrumentPacks()), 40 m_instruments(InstrumentPack::listInstrumentPacks()),
40 m_resampler(0), 41 m_resampler(0),
42 m_flattener(0),
41 m_cq(0), 43 m_cq(0),
42 m_hqMode(true), 44 m_hqMode(true),
43 m_fineTuning(false), 45 m_fineTuning(false),
44 m_instrument(0), 46 m_instrument(0),
45 m_colsPerSec(50) 47 m_colsPerSec(50)
47 } 49 }
48 50
49 Silvet::~Silvet() 51 Silvet::~Silvet()
50 { 52 {
51 delete m_resampler; 53 delete m_resampler;
54 delete m_flattener;
52 delete m_cq; 55 delete m_cq;
53 for (int i = 0; i < (int)m_postFilter.size(); ++i) { 56 for (int i = 0; i < (int)m_postFilter.size(); ++i) {
54 delete m_postFilter[i]; 57 delete m_postFilter[i];
55 } 58 }
56 } 59 }
228 d.binNames.push_back("Frequency"); 231 d.binNames.push_back("Frequency");
229 d.binNames.push_back("Velocity"); 232 d.binNames.push_back("Velocity");
230 d.hasKnownExtents = false; 233 d.hasKnownExtents = false;
231 d.isQuantized = false; 234 d.isQuantized = false;
232 d.sampleType = OutputDescriptor::VariableSampleRate; 235 d.sampleType = OutputDescriptor::VariableSampleRate;
233 d.sampleRate = m_inputSampleRate / (m_cq ? m_cq->getColumnHop() : 62); 236 d.sampleRate = processingSampleRate / (m_cq ? m_cq->getColumnHop() : 62);
234 d.hasDuration = true; 237 d.hasDuration = true;
235 m_notesOutputNo = list.size(); 238 m_notesOutputNo = list.size();
236 list.push_back(d); 239 list.push_back(d);
237 240
238 d.identifier = "timefreq"; 241 d.identifier = "timefreq";
344 347
345 void 348 void
346 Silvet::reset() 349 Silvet::reset()
347 { 350 {
348 delete m_resampler; 351 delete m_resampler;
352 delete m_flattener;
349 delete m_cq; 353 delete m_cq;
350 354
351 if (m_inputSampleRate != processingSampleRate) { 355 if (m_inputSampleRate != processingSampleRate) {
352 m_resampler = new Resampler(m_inputSampleRate, processingSampleRate); 356 m_resampler = new Resampler(m_inputSampleRate, processingSampleRate);
353 } else { 357 } else {
354 m_resampler = 0; 358 m_resampler = 0;
355 } 359 }
360
361 m_flattener = new FlattenDynamics(m_inputSampleRate); // before resampling
362 m_flattener->reset();
356 363
357 double minFreq = 27.5; 364 double minFreq = 27.5;
358 365
359 if (!m_hqMode) { 366 if (!m_hqMode) {
360 // We don't actually return any notes from the bottom octave, 367 // We don't actually return any notes from the bottom octave,
386 m_postFilter.clear(); 393 m_postFilter.clear();
387 for (int i = 0; i < m_instruments[0].templateNoteCount; ++i) { 394 for (int i = 0; i < m_instruments[0].templateNoteCount; ++i) {
388 m_postFilter.push_back(new MedianFilter<double>(3)); 395 m_postFilter.push_back(new MedianFilter<double>(3));
389 } 396 }
390 m_pianoRoll.clear(); 397 m_pianoRoll.clear();
398 m_inputGains.clear();
391 m_columnCount = 0; 399 m_columnCount = 0;
392 m_startTime = RealTime::zeroTime; 400 m_startTime = RealTime::zeroTime;
393 } 401 }
394 402
395 Silvet::FeatureSet 403 Silvet::FeatureSet
396 Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp) 404 Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
397 { 405 {
398 if (m_columnCount == 0) { 406 if (m_columnCount == 0) {
399 m_startTime = timestamp; 407 m_startTime = timestamp;
400 } 408 }
409
410 vector<float> flattened(m_blockSize);
411 float gain = 1.f;
412 m_flattener->connectInputPort
413 (FlattenDynamics::AudioInputPort, inputBuffers[0]);
414 m_flattener->connectOutputPort
415 (FlattenDynamics::AudioOutputPort, &flattened[0]);
416 m_flattener->connectOutputPort
417 (FlattenDynamics::GainOutputPort, &gain);
418 m_flattener->process(m_blockSize);
419
420 m_inputGains.push_back(gain);
401 421
402 vector<double> data; 422 vector<double> data;
403 for (int i = 0; i < m_blockSize; ++i) { 423 for (int i = 0; i < m_blockSize; ++i) {
404 double d = inputBuffers[0][i]; 424 double d = flattened[i];
405 data.push_back(d); 425 data.push_back(d);
406 } 426 }
407 427
408 if (m_resampler) { 428 if (m_resampler) {
409 data = m_resampler->process(data.data(), data.size()); 429 data = m_resampler->process(data.data(), data.size());
410 } 430 }
411 431
412 Grid cqout = m_cq->process(data); 432 Grid cqout = m_cq->process(data);
413 FeatureSet fs = transcribe(cqout); 433 FeatureSet fs = transcribe(cqout);
414 return fs; 434 return fs;
415 } 435 }
416 436
775 partShift = shift; 795 partShift = shift;
776 partVelocity = 0; 796 partVelocity = 0;
777 } 797 }
778 } 798 }
779 799
780 int v = strength * 2; 800 //!!! todo: do something with input gain. Presumably we need
801 //!!! to index it by something close to, but not actually, i
802 //!!! (depending on cq latency)
803
804 cerr << "i = " << i << ", gain length = " << m_inputGains.size()
805 << ", cq latency = " << m_cq->getLatency() << " (as columns = "
806 << m_cq->getLatency() / m_cq->getColumnHop() << ", as input blocks = "
807 << m_cq->getLatency() / m_blockSize << ")" << endl;
808
809 int v = round(strength * 2);
781 if (v > 127) v = 127; 810 if (v > 127) v = 127;
782 811
783 if (v > partVelocity) { 812 if (v > partVelocity) {
784 partVelocity = v; 813 partVelocity = v;
785 } 814 }