From d2fe49c20c9e679dce96b27e089855af0381c310 Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Wed, 21 Nov 2007 19:57:49 +0000 Subject: [PATCH] * Sort out resynthesis gain; add crispness parameter to pitch shifter plugin --- src/StretchCalculator.h | 2 + src/StretcherImpl.cpp | 9 +++- src/StretcherProcess.cpp | 3 +- src/Window.h | 4 ++ src/ladspa/RubberBandPitchShifter.cpp | 69 ++++++++++++++++++++++----- src/ladspa/RubberBandPitchShifter.h | 16 ++++--- src/main.cpp | 2 - 7 files changed, 82 insertions(+), 23 deletions(-) diff --git a/src/StretchCalculator.h b/src/StretchCalculator.h index 5060e5f..f6c3544 100644 --- a/src/StretchCalculator.h +++ b/src/StretchCalculator.h @@ -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; } diff --git a/src/StretcherImpl.cpp b/src/StretcherImpl.cpp index d88b46b..c7a4074 100644 --- a/src/StretcherImpl.cpp +++ b/src/StretcherImpl.cpp @@ -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 diff --git a/src/StretcherProcess.cpp b/src/StretcherProcess.cpp index c5b6c02..75b4dfa 100644 --- a/src/StretcherProcess.cpp +++ b/src/StretcherProcess.cpp @@ -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); diff --git a/src/Window.h b/src/Window.h index a89feb9..305daa7 100644 --- a/src/Window.h +++ b/src/Window.h @@ -19,6 +19,8 @@ #include #include +namespace RubberBand { + enum WindowType { RectangularWindow, BartlettWindow, @@ -158,4 +160,6 @@ void Window::cosinewin(T *mult, T a0, T a1, T a2, T a3) } } +} + #endif diff --git a/src/ladspa/RubberBandPitchShifter.cpp b/src/ladspa/RubberBandPitchShifter.cpp index 8ac545e..8ab6e65 100644 --- a/src/ladspa/RubberBandPitchShifter.cpp +++ b/src/ladspa/RubberBandPitchShifter.cpp @@ -19,6 +19,8 @@ #include #include +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(8092); //!!! + m_outputBuffer[c] = new RingBuffer(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; diff --git a/src/ladspa/RubberBandPitchShifter.h b/src/ladspa/RubberBandPitchShifter.h index 5c5ccb8..fd7474c 100644 --- a/src/ladspa/RubberBandPitchShifter.h +++ b/src/ladspa/RubberBandPitchShifter.h @@ -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; diff --git a/src/main.cpp b/src/main.cpp index cb712f1..442854d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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;