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