comparison src/Silvet.cpp @ 297:d6ab1b4918bd livemode

Thinking about a "live" mode...
author Chris Cannam
date Fri, 28 Nov 2014 09:42:56 +0000
parents aa7be9d8112e
children ebe5e0942bb8
comparison
equal deleted inserted replaced
296:a3229b972463 297:d6ab1b4918bd
42 Plugin(inputSampleRate), 42 Plugin(inputSampleRate),
43 m_instruments(InstrumentPack::listInstrumentPacks()), 43 m_instruments(InstrumentPack::listInstrumentPacks()),
44 m_resampler(0), 44 m_resampler(0),
45 m_flattener(0), 45 m_flattener(0),
46 m_cq(0), 46 m_cq(0),
47 m_hqMode(true), 47 m_mode(HighQualityMode),
48 m_fineTuning(false), 48 m_fineTuning(false),
49 m_instrument(0), 49 m_instrument(0),
50 m_colsPerSec(50) 50 m_colsPerSec(50)
51 { 51 {
52 } 52 }
134 134
135 ParameterDescriptor desc; 135 ParameterDescriptor desc;
136 desc.identifier = "mode"; 136 desc.identifier = "mode";
137 desc.name = "Processing mode"; 137 desc.name = "Processing mode";
138 desc.unit = ""; 138 desc.unit = "";
139 desc.description = "Sets the tradeoff of processing speed against transcription quality. Draft mode modifies a number of internal parameters in favour of speed. Intensive mode (the default) will almost always produce better results."; 139 desc.description = "Sets the tradeoff of processing speed against transcription quality. Draft mode is tuned in favour of overall speed; Live mode is tuned in favour of lower latency; while Intensive mode (the default) will almost always produce the best results.";
140 desc.minValue = 0; 140 desc.minValue = 0;
141 desc.maxValue = 1; 141 desc.maxValue = 2;
142 desc.defaultValue = 1; 142 desc.defaultValue = 1;
143 desc.isQuantized = true; 143 desc.isQuantized = true;
144 desc.quantizeStep = 1; 144 desc.quantizeStep = 1;
145 desc.valueNames.push_back("Draft (faster)"); 145 desc.valueNames.push_back("Draft (faster)");
146 desc.valueNames.push_back("Intensive (higher quality)"); 146 desc.valueNames.push_back("Intensive (higher quality)");
147 desc.valueNames.push_back("Live (lower latency)");
147 list.push_back(desc); 148 list.push_back(desc);
148 149
149 desc.identifier = "instrument"; 150 desc.identifier = "instrument";
150 desc.name = "Instrument"; 151 desc.name = "Instrument";
151 desc.unit = ""; 152 desc.unit = "";
178 179
179 float 180 float
180 Silvet::getParameter(string identifier) const 181 Silvet::getParameter(string identifier) const
181 { 182 {
182 if (identifier == "mode") { 183 if (identifier == "mode") {
183 return m_hqMode ? 1.f : 0.f; 184 return (float)(int)m_mode;
184 } else if (identifier == "finetune") { 185 } else if (identifier == "finetune") {
185 return m_fineTuning ? 1.f : 0.f; 186 return m_fineTuning ? 1.f : 0.f;
186 } else if (identifier == "instrument") { 187 } else if (identifier == "instrument") {
187 return m_instrument; 188 return m_instrument;
188 } 189 }
191 192
192 void 193 void
193 Silvet::setParameter(string identifier, float value) 194 Silvet::setParameter(string identifier, float value)
194 { 195 {
195 if (identifier == "mode") { 196 if (identifier == "mode") {
196 m_hqMode = (value > 0.5); 197 m_mode = (ProcessingMode)(int)(value + 0.5);
197 } else if (identifier == "finetune") { 198 } else if (identifier == "finetune") {
198 m_fineTuning = (value > 0.5); 199 m_fineTuning = (value > 0.5);
199 } else if (identifier == "instrument") { 200 } else if (identifier == "instrument") {
200 m_instrument = lrintf(value); 201 m_instrument = lrintf(value);
201 } 202 }
397 m_flattener = new FlattenDynamics(m_inputSampleRate); // before resampling 398 m_flattener = new FlattenDynamics(m_inputSampleRate); // before resampling
398 m_flattener->reset(); 399 m_flattener->reset();
399 400
400 double minFreq = 27.5; 401 double minFreq = 27.5;
401 402
402 if (!m_hqMode) { 403 if (m_mode != HighQualityMode) {
403 // We don't actually return any notes from the bottom octave, 404 // We don't actually return any notes from the bottom octave,
404 // so we can just pad with zeros 405 // so we can just pad with zeros
405 minFreq *= 2; 406 minFreq *= 2;
406 } 407 }
407 408
419 params.threshold = 0.0005; 420 params.threshold = 0.0005;
420 params.window = CQParameters::Hann; 421 params.window = CQParameters::Hann;
421 422
422 m_cq = new CQSpectrogram(params, CQSpectrogram::InterpolateLinear); 423 m_cq = new CQSpectrogram(params, CQSpectrogram::InterpolateLinear);
423 424
424 m_colsPerSec = m_hqMode ? 50 : 25; 425 cerr << "cq latency = " << m_cq->getLatency() << endl;
426
427 m_colsPerSec = (m_mode == DraftMode ? 25 : 50);
425 428
426 for (int i = 0; i < (int)m_postFilter.size(); ++i) { 429 for (int i = 0; i < (int)m_postFilter.size(); ++i) {
427 delete m_postFilter[i]; 430 delete m_postFilter[i];
428 } 431 }
429 m_postFilter.clear(); 432 m_postFilter.clear();
513 fs[m_fcqOutputNo].push_back(f); 516 fs[m_fcqOutputNo].push_back(f);
514 } 517 }
515 518
516 int width = filtered.size(); 519 int width = filtered.size();
517 520
518 int iterations = m_hqMode ? 20 : 10; 521 int iterations = (m_mode == HighQualityMode ? 20 : 10);
519 522
520 Grid localPitches(width, vector<double>(pack.templateNoteCount, 0.0)); 523 Grid localPitches(width, vector<double>(pack.templateNoteCount, 0.0));
521 524
522 bool wantShifts = m_hqMode && m_fineTuning; 525 bool wantShifts = (m_mode == HighQualityMode) && m_fineTuning;
523 int shiftCount = 1; 526 int shiftCount = 1;
524 if (wantShifts) { 527 if (wantShifts) {
525 shiftCount = pack.templateMaxShift * 2 + 1; 528 shiftCount = pack.templateMaxShift * 2 + 1;
526 } 529 }
527 530
542 } 545 }
543 if (sum < 1e-5) continue; 546 if (sum < 1e-5) continue;
544 547
545 present[i] = true; 548 present[i] = true;
546 549
547 EM em(&pack, m_hqMode); 550 EM em(&pack, m_mode == HighQualityMode);
548 551
549 em.setPitchSparsity(pack.pitchSparsity); 552 em.setPitchSparsity(pack.pitchSparsity);
550 em.setSourceSparsity(pack.sourceSparsity); 553 em.setSourceSparsity(pack.sourceSparsity);
551 554
552 for (int j = 0; j < iterations; ++j) { 555 for (int j = 0; j < iterations; ++j) {
649 vector<double> outCol(pack.templateHeight); 652 vector<double> outCol(pack.templateHeight);
650 653
651 // In HQ mode, the CQ returns 600 bins and we ignore the 654 // In HQ mode, the CQ returns 600 bins and we ignore the
652 // lowest 55 of them. 655 // lowest 55 of them.
653 // 656 //
654 // In draft mode the CQ is an octave shorter, returning 657 // In draft and live mode the CQ is an octave shorter,
655 // 540 bins, so we instead pad them with an additional 5 658 // returning 540 bins, so we instead pad them with an
656 // zeros. 659 // additional 5 zeros.
657 // 660 //
658 // We also need to reverse the column as we go, since the 661 // We also need to reverse the column as we go, since the
659 // raw CQ has the high frequencies first and we need it 662 // raw CQ has the high frequencies first and we need it
660 // the other way around. 663 // the other way around.
661 664
662 if (m_hqMode) { 665 if (m_mode == HighQualityMode) {
663 for (int j = 0; j < pack.templateHeight; ++j) { 666 for (int j = 0; j < pack.templateHeight; ++j) {
664 int ix = inCol.size() - j - 55; 667 int ix = inCol.size() - j - 55;
665 outCol[j] = inCol[ix]; 668 outCol[j] = inCol[ix];
666 } 669 }
667 } else { 670 } else {