* Fix under/overruns in ladspa plugin
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
CXX := @CXX@
|
CXX := @CXX@
|
||||||
|
#CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS @CXXFLAGS@ @SRC_CFLAGS@ @SNDFILE_CFLAGS@ @FFTW_CFLAGS@ @Vamp_CFLAGS@ -Irubberband -Isrc $(OPTFLAGS)
|
||||||
|
OPTFLAGS := -O3 -ffast-math -ftree-vectorize -ftree-vect-loop-version -march=pentium4 -msse -msse2
|
||||||
CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS @CXXFLAGS@ @SRC_CFLAGS@ @SNDFILE_CFLAGS@ @FFTW_CFLAGS@ @Vamp_CFLAGS@ -Irubberband -Isrc $(OPTFLAGS)
|
CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS @CXXFLAGS@ @SRC_CFLAGS@ @SNDFILE_CFLAGS@ @FFTW_CFLAGS@ @Vamp_CFLAGS@ -Irubberband -Isrc $(OPTFLAGS)
|
||||||
CFLAGS := @CFLAGS@ $(OPTFLAGS)
|
CFLAGS := @CFLAGS@ $(OPTFLAGS)
|
||||||
LDFLAGS := @LDFLAGS@ -lpthread $(LDFLAGS)
|
LDFLAGS := @LDFLAGS@ -lpthread $(LDFLAGS)
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ protected:
|
|||||||
SRC_STATE *m_src;
|
SRC_STATE *m_src;
|
||||||
float *m_iin;
|
float *m_iin;
|
||||||
float *m_iout;
|
float *m_iout;
|
||||||
|
float m_lastRatio;
|
||||||
int m_channels;
|
int m_channels;
|
||||||
int m_iinsize;
|
int m_iinsize;
|
||||||
int m_ioutsize;
|
int m_ioutsize;
|
||||||
@@ -76,6 +77,7 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
|
|||||||
m_src(0),
|
m_src(0),
|
||||||
m_iin(0),
|
m_iin(0),
|
||||||
m_iout(0),
|
m_iout(0),
|
||||||
|
m_lastRatio(1.f),
|
||||||
m_channels(channels),
|
m_channels(channels),
|
||||||
m_iinsize(0),
|
m_iinsize(0),
|
||||||
m_ioutsize(0),
|
m_ioutsize(0),
|
||||||
@@ -105,6 +107,8 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
|
|||||||
m_iin = (float *)malloc(m_iinsize * sizeof(float));
|
m_iin = (float *)malloc(m_iinsize * sizeof(float));
|
||||||
m_iout = (float *)malloc(m_ioutsize * sizeof(float));
|
m_iout = (float *)malloc(m_ioutsize * sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
D_SRC::~D_SRC()
|
D_SRC::~D_SRC()
|
||||||
@@ -171,6 +175,8 @@ D_SRC::resample(const float *const R__ *const R__ in,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_lastRatio = ratio;
|
||||||
|
|
||||||
return data.output_frames_gen;
|
return data.output_frames_gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,6 +195,9 @@ StretchCalculator::calculateSingle(double ratio,
|
|||||||
|
|
||||||
m_prevDf = df;
|
m_prevDf = df;
|
||||||
|
|
||||||
|
bool ratioChanged = (ratio != m_prevRatio);
|
||||||
|
m_prevRatio = ratio;
|
||||||
|
|
||||||
if (isTransient && m_transientAmnesty == 0) {
|
if (isTransient && m_transientAmnesty == 0) {
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
std::cerr << "StretchCalculator::calculateSingle: transient"
|
std::cerr << "StretchCalculator::calculateSingle: transient"
|
||||||
@@ -210,9 +213,8 @@ StretchCalculator::calculateSingle(double ratio,
|
|||||||
return -int(increment);
|
return -int(increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_prevRatio != ratio) {
|
if (ratioChanged) {
|
||||||
m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment);
|
m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment);
|
||||||
m_prevRatio = ratio;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_transientAmnesty > 0) --m_transientAmnesty;
|
if (m_transientAmnesty > 0) --m_transientAmnesty;
|
||||||
|
|||||||
@@ -236,9 +236,27 @@ RubberBandStretcher::Impl::setPitchScale(double fs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fs == m_pitchScale) return;
|
if (fs == m_pitchScale) return;
|
||||||
|
|
||||||
|
bool was1 = (m_pitchScale == 1.f);
|
||||||
|
bool rbs = resampleBeforeStretching();
|
||||||
|
|
||||||
m_pitchScale = fs;
|
m_pitchScale = fs;
|
||||||
|
|
||||||
reconfigure();
|
reconfigure();
|
||||||
|
|
||||||
|
if (!(m_options & OptionPitchHighConsistency) &&
|
||||||
|
(was1 || resampleBeforeStretching() != rbs) &&
|
||||||
|
m_pitchScale != 1.f) {
|
||||||
|
|
||||||
|
cerr << "reset resampler" << endl;
|
||||||
|
|
||||||
|
// resampling mode has changed
|
||||||
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
|
if (m_channelData[c]->resampler) {
|
||||||
|
m_channelData[c]->resampler->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
|
|||||||
@@ -1042,7 +1042,6 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
|
|||||||
1.0 / m_pitchScale,
|
1.0 / m_pitchScale,
|
||||||
last);
|
last);
|
||||||
|
|
||||||
|
|
||||||
writeOutput(*cd.outbuf, cd.resamplebuf,
|
writeOutput(*cd.outbuf, cd.resamplebuf,
|
||||||
outframes, cd.outCount, theoreticalOut);
|
outframes, cd.outCount, theoreticalOut);
|
||||||
|
|
||||||
|
|||||||
@@ -80,27 +80,27 @@ RubberBandPitchShifter::portsStereo[PortCountStereo] =
|
|||||||
const LADSPA_PortRangeHint
|
const LADSPA_PortRangeHint
|
||||||
RubberBandPitchShifter::hintsMono[PortCountMono] =
|
RubberBandPitchShifter::hintsMono[PortCountMono] =
|
||||||
{
|
{
|
||||||
{ 0, 0, 0 },
|
{ 0, 0, 0 }, // latency
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // cents
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE,
|
LADSPA_HINT_BOUNDED_ABOVE,
|
||||||
-100.0, 100.0 },
|
-100.0, 100.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // semitones
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_INTEGER,
|
LADSPA_HINT_INTEGER,
|
||||||
-12.0, 12.0 },
|
-12.0, 12.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // octaves
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_INTEGER,
|
LADSPA_HINT_INTEGER,
|
||||||
-4.0, 4.0 },
|
-3.0, 3.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_MAXIMUM |
|
{ LADSPA_HINT_DEFAULT_MAXIMUM | // crispness
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_INTEGER,
|
LADSPA_HINT_INTEGER,
|
||||||
0.0, 3.0 },
|
0.0, 3.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // formant preserving
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_TOGGLED,
|
LADSPA_HINT_TOGGLED,
|
||||||
@@ -112,27 +112,27 @@ RubberBandPitchShifter::hintsMono[PortCountMono] =
|
|||||||
const LADSPA_PortRangeHint
|
const LADSPA_PortRangeHint
|
||||||
RubberBandPitchShifter::hintsStereo[PortCountStereo] =
|
RubberBandPitchShifter::hintsStereo[PortCountStereo] =
|
||||||
{
|
{
|
||||||
{ 0, 0, 0 },
|
{ 0, 0, 0 }, // latency
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // cents
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE,
|
LADSPA_HINT_BOUNDED_ABOVE,
|
||||||
-100.0, 100.0 },
|
-100.0, 100.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // semitones
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_INTEGER,
|
LADSPA_HINT_INTEGER,
|
||||||
-12.0, 12.0 },
|
-12.0, 12.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // octaves
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_INTEGER,
|
LADSPA_HINT_INTEGER,
|
||||||
-4.0, 4.0 },
|
-3.0, 3.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_MAXIMUM |
|
{ LADSPA_HINT_DEFAULT_MAXIMUM | // crispness
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_INTEGER,
|
LADSPA_HINT_INTEGER,
|
||||||
0.0, 3.0 },
|
0.0, 3.0 },
|
||||||
{ LADSPA_HINT_DEFAULT_0 |
|
{ LADSPA_HINT_DEFAULT_0 | // formant preserving
|
||||||
LADSPA_HINT_BOUNDED_BELOW |
|
LADSPA_HINT_BOUNDED_BELOW |
|
||||||
LADSPA_HINT_BOUNDED_ABOVE |
|
LADSPA_HINT_BOUNDED_ABOVE |
|
||||||
LADSPA_HINT_TOGGLED,
|
LADSPA_HINT_TOGGLED,
|
||||||
@@ -213,32 +213,29 @@ RubberBandPitchShifter::RubberBandPitchShifter(int sampleRate, size_t channels)
|
|||||||
m_prevRatio(1.0),
|
m_prevRatio(1.0),
|
||||||
m_currentCrispness(-1),
|
m_currentCrispness(-1),
|
||||||
m_currentFormant(false),
|
m_currentFormant(false),
|
||||||
m_extraLatency(128),
|
m_blockSize(1024),
|
||||||
|
m_reserve(1024),
|
||||||
m_stretcher(new RubberBandStretcher
|
m_stretcher(new RubberBandStretcher
|
||||||
(sampleRate, channels,
|
(sampleRate, channels,
|
||||||
RubberBandStretcher::OptionProcessRealTime)),
|
RubberBandStretcher::OptionProcessRealTime |
|
||||||
|
RubberBandStretcher::OptionPitchHighConsistency)),
|
||||||
m_sampleRate(sampleRate),
|
m_sampleRate(sampleRate),
|
||||||
m_channels(channels)
|
m_channels(channels)
|
||||||
{
|
{
|
||||||
for (size_t c = 0; c < m_channels; ++c) {
|
for (size_t c = 0; c < m_channels; ++c) {
|
||||||
|
|
||||||
m_input[c] = 0;
|
m_input[c] = 0;
|
||||||
m_output[c] = 0;
|
m_output[c] = 0;
|
||||||
//!!! size must be at least max process size plus m_extraLatency:
|
|
||||||
m_outputBuffer[c] = new RingBuffer<float>(8092); //!!!
|
int bufsize = m_blockSize + m_reserve + 8192;
|
||||||
m_outputBuffer[c]->zero(m_extraLatency);
|
|
||||||
//!!! size must be at least max process size:
|
m_outputBuffer[c] = new RingBuffer<float>(bufsize);
|
||||||
m_scratch[c] = new float[16384];//!!!
|
|
||||||
for (int i = 0; i < 16384; ++i) {
|
m_scratch[c] = new float[bufsize];
|
||||||
m_scratch[c][i] = 0.f;
|
for (int i = 0; i < bufsize; ++i) m_scratch[c][i] = 0.f;
|
||||||
}
|
|
||||||
}
|
|
||||||
int reqd = m_stretcher->getSamplesRequired();
|
|
||||||
m_stretcher->process(m_scratch, reqd, false);
|
|
||||||
int avail = m_stretcher->available();
|
|
||||||
std::cerr << "construction: reqd = " << reqd << ", available = " << avail << std::endl;
|
|
||||||
if (avail > 0) {
|
|
||||||
m_stretcher->retrieve(m_scratch, avail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activateImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
RubberBandPitchShifter::~RubberBandPitchShifter()
|
RubberBandPitchShifter::~RubberBandPitchShifter()
|
||||||
@@ -281,16 +278,40 @@ RubberBandPitchShifter::connectPort(LADSPA_Handle handle,
|
|||||||
};
|
};
|
||||||
|
|
||||||
*ports[port] = (float *)location;
|
*ports[port] = (float *)location;
|
||||||
|
|
||||||
|
if (shifter->m_latency) {
|
||||||
|
*(shifter->m_latency) =
|
||||||
|
float(shifter->m_stretcher->getLatency() + shifter->m_reserve);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RubberBandPitchShifter::activate(LADSPA_Handle handle)
|
RubberBandPitchShifter::activate(LADSPA_Handle handle)
|
||||||
{
|
{
|
||||||
RubberBandPitchShifter *shifter = (RubberBandPitchShifter *)handle;
|
RubberBandPitchShifter *shifter = (RubberBandPitchShifter *)handle;
|
||||||
shifter->updateRatio();
|
shifter->activateImpl();
|
||||||
shifter->m_prevRatio = shifter->m_ratio;
|
}
|
||||||
shifter->m_stretcher->reset();
|
|
||||||
shifter->m_stretcher->setPitchScale(shifter->m_ratio);
|
void
|
||||||
|
RubberBandPitchShifter::activateImpl()
|
||||||
|
{
|
||||||
|
updateRatio();
|
||||||
|
m_prevRatio = m_ratio;
|
||||||
|
m_stretcher->reset();
|
||||||
|
m_stretcher->setPitchScale(m_ratio);
|
||||||
|
|
||||||
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
|
m_outputBuffer[c]->reset();
|
||||||
|
m_outputBuffer[c]->zero(m_reserve);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prime stretcher
|
||||||
|
int reqd = m_stretcher->getSamplesRequired();
|
||||||
|
m_stretcher->process(m_scratch, reqd, false);
|
||||||
|
int avail = m_stretcher->available();
|
||||||
|
if (avail > 0) {
|
||||||
|
m_stretcher->retrieve(m_scratch, avail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -303,9 +324,9 @@ RubberBandPitchShifter::run(LADSPA_Handle handle, unsigned long samples)
|
|||||||
void
|
void
|
||||||
RubberBandPitchShifter::updateRatio()
|
RubberBandPitchShifter::updateRatio()
|
||||||
{
|
{
|
||||||
double oct = *m_octaves;
|
double oct = (m_octaves ? *m_octaves : 0.0);
|
||||||
oct += *m_semitones / 12;
|
oct += (m_semitones ? *m_semitones : 0.0) / 12;
|
||||||
oct += *m_cents / 1200;
|
oct += (m_cents ? *m_cents : 0.0) / 1200;
|
||||||
m_ratio = pow(2.0, oct);
|
m_ratio = pow(2.0, oct);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +381,30 @@ RubberBandPitchShifter::updateFormant()
|
|||||||
|
|
||||||
void
|
void
|
||||||
RubberBandPitchShifter::runImpl(unsigned long insamples)
|
RubberBandPitchShifter::runImpl(unsigned long insamples)
|
||||||
|
{
|
||||||
|
unsigned long offset = 0;
|
||||||
|
|
||||||
|
// We have to break up the input into chunks like this because
|
||||||
|
// insamples could be arbitrarily large and our output buffer is
|
||||||
|
// of limited size
|
||||||
|
|
||||||
|
while (offset < insamples) {
|
||||||
|
|
||||||
|
unsigned long block = (unsigned long)m_blockSize;
|
||||||
|
if (block > insamples) block = insamples;
|
||||||
|
|
||||||
|
runImpl(block, offset);
|
||||||
|
|
||||||
|
offset += block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RubberBandPitchShifter::runImpl(unsigned long insamples, unsigned long offset)
|
||||||
{
|
{
|
||||||
// std::cerr << "RubberBandPitchShifter::runImpl(" << insamples << ")" << std::endl;
|
// std::cerr << "RubberBandPitchShifter::runImpl(" << insamples << ")" << std::endl;
|
||||||
|
|
||||||
static int incount = 0, outcount = 0;
|
// static int incount = 0, outcount = 0;
|
||||||
|
|
||||||
updateRatio();
|
updateRatio();
|
||||||
if (m_ratio != m_prevRatio) {
|
if (m_ratio != m_prevRatio) {
|
||||||
@@ -372,43 +413,51 @@ RubberBandPitchShifter::runImpl(unsigned long insamples)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_latency) {
|
if (m_latency) {
|
||||||
*m_latency = float(m_stretcher->getLatency() + m_extraLatency);
|
*m_latency = float(m_stretcher->getLatency() + m_reserve);
|
||||||
// std::cerr << "latency = " << *m_latency << std::endl;
|
// std::cerr << "latency = " << *m_latency << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCrispness();
|
updateCrispness();
|
||||||
updateFormant();
|
updateFormant();
|
||||||
|
|
||||||
int samples = insamples;
|
const int samples = insamples;
|
||||||
int processed = 0;
|
int processed = 0;
|
||||||
size_t outTotal = 0;
|
size_t outTotal = 0;
|
||||||
|
|
||||||
float *ptrs[2];
|
float *ptrs[2];
|
||||||
|
|
||||||
// We have to break up the input into chunks like this because
|
if (m_outputBuffer[0]->getReadSpace() < m_reserve) {
|
||||||
// insamples could be arbitrarily large
|
m_stretcher->setTimeRatio(1.1); // fill up temporarily
|
||||||
|
} else if (m_outputBuffer[0]->getReadSpace() > 8192) {
|
||||||
|
m_stretcher->setTimeRatio(0.9); // reduce temporarily
|
||||||
|
} else {
|
||||||
|
m_stretcher->setTimeRatio(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
while (processed < samples) {
|
while (processed < samples) {
|
||||||
|
|
||||||
//!!! size_t:
|
// never feed more than the minimum necessary number of
|
||||||
|
// samples at a time; ensures nothing will overflow internally
|
||||||
|
// and we don't need to call setMaxProcessSize
|
||||||
|
|
||||||
int toCauseProcessing = m_stretcher->getSamplesRequired();
|
int toCauseProcessing = m_stretcher->getSamplesRequired();
|
||||||
// std::cout << "to-cause: " << toCauseProcessing << ", remain = " << samples - processed;
|
|
||||||
int inchunk = std::min(samples - processed, toCauseProcessing);
|
int inchunk = std::min(samples - processed, toCauseProcessing);
|
||||||
for (size_t c = 0; c < m_channels; ++c) {
|
for (size_t c = 0; c < m_channels; ++c) {
|
||||||
ptrs[c] = &(m_input[c][processed]);
|
ptrs[c] = &(m_input[c][offset + processed]);
|
||||||
}
|
}
|
||||||
m_stretcher->process(ptrs, inchunk, false);
|
m_stretcher->process(ptrs, inchunk, false);
|
||||||
processed += inchunk;
|
processed += inchunk;
|
||||||
incount += inchunk; //!!!
|
|
||||||
|
|
||||||
int avail = m_stretcher->available();
|
int avail = m_stretcher->available();
|
||||||
int writable = m_outputBuffer[0]->getWriteSpace();
|
int writable = m_outputBuffer[0]->getWriteSpace();
|
||||||
int outchunk = std::min(avail, writable);
|
int outchunk = std::min(avail, writable);
|
||||||
size_t actual = m_stretcher->retrieve(m_scratch, outchunk);
|
size_t actual = m_stretcher->retrieve(m_scratch, outchunk);
|
||||||
outTotal += actual;
|
outTotal += actual;
|
||||||
outcount += actual;
|
|
||||||
|
|
||||||
// std::cout << ", avail: " << avail << ", outchunk = " << outchunk;
|
// incount += inchunk;
|
||||||
|
// outcount += actual;
|
||||||
|
|
||||||
|
// std::cout << "avail: " << avail << ", outchunk = " << outchunk;
|
||||||
// if (actual != outchunk) std::cout << " (" << actual << ")";
|
// if (actual != outchunk) std::cout << " (" << actual << ")";
|
||||||
// std::cout << std::endl;
|
// std::cout << std::endl;
|
||||||
|
|
||||||
@@ -422,26 +471,13 @@ RubberBandPitchShifter::runImpl(unsigned long insamples)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "in: " << incount << ", out: " << outcount << ", loss: " << incount - outcount << std::endl;
|
|
||||||
|
|
||||||
// std::cout << "processed = " << processed << " in, " << outTotal << " out" << ", fill = " << m_outputBuffer[0]->getReadSpace() << " of " << m_outputBuffer[0]->getSize() << std::endl;
|
|
||||||
|
|
||||||
for (size_t c = 0; c < m_channels; ++c) {
|
for (size_t c = 0; c < m_channels; ++c) {
|
||||||
int avail = m_outputBuffer[c]->getReadSpace();
|
int toRead = m_outputBuffer[c]->getReadSpace();
|
||||||
// std::cout << "avail: " << avail << std::endl;
|
if (toRead < samples && c == 0) {
|
||||||
if (avail < samples && c == 0) {
|
std::cerr << "RubberBandPitchShifter::runImpl: buffer underrun: required = " << samples << ", available = " << toRead << std::endl;
|
||||||
std::cerr << "RubberBandPitchShifter::runImpl: buffer underrun: required = " << samples << ", available = " << avail << std::endl;
|
|
||||||
}
|
}
|
||||||
int chunk = std::min(avail, samples);
|
int chunk = std::min(toRead, samples);
|
||||||
// std::cout << "out chunk: " << chunk << std::endl;
|
m_outputBuffer[c]->read(&(m_output[c][offset]), chunk);
|
||||||
m_outputBuffer[c]->read(m_output[c], chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int minr = -1;
|
|
||||||
int avail = m_outputBuffer[0]->getReadSpace();
|
|
||||||
if (minr == -1 || (avail >= 0 && avail < minr)) {
|
|
||||||
std::cerr << "RubberBandPitchShifter::runImpl: new min remaining " << avail << " from " << minr << std::endl;
|
|
||||||
minr = avail;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,9 @@ protected:
|
|||||||
static void deactivate(LADSPA_Handle);
|
static void deactivate(LADSPA_Handle);
|
||||||
static void cleanup(LADSPA_Handle);
|
static void cleanup(LADSPA_Handle);
|
||||||
|
|
||||||
|
void activateImpl();
|
||||||
void runImpl(unsigned long);
|
void runImpl(unsigned long);
|
||||||
|
void runImpl(unsigned long, unsigned long offset);
|
||||||
void updateRatio();
|
void updateRatio();
|
||||||
void updateCrispness();
|
void updateCrispness();
|
||||||
void updateFormant();
|
void updateFormant();
|
||||||
@@ -85,7 +87,8 @@ protected:
|
|||||||
int m_currentCrispness;
|
int m_currentCrispness;
|
||||||
bool m_currentFormant;
|
bool m_currentFormant;
|
||||||
|
|
||||||
size_t m_extraLatency;
|
size_t m_blockSize;
|
||||||
|
size_t m_reserve;
|
||||||
|
|
||||||
RubberBand::RubberBandStretcher *m_stretcher;
|
RubberBand::RubberBandStretcher *m_stretcher;
|
||||||
RubberBand::RingBuffer<float> *m_outputBuffer[2];
|
RubberBand::RingBuffer<float> *m_outputBuffer[2];
|
||||||
|
|||||||
4
src/ladspa/ladspa-plugin.map
Normal file
4
src/ladspa/ladspa-plugin.map
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
global: ladspa_descriptor;
|
||||||
|
local: *;
|
||||||
|
};
|
||||||
4
src/vamp/vamp-plugin.map
Normal file
4
src/vamp/vamp-plugin.map
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
global: vampGetPluginDescriptor;
|
||||||
|
local: *;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user