* Sort out resynthesis gain; add crispness parameter to pitch shifter plugin

This commit is contained in:
Chris Cannam
2007-11-21 19:57:49 +00:00
parent 902e52f8f1
commit d2fe49c20c
7 changed files with 82 additions and 23 deletions

View File

@@ -49,6 +49,8 @@ public:
virtual int calculateSingle(double ratio, size_t inputDurationSoFar,
float curveValue);
void setUseHardPeaks(bool use) { m_useHardPeaks = use; }
void reset();
void setDebugLevel(int level) { m_debugLevel = level; }

View File

@@ -403,7 +403,7 @@ RubberBandStretcher::Impl::calculateSizes()
//necessary. clearly something wrong in our calculations... or do
//we just need to ensure client calls setMaxProcessSize?
if (!m_realtime && !m_threaded) {
m_outbufSize = m_outbufSize * 2;
m_outbufSize = m_outbufSize * 5;
}
}
@@ -616,10 +616,17 @@ RubberBandStretcher::Impl::getLatency() const
void
RubberBandStretcher::Impl::setTransientsOption(Options options)
{
if (!m_realtime) {
cerr << "RubberBandStretcher::Impl::setTransientsOption: Not permissible in non-realtime mode" << endl;
return;
}
m_options &= ~(OptionTransientsMixed |
OptionTransientsSmooth |
OptionTransientsCrisp);
m_options |= options;
m_stretchCalculator->setUseHardPeaks
(!(m_options & OptionTransientsSmooth));
}
void

View File

@@ -661,7 +661,8 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel)
//!!! not much cop, this bit
float area = m_window->getArea();
float area = m_window->getArea() * 1.5;
// float area = 1.f;
for (size_t i = 0; i < m_windowSize; ++i) {
float val = m_window->getValue(i);

View File

@@ -19,6 +19,8 @@
#include <iostream>
#include <map>
namespace RubberBand {
enum WindowType {
RectangularWindow,
BartlettWindow,
@@ -158,4 +160,6 @@ void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
}
}
}
#endif

View File

