Mercurial > hg > silvet
diff src/Silvet.cpp @ 252:34e69544691b norm
Make use of input gain information to adjust output note velocities back to original levels
author | Chris Cannam |
---|---|
date | Wed, 23 Jul 2014 10:20:07 +0100 |
parents | 6b7e78cf96c9 |
children | 10d8bd634a77 |
line wrap: on
line diff
--- a/src/Silvet.cpp Tue Jul 22 18:41:09 2014 +0100 +++ b/src/Silvet.cpp Wed Jul 23 10:20:07 2014 +0100 @@ -417,7 +417,7 @@ (FlattenDynamics::GainOutputPort, &gain); m_flattener->process(m_blockSize); - m_inputGains.push_back(gain); + m_inputGains[timestamp] = gain; vector<double> data; for (int i = 0; i < m_blockSize; ++i) { @@ -754,13 +754,7 @@ int partShift = 0; int partVelocity = 0; - Feature f; - f.hasTimestamp = true; - f.hasDuration = true; - - double columnDuration = 1.0 / m_colsPerSec; - int postFilterLatency = int(m_postFilter[0]->getSize() / 2); - int partThreshold = floor(0.05 / columnDuration); + int partThreshold = floor(0.05 * m_colsPerSec); for (int i = start; i != end; ++i) { @@ -781,49 +775,87 @@ // cerr << "i = " << i << ", partStart = " << partStart << ", shift = " << shift << ", partShift = " << partShift << endl; // pitch has changed, emit an intermediate note - f.timestamp = RealTime::fromSeconds - (columnDuration * (partStart - postFilterLatency) + 0.02); - f.duration = RealTime::fromSeconds - (columnDuration * (i - partStart)); - f.values.clear(); - f.values.push_back - (noteFrequency(note, partShift, shiftCount)); - f.values.push_back(partVelocity); - f.label = noteName(note, partShift, shiftCount); - noteFeatures.push_back(f); + noteFeatures.push_back(makeNoteFeature(partStart, + i, + note, + partShift, + shiftCount, + partVelocity)); partStart = i; partShift = shift; partVelocity = 0; } } - //!!! todo: do something with input gain. Presumably we need - //!!! to index it by something close to, but not actually, i - //!!! (depending on cq latency) -/* - cerr << "i = " << i << ", gain length = " << m_inputGains.size() - << ", cq latency = " << m_cq->getLatency() << " (as columns = " - << m_cq->getLatency() / m_cq->getColumnHop() << ", as input blocks = " - << m_cq->getLatency() / m_blockSize << ")" << endl; -*/ int v = round(strength * 2); - if (v > 127) v = 127; - if (v > partVelocity) { partVelocity = v; } } if (end >= partStart + partThreshold) { - f.timestamp = RealTime::fromSeconds - (columnDuration * (partStart - postFilterLatency) + 0.02); - f.duration = RealTime::fromSeconds - (columnDuration * (end - partStart)); - f.values.clear(); - f.values.push_back - (noteFrequency(note, partShift, shiftCount)); - f.values.push_back(partVelocity); - f.label = noteName(note, partShift, shiftCount); - noteFeatures.push_back(f); + noteFeatures.push_back(makeNoteFeature(partStart, + end, + note, + partShift, + shiftCount, + partVelocity)); } } + +Silvet::Feature +Silvet::makeNoteFeature(int start, + int end, + int note, + int shift, + int shiftCount, + int velocity) +{ + double columnDuration = 1.0 / m_colsPerSec; + int postFilterLatency = int(m_postFilter[0]->getSize() / 2); + + Feature f; + + f.hasTimestamp = true; + f.timestamp = RealTime::fromSeconds + (columnDuration * (start - postFilterLatency) + 0.02); + + f.hasDuration = true; + f.duration = RealTime::fromSeconds + (columnDuration * (end - start)); + + f.values.clear(); + + f.values.push_back + (noteFrequency(note, shift, shiftCount)); + + float inputGain = getInputGainAt(f.timestamp); +// cerr << "adjusting velocity from " << velocity << " to " << round(velocity/inputGain) << endl; + velocity = round(velocity / inputGain); + if (velocity > 127) velocity = 127; + if (velocity < 1) velocity = 1; + f.values.push_back(velocity); + + f.label = noteName(note, shift, shiftCount); + + return f; +} + +float +Silvet::getInputGainAt(RealTime t) +{ + map<RealTime, float>::const_iterator i = m_inputGains.lower_bound(t); + + if (i == m_inputGains.end()) { + if (i != m_inputGains.begin()) { + --i; + } else { + return 1.f; // no data + } + } + +// cerr << "gain at time " << t << " = " << i->second << endl; + + return i->second; +} +