Mercurial > hg > silvet
diff src/Silvet.cpp @ 298:ebe5e0942bb8 livemode
More toward a possible live mode
author | Chris Cannam |
---|---|
date | Fri, 28 Nov 2014 10:18:22 +0000 |
parents | d6ab1b4918bd |
children | ba5f3b084466 |
line wrap: on
line diff
--- a/src/Silvet.cpp Fri Nov 28 09:42:56 2014 +0000 +++ b/src/Silvet.cpp Fri Nov 28 10:18:22 2014 +0000 @@ -21,6 +21,7 @@ #include "MedianFilter.h" #include "constant-q-cpp/src/dsp/Resampler.h" #include "flattendynamics-ladspa.h" +#include "LiveInstruments.h" #include <vector> @@ -33,7 +34,9 @@ using Vamp::RealTime; static int processingSampleRate = 44100; -static int processingBPO = 60; + +static int binsPerSemitoneLive = 1; +static int binsPerSemitoneNormal = 5; static int minInputSampleRate = 100; static int maxInputSampleRate = 192000; @@ -41,6 +44,7 @@ Silvet::Silvet(float inputSampleRate) : Plugin(inputSampleRate), m_instruments(InstrumentPack::listInstrumentPacks()), + m_liveInstruments(LiveAdapter::adaptAll(m_instruments)), m_resampler(0), m_flattener(0), m_cq(0), @@ -247,18 +251,18 @@ d.description = "Filtered constant-Q time-frequency distribution as used as input to the expectation-maximisation algorithm."; d.unit = ""; d.hasFixedBinCount = true; - d.binCount = m_instruments[0].templateHeight; + d.binCount = getPack(0).templateHeight; d.binNames.clear(); if (m_cq) { char name[50]; - for (int i = 0; i < m_instruments[0].templateHeight; ++i) { + for (int i = 0; i < getPack(0).templateHeight; ++i) { // We have a 600-bin (10 oct 60-bin CQ) of which the // lowest-frequency 55 bins have been dropped, for a // 545-bin template. The native CQ bins go high->low // frequency though, so these are still the first 545 bins // as reported by getBinFrequency, though in reverse order float freq = m_cq->getBinFrequency - (m_instruments[0].templateHeight - i - 1); + (getPack(0).templateHeight - i - 1); sprintf(name, "%.1f Hz", freq); d.binNames.push_back(name); } @@ -276,10 +280,10 @@ d.description = "Pitch activation distribution resulting from expectation-maximisation algorithm, prior to note extraction."; d.unit = ""; d.hasFixedBinCount = true; - d.binCount = m_instruments[0].templateNoteCount; + d.binCount = getPack(0).templateNoteCount; d.binNames.clear(); if (m_cq) { - for (int i = 0; i < m_instruments[0].templateNoteCount; ++i) { + for (int i = 0; i < getPack(0).templateNoteCount; ++i) { d.binNames.push_back(noteName(i, 0, 1)); } } @@ -406,10 +410,13 @@ minFreq *= 2; } + int bpo = 12 * + (m_mode == LiveMode ? binsPerSemitoneLive : binsPerSemitoneNormal); + CQParameters params(processingSampleRate, minFreq, processingSampleRate / 3, - processingBPO); + bpo); params.q = 0.95; // MIREX code uses 0.8, but it seems 0.9 or lower // drops the FFT size to 512 from 1024 and alters @@ -430,7 +437,7 @@ delete m_postFilter[i]; } m_postFilter.clear(); - for (int i = 0; i < m_instruments[0].templateNoteCount; ++i) { + for (int i = 0; i < getPack(0).templateNoteCount; ++i) { m_postFilter.push_back(new MedianFilter<double>(3)); } m_pianoRoll.clear(); @@ -506,7 +513,7 @@ if (filtered.empty()) return fs; - const InstrumentPack &pack = m_instruments[m_instrument]; + const InstrumentPack &pack(getPack(m_instrument)); for (int i = 0; i < (int)filtered.size(); ++i) { Feature f; @@ -633,7 +640,7 @@ // size we reduce to in a moment int latentColumns = m_cq->getLatency() / m_cq->getColumnHop(); - const InstrumentPack &pack = m_instruments[m_instrument]; + const InstrumentPack &pack(getPack(m_instrument)); for (int i = 0; i < width; ++i) { @@ -652,7 +659,7 @@ vector<double> outCol(pack.templateHeight); // In HQ mode, the CQ returns 600 bins and we ignore the - // lowest 55 of them. + // lowest 55 of them (assuming binsPerSemitone == 5). // // In draft and live mode the CQ is an octave shorter, // returning 540 bins, so we instead pad them with an @@ -662,29 +669,32 @@ // raw CQ has the high frequencies first and we need it // the other way around. + int bps = (m_mode == LiveMode ? + binsPerSemitoneLive : binsPerSemitoneNormal); + if (m_mode == HighQualityMode) { for (int j = 0; j < pack.templateHeight; ++j) { - int ix = inCol.size() - j - 55; + int ix = inCol.size() - j - (11 * bps); outCol[j] = inCol[ix]; } } else { - for (int j = 0; j < 5; ++j) { + for (int j = 0; j < bps; ++j) { outCol[j] = 0.0; } - for (int j = 5; j < pack.templateHeight; ++j) { - int ix = inCol.size() - j + 4; + for (int j = bps; j < pack.templateHeight; ++j) { + int ix = inCol.size() - j + (bps-1); outCol[j] = inCol[ix]; } } vector<double> noiseLevel1 = - MedianFilter<double>::filter(40, outCol); + MedianFilter<double>::filter(8 * bps, outCol); for (int j = 0; j < pack.templateHeight; ++j) { noiseLevel1[j] = std::min(outCol[j], noiseLevel1[j]); } vector<double> noiseLevel2 = - MedianFilter<double>::filter(40, noiseLevel1); + MedianFilter<double>::filter(8 * bps, noiseLevel1); for (int j = 0; j < pack.templateHeight; ++j) { outCol[j] = std::max(outCol[j] - noiseLevel2[j], 0.0); } @@ -703,7 +713,7 @@ const vector<int> &bestShifts, bool wantShifts) { - const InstrumentPack &pack = m_instruments[m_instrument]; + const InstrumentPack &pack(getPack(m_instrument)); vector<double> filtered;