@@ -19,6 +19,8 @@
#include <iostream>
#include <cmath>
using namespace RubberBand;
const char *const
RubberBandPitchShifter::portNamesMono[PortCountMono] =
{
@@ -26,6 +28,7 @@ RubberBandPitchShifter::portNamesMono[PortCountMono] =
"Cents",
"Semitones",
"Octaves",
"Crispness",
"Input",
"Output"
};
@@ -37,6 +40,7 @@ RubberBandPitchShifter::portNamesStereo[PortCountStereo] =
"Cents",
"Semitones",
"Octaves",
"Crispness",
"Input L",
"Output L",
"Input R",
@@ -50,6 +54,7 @@ RubberBandPitchShifter::portsMono[PortCountMono] =
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO
};
@@ -61,6 +66,7 @@ RubberBandPitchShifter::portsStereo[PortCountStereo] =
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
@@ -85,6 +91,11 @@ RubberBandPitchShifter::hintsMono[PortCountMono] =
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
-4.0, 4.0 },
{ LADSPA_HINT_DEFAULT_MAXIMUM |
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
0.0, 3.0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
@@ -107,6 +118,11 @@ RubberBandPitchShifter::hintsStereo[PortCountStereo] =
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
-4.0, 4.0 },
{ LADSPA_HINT_DEFAULT_MAXIMUM |
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
0.0, 3.0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
@@ -167,7 +183,6 @@ RubberBandPitchShifter::ladspaDescriptorStereo =
const LADSPA_Descriptor *
RubberBandPitchShifter::getDescriptor(unsigned long index)
{
// std::cerr << "RubberBandPitchShifter::getDescriptor(" << index << ")" << std::endl;
if (index == 0) return &ladspaDescriptorMono;
if (index == 1) return &ladspaDescriptorStereo;
else return 0;
@@ -178,27 +193,22 @@ RubberBandPitchShifter::RubberBandPitchShifter(int sampleRate, size_t channels)
m_cents(0),
m_semitones(0),
m_octaves(0),
m_crispness(0),
m_ratio(1.0),
m_prevRatio(1.0),
m_currentCrispness(-1),
m_extraLatency(8192), //!!! this should be at least the maximum possible displacement from linear at input rates, divided by the pitch scale factor. It could be very large
m_stretcher(new RubberBand::RubberBandStretcher
m_stretcher(new RubberBandStretcher
(sampleRate, channels,
RubberBand::RubberBandStretcher::OptionProcessRealTime)),// |
// RubberBand::RubberBandStretcher::OptionStretchPrecise |
// RubberBand::RubberBandStretcher::OptionTransientsSmooth |
// RubberBand::RubberBandStretcher::OptionTransientsCrisp |
// RubberBand::RubberBandStretcher::OptionPhasePeakLocked |
// RubberBand::RubberBandStretcher::OptionThreadingNone)),
RubberBandStretcher::OptionProcessRealTime)),
m_sampleRate(sampleRate),
m_channels(channels)
{
// m_stretcher->setMaxProcessBlockSize(4096);
for (size_t c = 0; c < m_channels; ++c) {
m_input[c] = 0;
m_output[c] = 0;
//!!! size must be at least max process size plus m_extraLatency:
m_outputBuffer[c] = new RubberBand::RingBuffer<float>(8092); //!!!
m_outputBuffer[c] = new RingBuffer<float>(8092); //!!!
m_outputBuffer[c]->zero(m_extraLatency);
//!!! size must be at least max process size:
m_scratch[c] = new float[16384];//!!!
@@ -236,6 +246,7 @@ RubberBandPitchShifter::connectPort(LADSPA_Handle handle,
&shifter->m_cents,
&shifter->m_semitones,
&shifter->m_octaves,
&shifter->m_crispness,
&shifter->m_input[0],
&shifter->m_output[0],
&shifter->m_input[1],
@@ -249,8 +260,6 @@ void
RubberBandPitchShifter::activate(LADSPA_Handle handle)
{
RubberBandPitchShifter *shifter = (RubberBandPitchShifter *)handle;
//!!! QMutexLocker locker(&shifter->m_mutex);
shifter->updateRatio();
shifter->m_prevRatio = shifter->m_ratio;
shifter->m_stretcher->reset();
@@ -273,6 +282,38 @@ RubberBandPitchShifter::updateRatio()
m_ratio = pow(2.0, oct);
}
void
RubberBandPitchShifter::updateCrispness()
{
if (!m_crispness) return;
int c = lrintf(*m_crispness);
if (c == m_currentCrispness) return;
if (c < 0 || c > 3) return;
RubberBandStretcher *s = m_stretcher;
switch (c) {
case 0:
s->setPhaseOption(RubberBandStretcher::OptionPhaseIndependent);
s->setTransientsOption(RubberBandStretcher::OptionTransientsSmooth);
break;
case 1:
s->setPhaseOption(RubberBandStretcher::OptionPhaseAdaptive);
s->setTransientsOption(RubberBandStretcher::OptionTransientsSmooth);
break;
case 2:
s->setPhaseOption(RubberBandStretcher::OptionPhaseAdaptive);
s->setTransientsOption(RubberBandStretcher::OptionTransientsMixed);
break;
case 3:
s->setPhaseOption(RubberBandStretcher::OptionPhaseAdaptive);
s->setTransientsOption(RubberBandStretcher::OptionTransientsCrisp);
break;
}
m_currentCrispness = c;
}
void
RubberBandPitchShifter::runImpl(unsigned long insamples)
{
@@ -289,6 +330,8 @@ RubberBandPitchShifter::runImpl(unsigned long insamples)
// std::cerr << "latency = " << *m_latency << std::endl;
}
updateCrispness();
int samples = insamples;
int processed = 0;
size_t outTotal = 0;

View File

@@ -37,12 +37,13 @@ protected:
OctavesPort = 1,
SemitonesPort = 2,
CentsPort = 3,
InputPort1 = 4,
OutputPort1 = 5,
PortCountMono = 6,
InputPort2 = 6,
OutputPort2 = 7,
PortCountStereo = 8
CrispnessPort = 4,
InputPort1 = 5,
OutputPort1 = 6,
PortCountMono = OutputPort1 + 1,
InputPort2 = 7,
OutputPort2 = 8,
PortCountStereo = OutputPort2 + 1
};
static const char *const portNamesMono[PortCountMono];
@@ -67,6 +68,7 @@ protected:
void runImpl(unsigned long);
void updateRatio();
void updateCrispness();
float *m_input[2];
float *m_output[2];
@@ -74,8 +76,10 @@ protected:
float *m_cents;
float *m_semitones;
float *m_octaves;
float *m_crispness;
double m_ratio;
double m_prevRatio;
int m_currentCrispness;
size_t m_extraLatency;

View File

@@ -341,7 +341,6 @@ int main(int argc, char **argv)
float value = obf[c][i];
if (fabsf(value) > outpeak) outpeak = fabsf(value);
outsum += value * value;
value *= 0.75;
if (value > 1.f) value = 1.f;
if (value < -1.f) value = -1.f;
fobf[i * channels + c] = value;
@@ -401,7 +400,6 @@ int main(int argc, char **argv)
float value = obf[c][i];
if (fabsf(value) > outpeak) outpeak = fabsf(value);
outsum += value * value;
value *= 0.75;//!!!
if (value > 1.f) value = 1.f;
if (value < -1.f) value = -1.f;
fobf[i * channels + c] = value;