Mercurial > hg > silvet
changeset 327:df9a8e16bae6 livemode-octave-higher
Experiment with dropping the bottom octave off each template (since most of the information is in higher harmonics anyway!) -- this is about 15% faster again and has half the latency, but per
author | Chris Cannam |
---|---|
date | Tue, 19 May 2015 09:29:00 +0100 |
parents | caaac814c22a |
children | 8545b883775e |
files | src/Instruments.h src/LiveInstruments.cpp src/Silvet.cpp |
diffstat | 3 files changed, 44 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Instruments.h Mon May 18 16:33:36 2015 +0100 +++ b/src/Instruments.h Tue May 19 09:29:00 2015 +0100 @@ -35,7 +35,7 @@ int templateNoteCount; int templateHeight; int templateMaxShift; - int templateSize; + int templateSize; // height plus space for shift at either end int lowestNote; int highestNote;
--- a/src/LiveInstruments.cpp Mon May 18 16:33:36 2015 +0100 +++ b/src/LiveInstruments.cpp Tue May 19 09:29:00 2015 +0100 @@ -37,25 +37,29 @@ InstrumentPack::Templates t; bool first = true; + + // The live instrument template is one octave shorter than the + // original, as well as having only 12 bpo instead of 60 + int height = SILVET_TEMPLATE_HEIGHT/5 - 12; for (const auto &origt: original.templates) { - t.lowestNote = origt.lowestNote; + t.lowestNote = origt.lowestNote + 12; t.highestNote = origt.highestNote; t.data.resize(origt.data.size()); for (int j = 0; j < int(origt.data.size()); ++j) { - t.data[j].resize(SILVET_TEMPLATE_HEIGHT/5); + t.data[j].resize(height); - for (int k = 0; k < SILVET_TEMPLATE_HEIGHT/5; ++k) { + for (int k = 0; k < height; ++k) { if (!merge || first) { t.data[j][k] = 0.f; } - for (int m = 0; m < 5; ++m) { - t.data[j][k] += origt.data[j][k * 5 + m + 2]; + for (int m = 2; m < 3; ++m) { + t.data[j][k] += origt.data[j][60 + k * 5 + m + 2]; } } } @@ -73,6 +77,7 @@ } // re-normalise + for (auto &t: templates) { for (auto &d: t.data) { float sum = 0.f; @@ -80,20 +85,20 @@ for (auto &v: d) v /= sum; } } - + InstrumentPack live(original.lowestNote, original.highestNote, original.name, templates); - live.templateHeight = SILVET_TEMPLATE_HEIGHT/5; + live.templateHeight = height; live.templateMaxShift = 0; - live.templateSize = live.templateHeight; + live.templateSize = height; live.maxPolyphony = original.maxPolyphony; live.pitchSparsity = original.pitchSparsity; live.sourceSparsity = original.sourceSparsity; - live.levelThreshold = original.levelThreshold / 15; + live.levelThreshold = original.levelThreshold / 20; return live; }
--- a/src/Silvet.cpp Mon May 18 16:33:36 2015 +0100 +++ b/src/Silvet.cpp Tue May 19 09:29:00 2015 +0100 @@ -500,8 +500,14 @@ if (m_mode != HighQualityMode) { // We don't actually return any notes from the bottom octave, - // so we can just pad with zeros - minFreq *= 2; + // so we can just pad with zeros. In live mode the template is + // an octave shorter as well. Each octave the min frequency is + // raised by halves the processing latency. + if (m_mode == LiveMode) { + minFreq *= 4; + } else { + minFreq *= 2; + } } int bpo = 12 * @@ -774,7 +780,7 @@ double columnThreshold = 1e-5; if (m_mode == LiveMode) { - columnThreshold /= 15; + columnThreshold /= 20; } vector<double> pitches(pack.templateNoteCount, 0.0); @@ -865,12 +871,22 @@ vector<double> inCol = in[i]; vector<double> outCol(pack.templateHeight); - // In HQ mode, the CQ returns 600 bins and we ignore the - // lowest 55 of them (assuming binsPerSemitone == 5). - // - // In draft and live mode the CQ is an octave shorter, - // returning 540 bins or equivalent, so we instead pad - // them with an additional 5 or equivalent zeros. + // In HQ mode, the CQ returns 600 bins (10 octaves at 5 + // bins per semitone) and we ignore the lowest 55 of them, + // giving us 545 bins total, which matches the height of + // each of our instrument templates. + // + // In draft mode the CQ is an octave shorter, returning + // 540 bins, so we instead pad with an additional 5 zeros + // at the lowest frequencies to get the same 545 bins. + // + // In live mode the CQ is two octaves shorter and only has + // 1 bin per semitone, and the template is also an octave + // shorter. So we get 96 bins (= 8 * 12) and want 97 (= + // (545 / 5) - 12), meaning we have to pad with one extra + // bin at the lowest frequency position. Essentially this + // is the same as draft mode (pad with bins-per-semitone + // bins), just that the result is a shorter vector. // // We also need to reverse the column as we go, since the // raw CQ has the high frequencies first and we need it @@ -885,11 +901,12 @@ outCol[j] = inCol[ix]; } } else { - for (int j = 0; j < bps; ++j) { + int pad = bps; + for (int j = 0; j < pad; ++j) { outCol[j] = 0.0; } - for (int j = bps; j < pack.templateHeight; ++j) { - int ix = inCol.size() - j + (bps-1); + for (int j = pad; j < pack.templateHeight; ++j) { + int ix = inCol.size() - j + (pad-1); outCol[j] = inCol[ix]; } }