Update from personal repository.
* Added an initial "formant preservation" option when pitch shifting * Real-time pitch shifting now uses a faster method by default, with less variation in CPU usage * The code is more amenable to compiler auto-vectorization (through e.g. gcc --ftree-vectorize).
This commit is contained in:
@@ -1,22 +1,39 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2008 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version. See the file
|
||||
COPYING included with this distribution for more information.
|
||||
*/
|
||||
|
||||
#include "StretcherChannelData.h"
|
||||
|
||||
#include "Resampler.h"
|
||||
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
RubberBandStretcher::Impl::ChannelData::ChannelData(size_t windowSize,
|
||||
size_t outbufSize)
|
||||
int overSample,
|
||||
size_t outbufSize) :
|
||||
oversample(overSample)
|
||||
{
|
||||
std::set<size_t> s;
|
||||
construct(s, windowSize, outbufSize);
|
||||
}
|
||||
|
||||
RubberBandStretcher::Impl::ChannelData::ChannelData(const std::set<size_t> &windowSizes,
|
||||
int overSample,
|
||||
size_t initialWindowSize,
|
||||
size_t outbufSize)
|
||||
size_t outbufSize) :
|
||||
oversample(overSample)
|
||||
{
|
||||
construct(windowSizes, initialWindowSize, outbufSize);
|
||||
}
|
||||
@@ -37,7 +54,8 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &window
|
||||
if (initialWindowSize > maxSize) maxSize = initialWindowSize;
|
||||
}
|
||||
|
||||
size_t realSize = maxSize/2 + 1; // size of the real "half" of freq data
|
||||
// max size of the real "half" of freq data
|
||||
size_t realSize = (maxSize * oversample)/2 + 1;
|
||||
|
||||
// std::cerr << "ChannelData::construct([" << windowSizes.size() << "], " << maxSize << ", " << outbufSize << ")" << std::endl;
|
||||
|
||||
@@ -51,19 +69,21 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &window
|
||||
prevPhase = new double[realSize];
|
||||
unwrappedPhase = new double[realSize];
|
||||
freqPeak = new size_t[realSize];
|
||||
envelope = new double[realSize];
|
||||
|
||||
fltbuf = new float[maxSize];
|
||||
|
||||
accumulator = new float[maxSize];
|
||||
windowAccumulator = new float[maxSize];
|
||||
|
||||
fltbuf = new float[maxSize];
|
||||
|
||||
for (std::set<size_t>::const_iterator i = windowSizes.begin();
|
||||
i != windowSizes.end(); ++i) {
|
||||
ffts[*i] = new FFT(*i);
|
||||
ffts[*i] = new FFT(*i * oversample);
|
||||
ffts[*i]->initDouble();
|
||||
}
|
||||
if (windowSizes.find(initialWindowSize) == windowSizes.end()) {
|
||||
ffts[initialWindowSize] = new FFT(initialWindowSize);
|
||||
ffts[initialWindowSize] = new FFT(initialWindowSize * oversample);
|
||||
ffts[initialWindowSize]->initDouble();
|
||||
}
|
||||
fft = ffts[initialWindowSize];
|
||||
@@ -82,16 +102,17 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &window
|
||||
prevPhase[i] = 0.0;
|
||||
unwrappedPhase[i] = 0.0;
|
||||
freqPeak[i] = 0;
|
||||
envelope[i] = 0.0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < initialWindowSize; ++i) {
|
||||
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.0;
|
||||
fltbuf[i] = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +120,7 @@ void
|
||||
RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
|
||||
{
|
||||
size_t oldSize = inbuf->getSize();
|
||||
size_t realSize = windowSize/2 + 1;
|
||||
size_t realSize = (windowSize * oversample) / 2 + 1;
|
||||
|
||||
// std::cerr << "ChannelData::setWindowSize(" << windowSize << ") [from " << oldSize << "]" << std::endl;
|
||||
|
||||
@@ -114,7 +135,7 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
|
||||
if (ffts.find(windowSize) == ffts.end()) {
|
||||
//!!! this also requires a lock, but it shouldn't occur in
|
||||
//RT mode with proper initialisation
|
||||
ffts[windowSize] = new FFT(windowSize);
|
||||
ffts[windowSize] = new FFT(windowSize * oversample);
|
||||
ffts[windowSize]->initDouble();
|
||||
}
|
||||
|
||||
@@ -122,7 +143,7 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
|
||||
|
||||
dblbuf = fft->getDoubleTimeBuffer();
|
||||
|
||||
for (size_t i = 0; i < windowSize; ++i) {
|
||||
for (size_t i = 0; i < windowSize * oversample; ++i) {
|
||||
dblbuf[i] = 0.0;
|
||||
}
|
||||
|
||||
@@ -155,16 +176,19 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
|
||||
delete[] prevPhase;
|
||||
delete[] unwrappedPhase;
|
||||
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];
|
||||
|
||||
|
||||
// But we do want to preserve data in these
|
||||
|
||||
float *newAcc = new float[windowSize];
|
||||
@@ -185,10 +209,11 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
|
||||
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.0;
|
||||
fltbuf[i] = 0.f;
|
||||
}
|
||||
|
||||
for (size_t i = oldSize; i < windowSize; ++i) {
|
||||
@@ -197,7 +222,7 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
|
||||
}
|
||||
|
||||
if (ffts.find(windowSize) == ffts.end()) {
|
||||
ffts[windowSize] = new FFT(windowSize);
|
||||
ffts[windowSize] = new FFT(windowSize * oversample);
|
||||
ffts[windowSize]->initDouble();
|
||||
}
|
||||
|
||||
@@ -205,7 +230,7 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
|
||||
|
||||
dblbuf = fft->getDoubleTimeBuffer();
|
||||
|
||||
for (size_t i = 0; i < windowSize; ++i) {
|
||||
for (size_t i = 0; i < windowSize * oversample; ++i) {
|
||||
dblbuf[i] = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -228,13 +253,32 @@ 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;
|
||||
resamplebufSize = sz;
|
||||
}
|
||||
|
||||
RubberBandStretcher::Impl::ChannelData::~ChannelData()
|
||||
{
|
||||
delete resampler;
|
||||
delete[] resamplebuf;
|
||||
|
||||
if (resamplebuf) {
|
||||
delete[] resamplebuf;
|
||||
}
|
||||
|
||||
delete inbuf;
|
||||
delete outbuf;
|
||||
|
||||
delete[] mag;
|
||||
delete[] phase;
|
||||
delete[] prevPhase;
|
||||
@@ -243,6 +287,7 @@ RubberBandStretcher::Impl::ChannelData::~ChannelData()
|
||||
delete[] accumulator;
|
||||
delete[] windowAccumulator;
|
||||
delete[] fltbuf;
|
||||
delete[] envelope;
|
||||
|
||||
for (std::map<size_t, FFT *>::iterator i = ffts.begin();
|
||||
i != ffts.end(); ++i) {
|
||||
@@ -264,6 +309,7 @@ RubberBandStretcher::Impl::ChannelData::reset()
|
||||
inCount = 0;
|
||||
inputSize = -1;
|
||||
outCount = 0;
|
||||
unchanged = true;
|
||||
draining = false;
|
||||
outputComplete = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user