From 057481ea41790effa6880a767e1036d16b18fb2d Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Tue, 8 Jul 2008 15:00:22 +0000 Subject: [PATCH] * Work around a patent (also producing better results, in many cases) * Add aligned allocation functions in sysutils --- rubberband/RubberBandStretcher.h | 25 +-- rubberband/rubberband-c.h | 3 +- src/Resampler.cpp | 11 +- src/StretcherChannelData.cpp | 108 +++++------- src/StretcherChannelData.h | 1 + src/StretcherImpl.cpp | 2 +- src/StretcherProcess.cpp | 229 ++++++++++---------------- src/ladspa/RubberBandPitchShifter.cpp | 6 +- src/main.cpp | 5 - src/sysutils.cpp | 45 +++++ src/sysutils.h | 8 + src/vamp/RubberBandVampPlugin.cpp | 2 +- 12 files changed, 195 insertions(+), 250 deletions(-) diff --git a/rubberband/RubberBandStretcher.h b/rubberband/RubberBandStretcher.h index 7f36930..151e564 100644 --- a/rubberband/RubberBandStretcher.h +++ b/rubberband/RubberBandStretcher.h @@ -110,21 +110,15 @@ public: * during non-transient segments. These options may be changed at * any time. * - * \li \c OptionPhaseAdaptive - Lock the adjustments of phase - * for frequencies close to peak frequencies to those of the - * peak, but reduce the degree of locking as the stretch ratio - * gets longer. This, the default setting, should give a good - * balance between clarity and smoothness in most situations. + * \li \c OptionPhaseLaminar - Adjust phases when stretching in + * such a way as to try to retain the continuity of phase + * relationships between adjacent frequency bins whose phases + * are behaving in similar ways. This, the default setting, + * should give good results in most situations. * - * \li \c OptionPhasePeakLocked - Lock the adjustments of phase - * for frequencies close to peak frequencies to those of the - * peak. This should give a clear result in situations with - * relatively low stretch ratios, but a relatively metallic - * sound at longer stretches. - * - * \li \c OptionPhaseIndependent - Do not lock phase adjustments - * to peak frequencies. This usually results in a softer, - * phasier sound. + * \li \c OptionPhaseIndependent - Adjust the phase in each + * frequency bin independently from its neighbours. This + * usually results in a slightly softer, phasier sound. * * 5. Flags prefixed \c OptionThreading control the threading * model of the stretcher. These options may not be changed after @@ -207,8 +201,7 @@ public: OptionTransientsMixed = 0x00000100, OptionTransientsSmooth = 0x00000200, - OptionPhaseAdaptive = 0x00000000, - OptionPhasePeakLocked = 0x00001000, + OptionPhaseLaminar = 0x00000000, OptionPhaseIndependent = 0x00002000, OptionThreadingAuto = 0x00000000, diff --git a/rubberband/rubberband-c.h b/rubberband/rubberband-c.h index 2dfa787..78fd129 100644 --- a/rubberband/rubberband-c.h +++ b/rubberband/rubberband-c.h @@ -48,8 +48,7 @@ enum RubberBandOption { RubberBandOptionTransientsMixed = 0x00000100, RubberBandOptionTransientsSmooth = 0x00000200, - RubberBandOptionPhaseAdaptive = 0x00000000, - RubberBandOptionPhasePeakLocked = 0x00001000, + RubberBandOptionPhaseLaminar = 0x00000000, RubberBandOptionPhaseIndependent = 0x00002000, RubberBandOptionThreadingAuto = 0x00000000, diff --git a/src/Resampler.cpp b/src/Resampler.cpp index 5bcff08..539dcb8 100644 --- a/src/Resampler.cpp +++ b/src/Resampler.cpp @@ -101,11 +101,10 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize, } if (maxBufferSize > 0 && m_channels > 1) { - //!!! alignment? m_iinsize = maxBufferSize * m_channels; m_ioutsize = maxBufferSize * m_channels * 2; - m_iin = (float *)malloc(m_iinsize * sizeof(float)); - m_iout = (float *)malloc(m_ioutsize * sizeof(float)); + m_iin = allocFloat(m_iinsize); + m_iout = allocFloat(m_ioutsize); } reset(); @@ -138,12 +137,10 @@ D_SRC::resample(const float *const R__ *const R__ in, data.data_out = *out; } else { if (incount * m_channels > m_iinsize) { - m_iinsize = incount * m_channels; - m_iin = (float *)realloc(m_iin, m_iinsize * sizeof(float)); + m_iin = allocFloat(m_iin, m_iinsize); } if (outcount * m_channels > m_ioutsize) { - m_ioutsize = outcount * m_channels; - m_iout = (float *)realloc(m_iout, m_ioutsize * sizeof(float)); + m_iout = allocFloat(m_iout, m_ioutsize); } for (int i = 0; i < incount; ++i) { for (int c = 0; c < m_channels; ++c) { diff --git a/src/StretcherChannelData.cpp b/src/StretcherChannelData.cpp index 2a8fe40..8378975 100644 --- a/src/StretcherChannelData.cpp +++ b/src/StretcherChannelData.cpp @@ -19,7 +19,7 @@ namespace RubberBand { - + RubberBandStretcher::Impl::ChannelData::ChannelData(size_t windowSize, int overSample, size_t outbufSize) : @@ -64,18 +64,19 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set &window inbuf = new RingBuffer(maxSize); outbuf = new RingBuffer(outbufSize); - mag = new double[realSize]; - phase = new double[realSize]; - prevPhase = new double[realSize]; - unwrappedPhase = new double[realSize]; + mag = allocDouble(realSize); + phase = allocDouble(realSize); + prevPhase = allocDouble(realSize); + prevError = allocDouble(realSize); + unwrappedPhase = allocDouble(realSize); + envelope = allocDouble(realSize); + freqPeak = new size_t[realSize]; - envelope = new double[realSize]; - fltbuf = new float[maxSize]; - - accumulator = new float[maxSize]; - windowAccumulator = new float[maxSize]; + fltbuf = allocFloat(maxSize); + accumulator = allocFloat(maxSize); + windowAccumulator = allocFloat(maxSize); for (std::set::const_iterator i = windowSizes.begin(); i != windowSizes.end(); ++i) { @@ -97,23 +98,12 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set &window reset(); for (size_t i = 0; i < realSize; ++i) { - mag[i] = 0.0; - phase[i] = 0.0; - prevPhase[i] = 0.0; - unwrappedPhase[i] = 0.0; freqPeak[i] = 0; - envelope[i] = 0.0; } for (size_t i = 0; i < initialWindowSize * oversample; ++i) { dblbuf[i] = 0.0; } - - for (size_t i = 0; i < maxSize; ++i) { - accumulator[i] = 0.f; - windowAccumulator[i] = 0.f; - fltbuf[i] = 0.f; - } } void @@ -151,6 +141,7 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize) mag[i] = 0.0; phase[i] = 0.0; prevPhase[i] = 0.0; + prevError[i] = 0.0; unwrappedPhase[i] = 0.0; freqPeak[i] = 0; } @@ -171,56 +162,44 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize) // We don't want to preserve data in these arrays - delete[] mag; - delete[] phase; - delete[] prevPhase; - delete[] unwrappedPhase; + mag = allocDouble(mag, realSize); + phase = allocDouble(phase, realSize); + prevPhase = allocDouble(prevPhase, realSize); + prevError = allocDouble(prevError, realSize); + unwrappedPhase = allocDouble(unwrappedPhase, realSize); + envelope = allocDouble(envelope, realSize); + delete[] freqPeak; - delete[] envelope; - - mag = new double[realSize]; - phase = new double[realSize]; - prevPhase = new double[realSize]; - unwrappedPhase = new double[realSize]; freqPeak = new size_t[realSize]; - envelope = new double[realSize]; - - delete[] fltbuf; - fltbuf = new float[windowSize]; + fltbuf = allocFloat(fltbuf, windowSize); // But we do want to preserve data in these - float *newAcc = new float[windowSize]; + float *newAcc = allocFloat(windowSize); + for (size_t i = 0; i < oldSize; ++i) newAcc[i] = accumulator[i]; - delete[] accumulator; + + freeFloat(accumulator); accumulator = newAcc; - newAcc = new float[windowSize]; + newAcc = allocFloat(windowSize); + for (size_t i = 0; i < oldSize; ++i) newAcc[i] = windowAccumulator[i]; - delete[] windowAccumulator; + + freeFloat(windowAccumulator); windowAccumulator = newAcc; //!!! and resampler? for (size_t i = 0; i < realSize; ++i) { - mag[i] = 0.0; - phase[i] = 0.0; - prevPhase[i] = 0.0; - unwrappedPhase[i] = 0.0; freqPeak[i] = 0; - envelope[i] = 0.0; } for (size_t i = 0; i < windowSize; ++i) { fltbuf[i] = 0.f; } - for (size_t i = oldSize; i < windowSize; ++i) { - accumulator[i] = 0.f; - windowAccumulator[i] = 0.f; - } - if (ffts.find(windowSize) == ffts.end()) { ffts[windowSize] = new FFT(windowSize * oversample); ffts[windowSize]->initDouble(); @@ -256,15 +235,7 @@ RubberBandStretcher::Impl::ChannelData::setOutbufSize(size_t outbufSize) void RubberBandStretcher::Impl::ChannelData::setResampleBufSize(size_t sz) { - if (!resamplebuf) { - resamplebuf = new float[sz]; - resamplebufSize = sz; - return; - } - - delete[] resamplebuf; - resamplebuf = new float[sz]; - for (size_t i = 0; i < sz; ++i) resamplebuf[i] = 0.f; + resamplebuf = allocFloat(resamplebuf, sz); resamplebufSize = sz; } @@ -272,22 +243,21 @@ RubberBandStretcher::Impl::ChannelData::~ChannelData() { delete resampler; - if (resamplebuf) { - delete[] resamplebuf; - } + freeFloat(resamplebuf); delete inbuf; delete outbuf; - delete[] mag; - delete[] phase; - delete[] prevPhase; - delete[] unwrappedPhase; + freeDouble(mag); + freeDouble(phase); + freeDouble(prevPhase); + freeDouble(prevError); + freeDouble(unwrappedPhase); + freeDouble(envelope); delete[] freqPeak; - delete[] accumulator; - delete[] windowAccumulator; - delete[] fltbuf; - delete[] envelope; + freeFloat(accumulator); + freeFloat(windowAccumulator); + freeFloat(fltbuf); for (std::map::iterator i = ffts.begin(); i != ffts.end(); ++i) { diff --git a/src/StretcherChannelData.h b/src/StretcherChannelData.h index 5020568..b56a6e0 100644 --- a/src/StretcherChannelData.h +++ b/src/StretcherChannelData.h @@ -91,6 +91,7 @@ public: double *phase; double *prevPhase; + double *prevError; double *unwrappedPhase; diff --git a/src/StretcherImpl.cpp b/src/StretcherImpl.cpp index da359f2..126b001 100644 --- a/src/StretcherImpl.cpp +++ b/src/StretcherImpl.cpp @@ -713,7 +713,7 @@ RubberBandStretcher::Impl::setTransientsOption(Options options) void RubberBandStretcher::Impl::setPhaseOption(Options options) { - int mask = (OptionPhaseAdaptive | OptionPhasePeakLocked | OptionPhaseIndependent); + int mask = (OptionPhaseLaminar | OptionPhaseIndependent); m_options &= ~mask; options &= mask; m_options |= options; diff --git a/src/StretcherProcess.cpp b/src/StretcherProcess.cpp index 7f14005..70d540f 100644 --- a/src/StretcherProcess.cpp +++ b/src/StretcherProcess.cpp @@ -333,7 +333,7 @@ RubberBandStretcher::Impl::processChunkForChannel(size_t c, // We need to peek m_windowSize samples for processing, and // then skip m_increment to advance the read pointer. - + modifyChunk(c, phaseIncrement, phaseReset); synthesiseChunk(c); // reads from cd.mag, cd.phase @@ -643,7 +643,8 @@ static inline double mod(double x, double y) { return x - (y * floor(x / y)); } static inline double princarg(double a) { return mod(a + M_PI, -2.0 * M_PI) + M_PI; } void -RubberBandStretcher::Impl::modifyChunk(size_t channel, size_t outputIncrement, +RubberBandStretcher::Impl::modifyChunk(size_t channel, + size_t outputIncrement, bool phaseReset) { Profiler profiler("RubberBandStretcher::Impl::modifyChunk"); @@ -654,184 +655,120 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel, size_t outputIncrement, cerr << "phase reset: leaving phases unmodified" << endl; } - int pfp = 0; - double rate = m_sampleRate; - - int sz = m_windowSize; - - int count = (sz * cd.oversample) / 2; + const double rate = m_sampleRate; + const int sz = m_windowSize; + const int count = (sz * cd.oversample) / 2; bool unchanged = cd.unchanged && (outputIncrement == m_increment); bool fullReset = phaseReset; + bool laminar = !(m_options & OptionPhaseIndependent); + bool bandlimited = (m_options & OptionTransientsMixed); + int bandlow = lrint((150 * sz * cd.oversample) / rate); + int bandhigh = lrint((1000 * sz * cd.oversample) / rate); - if (!(m_options & OptionPhaseIndependent)) { + float freq0 = m_freq0; + float freq1 = m_freq1; + float freq2 = m_freq2; - cd.freqPeak[0] = 0; - - float freq0 = m_freq0; - float freq1 = m_freq1; - float freq2 = m_freq2; - - // As the stretch ratio increases, so the frequency thresholds - // for phase lamination should increase. Beyond a ratio of - // about 1.5, the threshold should be about 1200Hz; beyond a - // ratio of 2, we probably want no lamination to happen at all - // by default. This calculation aims for more or less that. - // We only do this if the phase option is OptionPhaseAdaptive - // (the default), i.e. not Independent or PeakLocked. - - if (!(m_options & OptionPhasePeakLocked)) { - float r = getEffectiveRatio(); - if (r > 1) { - float rf0 = 600 + (600 * ((r-1)*(r-1)*(r-1)*2)); - float f1ratio = freq1 / freq0; - float f2ratio = freq2 / freq0; - freq0 = std::max(freq0, rf0); - freq1 = freq0 * f1ratio; - freq2 = freq0 * f2ratio; - } + if (laminar) { + float r = getEffectiveRatio(); + if (r > 1) { + float rf0 = 600 + (600 * ((r-1)*(r-1)*(r-1)*2)); + float f1ratio = freq1 / freq0; + float f2ratio = freq2 / freq0; + freq0 = std::max(freq0, rf0); + freq1 = freq0 * f1ratio; + freq2 = freq0 * f2ratio; } - - int limit0 = lrint((freq0 * sz * cd.oversample) / rate); - int limit1 = lrint((freq1 * sz * cd.oversample) / rate); - int limit2 = lrint((freq2 * sz * cd.oversample) / rate); - - int range = 0; - - if (limit1 < limit0) limit1 = limit0; - if (limit2 < limit1) limit2 = limit1; - -// cerr << "limit0 = " << limit0 << " limit1 = " << limit1 << " limit2 = " << limit2 << endl; - - int peakCount = 0; - - for (int i = 0; i <= count; ++i) { - - double mag = cd.mag[i]; - bool isPeak = true; - - for (int j = 1; j <= range; ++j) { - - if (mag < cd.mag[i-j]) { - isPeak = false; - break; - } - - if (mag < cd.mag[i+j]) { - isPeak = false; - break; - } - } - - if (isPeak) { - - // i is a peak bin. - - // The previous peak bin was at pfp; make freqPeak entries - // from pfp to half-way between pfp and i point at pfp, and - // those from the half-way mark to i point at i. - - int halfway = (pfp + i) / 2; - if (halfway == pfp) halfway = pfp + 1; - - for (int j = pfp + 1; j < halfway; ++j) { - cd.freqPeak[j] = pfp; - } - for (int j = halfway; j <= i; ++j) { - cd.freqPeak[j] = i; - } - - pfp = i; - - ++peakCount; - } - - if (i == limit0) range = 1; - if (i == limit1) range = 2; - if (i >= limit2) { - range = 3; - if (i + range + 1 > count) range = count - i - 1; - } - } - -// cerr << "peakCount = " << peakCount << endl; - - cd.freqPeak[count-1] = count-1; - cd.freqPeak[count] = count; } - Profiler profiler2("RubberBandStretcher::Impl::modifyChunk part 2"); + int limit0 = lrint((freq0 * sz * cd.oversample) / rate); + int limit1 = lrint((freq1 * sz * cd.oversample) / rate); + int limit2 = lrint((freq2 * sz * cd.oversample) / rate); - double peakInPhase = 0.0; - double peakOutPhase = 0.0; - int p = -1, pp = -1; + if (limit1 < limit0) limit1 = limit0; + if (limit2 < limit1) limit2 = limit1; + + double prevInstability = 0.0; + double prevDirection = 0.0; + double distance = 0.0; + const double maxdist = 8.0; - for (int i = 0; i <= count; ++i) { - - if (m_options & OptionPhaseIndependent) { - p = i; - pp = i-1; - } else { - p = cd.freqPeak[i]; - if (i > 0) pp = cd.freqPeak[i-1]; - } + const int lookback = -1; + + for (int i = 0; i <= count; i -= lookback) { bool resetThis = phaseReset; - if (m_options & OptionTransientsMixed) { - int low = lrint((150 * sz * cd.oversample) / rate); - int high = lrint((1000 * sz * cd.oversample) / rate); + if (bandlimited) { if (resetThis) { - if (i > low && i < high) { + if (i > bandlow && i < bandhigh) { resetThis = false; fullReset = false; } } } + double p = cd.phase[i]; + double perr = 0.0; + double outphase = p; + + double mi = maxdist; + if (i <= limit0) mi = 0.0; + else if (i <= limit1) mi = 1.0; + else if (i <= limit2) mi = 3.0; + if (!resetThis) { - if (i == 0 || p != pp) { - + double omega = (2 * M_PI * m_increment * i) / (sz * cd.oversample); - double omega = (2 * M_PI * m_increment * p) / - (sz * cd.oversample); - double expectedPhase = cd.prevPhase[p] + omega; - double phaseError = princarg(cd.phase[p] - expectedPhase); - double phaseIncrement = (omega + phaseError) / m_increment; - - double unwrappedPhase = cd.unwrappedPhase[p] + - outputIncrement * phaseIncrement; + double pp = cd.prevPhase[i]; + double ep = pp + omega; + perr = princarg(p - ep); - cd.prevPhase[p] = cd.phase[p]; - cd.phase[p] = unwrappedPhase; - cd.unwrappedPhase[p] = unwrappedPhase; + double instability = fabs(perr - cd.prevError[i]); + bool direction = (perr > cd.prevError[i]); - peakInPhase = cd.prevPhase[p]; - peakOutPhase = unwrappedPhase; + bool inherit = false; + if (laminar) { + if (distance >= mi) { + inherit = false; + } else if (bandlimited && (i == bandhigh || i == bandlow)) { + inherit = false; + } else if (instability > prevInstability && + direction == prevDirection) { + inherit = true; + } } - if (i != p) { + double advance = outputIncrement * ((omega + perr) / m_increment); -// cd.phase[i] = atan2(cd.imag[i], cd.real[i]);//!!! - - double diffToPeak = peakInPhase - cd.phase[i]; - double unwrappedPhase = peakOutPhase - diffToPeak; - - cd.prevPhase[i] = cd.phase[i]; - cd.phase[i] = unwrappedPhase; - cd.unwrappedPhase[i] = unwrappedPhase; + if (inherit) { + double inherited = + cd.unwrappedPhase[i + lookback] - cd.prevPhase[i + lookback]; + advance = ((advance * distance) + (inherited * (mi - distance))) + / mi; + outphase = p + advance; + distance += 1.0; + } else { + outphase = cd.unwrappedPhase[i] + advance; + distance = 0.0; } + prevInstability = instability; + prevDirection = direction; + } else { - // resetThis == true - cd.prevPhase[i] = cd.phase[i]; - cd.unwrappedPhase[i] = cd.phase[i]; + distance = 0.0; } - } + cd.prevError[i] = perr; + cd.prevPhase[i] = p; + cd.phase[i] = outphase; + cd.unwrappedPhase[i] = outphase; + } if (fullReset) unchanged = true; cd.unchanged = unchanged; @@ -839,7 +776,7 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel, size_t outputIncrement, if (unchanged && m_debugLevel > 1) { cerr << "frame unchanged on channel " << channel << endl; } -} +} void diff --git a/src/ladspa/RubberBandPitchShifter.cpp b/src/ladspa/RubberBandPitchShifter.cpp index de981aa..6839124 100644 --- a/src/ladspa/RubberBandPitchShifter.cpp +++ b/src/ladspa/RubberBandPitchShifter.cpp @@ -379,15 +379,15 @@ RubberBandPitchShifter::updateCrispness() s->setTransientsOption(RubberBandStretcher::OptionTransientsSmooth); break; case 1: - s->setPhaseOption(RubberBandStretcher::OptionPhaseAdaptive); + s->setPhaseOption(RubberBandStretcher::OptionPhaseLaminar); s->setTransientsOption(RubberBandStretcher::OptionTransientsSmooth); break; case 2: - s->setPhaseOption(RubberBandStretcher::OptionPhaseAdaptive); + s->setPhaseOption(RubberBandStretcher::OptionPhaseLaminar); s->setTransientsOption(RubberBandStretcher::OptionTransientsMixed); break; case 3: - s->setPhaseOption(RubberBandStretcher::OptionPhaseAdaptive); + s->setPhaseOption(RubberBandStretcher::OptionPhaseLaminar); s->setTransientsOption(RubberBandStretcher::OptionTransientsCrisp); break; } diff --git a/src/main.cpp b/src/main.cpp index 6938b22..4face44 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,7 +76,6 @@ int main(int argc, char **argv) bool longwin = false; bool shortwin = false; bool hqpitch = false; - bool softening = true; bool formant = false; bool crispchanged = false; int crispness = -1; @@ -115,7 +114,6 @@ int main(int argc, char **argv) { "window-long", 0, 0, '3' }, { "window-short", 0, 0, '4' }, { "bl-transients", 0, 0, '8' }, - { "no-softening", 0, 0, '9' }, { "pitch-hq", 0, 0, '%' }, { "threads", 0, 0, '@' }, { "quiet", 0, 0, 'q' }, @@ -144,7 +142,6 @@ int main(int argc, char **argv) case '3': longwin = true; crispchanged = true; break; case '4': shortwin = true; crispchanged = true; break; case '8': transients = BandLimitedTransients; crispchanged = true; break; - case '9': softening = false; break; case '%': hqpitch = true; break; case 'c': crispness = atoi(optarg); break; case 'q': quiet = true; break; @@ -193,7 +190,6 @@ int main(int argc, char **argv) cerr << " --no-transients Disable phase resynchronisation at transients" << endl; cerr << " --bl-transients Band-limit phase resync to extreme frequencies" << endl; cerr << " --no-peaklock Disable phase locking to peak frequencies" << endl; - cerr << " --no-softening Disable large-ratio softening of phase locking" << endl; cerr << " --window-long Use longer processing window (actual size may vary)" << endl; cerr << " --window-short Use shorter processing window" << endl; cerr << " --pitch-hq In RT mode, use a slower, higher quality pitch shift" << endl; @@ -290,7 +286,6 @@ int main(int argc, char **argv) if (realtime) options |= RubberBandStretcher::OptionProcessRealTime; if (precise) options |= RubberBandStretcher::OptionStretchPrecise; if (!peaklock) options |= RubberBandStretcher::OptionPhaseIndependent; - if (!softening) options |= RubberBandStretcher::OptionPhasePeakLocked; if (longwin) options |= RubberBandStretcher::OptionWindowLong; if (shortwin) options |= RubberBandStretcher::OptionWindowShort; if (formant) options |= RubberBandStretcher::OptionFormantPreserved; diff --git a/src/sysutils.cpp b/src/sysutils.cpp index ba91d16..80cc152 100644 --- a/src/sysutils.cpp +++ b/src/sysutils.cpp @@ -27,6 +27,7 @@ #include + namespace RubberBand { bool @@ -101,6 +102,50 @@ void usleep(unsigned long usec) #endif + +float *allocFloat(float *ptr, int count) +{ + if (ptr) free((void *)ptr); + void *allocated; + if (!posix_memalign(&allocated, 16, count * sizeof(float))) { + allocated = malloc(count * sizeof(float)); + } + for (int i = 0; i < count; ++i) ((float *)allocated)[i] = 0.f; + return (float *)allocated; +} + +float *allocFloat(int count) +{ + return allocFloat(0, count); +} + +void freeFloat(float *ptr) +{ + if (ptr) free(ptr); +} + +double *allocDouble(double *ptr, int count) +{ + if (ptr) free((void *)ptr); + void *allocated; + if (!posix_memalign(&allocated, 16, count * sizeof(double))) { + allocated = malloc(count * sizeof(double)); + } + for (int i = 0; i < count; ++i) ((double *)allocated)[i] = 0.f; + return (double *)allocated; +} + +double *allocDouble(int count) +{ + return allocDouble(0, count); +} + +void freeDouble(double *ptr) +{ + if (ptr) free(ptr); +} + + } diff --git a/src/sysutils.h b/src/sysutils.h index 1c441d6..a529afd 100644 --- a/src/sysutils.h +++ b/src/sysutils.h @@ -49,6 +49,14 @@ void usleep(unsigned long); #endif +extern float *allocFloat(int); +extern float *allocFloat(float *, int); +extern void freeFloat(float *); + +extern double *allocDouble(int); +extern double *allocDouble(double *, int); +extern void freeDouble(double *); + } #endif diff --git a/src/vamp/RubberBandVampPlugin.cpp b/src/vamp/RubberBandVampPlugin.cpp index 9dfe4ff..feb5bfa 100644 --- a/src/vamp/RubberBandVampPlugin.cpp +++ b/src/vamp/RubberBandVampPlugin.cpp @@ -379,7 +379,7 @@ RubberBandVampPlugin::initialise(size_t channels, size_t stepSize, size_t blockS if (m_d->m_phaseIndependent) options |= RubberBand::RubberBandStretcher::OptionPhaseIndependent; - else options |= RubberBand::RubberBandStretcher::OptionPhasePeakLocked; + else options |= RubberBand::RubberBandStretcher::OptionPhaseLaminar; if (m_d->m_windowLength == 0) options |= RubberBand::RubberBandStretcher::OptionWindowStandard;