* Add library API version to headers
* Add phase reset on silence (doesn't appear to make much difference) * Fix mistake in LRDF file
This commit is contained in:
@@ -55,6 +55,7 @@ LIBRARY_INCLUDES := \
|
||||
src/Resampler.h \
|
||||
src/RingBuffer.h \
|
||||
src/Scavenger.h \
|
||||
src/SilentAudioCurve.h \
|
||||
src/SpectralDifferenceAudioCurve.h \
|
||||
src/StretchCalculator.h \
|
||||
src/StretcherImpl.h \
|
||||
@@ -73,6 +74,7 @@ LIBRARY_SOURCES := \
|
||||
src/Resampler.cpp \
|
||||
src/rubberband-c.cpp \
|
||||
src/RubberBandStretcher.cpp \
|
||||
src/SilentAudioCurve.cpp \
|
||||
src/SpectralDifferenceAudioCurve.cpp \
|
||||
src/StretchCalculator.cpp \
|
||||
src/StretcherImpl.cpp \
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#ifndef _RUBBERBANDSTRETCHER_H_
|
||||
#define _RUBBERBANDSTRETCHER_H_
|
||||
|
||||
#define RUBBERBAND_API_MAJOR_VERSION 2
|
||||
#define RUBBERBAND_API_MINOR_VERSION 0
|
||||
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RUBBERBAND_API_MAJOR_VERSION 2
|
||||
#define RUBBERBAND_API_MINOR_VERSION 0
|
||||
|
||||
/**
|
||||
* This is a C-linkage interface to the Rubber Band time stretcher.
|
||||
*
|
||||
|
||||
69
src/SilentAudioCurve.cpp
Normal file
69
src/SilentAudioCurve.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- 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 "SilentAudioCurve.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
SilentAudioCurve::SilentAudioCurve(size_t sampleRate, size_t windowSize) :
|
||||
AudioCurve(sampleRate, windowSize)
|
||||
{
|
||||
}
|
||||
|
||||
SilentAudioCurve::~SilentAudioCurve()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SilentAudioCurve::reset()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SilentAudioCurve::setWindowSize(size_t newSize)
|
||||
{
|
||||
m_windowSize = newSize;
|
||||
}
|
||||
|
||||
float
|
||||
SilentAudioCurve::process(const float *R__ mag, size_t)
|
||||
{
|
||||
const int hs = m_windowSize / 2;
|
||||
static float threshold = powf(10.f, -6);
|
||||
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
if (mag[i] > threshold) return 0.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
float
|
||||
SilentAudioCurve::process(const double *R__ mag, size_t)
|
||||
{
|
||||
const int hs = m_windowSize / 2;
|
||||
static double threshold = pow(10.0, -6);
|
||||
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
if (mag[i] > threshold) return 0.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
38
src/SilentAudioCurve.h
Normal file
38
src/SilentAudioCurve.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef _SILENT_AUDIO_CURVE_H_
|
||||
#define _SILENT_AUDIO_CURVE_H_
|
||||
|
||||
#include "AudioCurve.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
class SilentAudioCurve : public AudioCurve
|
||||
{
|
||||
public:
|
||||
SilentAudioCurve(size_t sampleRate, size_t windowSize);
|
||||
virtual ~SilentAudioCurve();
|
||||
|
||||
virtual void setWindowSize(size_t newSize);
|
||||
|
||||
virtual float process(const float *R__ mag, size_t increment);
|
||||
virtual float process(const double *R__ mag, size_t increment);
|
||||
virtual void reset();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "PercussiveAudioCurve.h"
|
||||
#include "HighFrequencyAudioCurve.h"
|
||||
#include "SpectralDifferenceAudioCurve.h"
|
||||
#include "SilentAudioCurve.h"
|
||||
#include "ConstantAudioCurve.h"
|
||||
#include "StretchCalculator.h"
|
||||
#include "StretcherChannelData.h"
|
||||
@@ -72,6 +73,7 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
|
||||
m_studyFFT(0),
|
||||
m_spaceAvailable("space"),
|
||||
m_inputDuration(0),
|
||||
m_silentHistory(0),
|
||||
m_lastProcessOutputIncrements(16),
|
||||
m_lastProcessPhaseResetDf(16),
|
||||
m_phaseResetAudioCurve(0),
|
||||
@@ -163,6 +165,7 @@ RubberBandStretcher::Impl::~Impl()
|
||||
|
||||
delete m_phaseResetAudioCurve;
|
||||
delete m_stretchAudioCurve;
|
||||
delete m_silentAudioCurve;
|
||||
delete m_stretchCalculator;
|
||||
delete m_studyFFT;
|
||||
|
||||
@@ -196,7 +199,9 @@ RubberBandStretcher::Impl::reset()
|
||||
m_mode = JustCreated;
|
||||
if (m_phaseResetAudioCurve) m_phaseResetAudioCurve->reset();
|
||||
if (m_stretchAudioCurve) m_stretchAudioCurve->reset();
|
||||
if (m_silentAudioCurve) m_silentAudioCurve->reset();
|
||||
m_inputDuration = 0;
|
||||
m_silentHistory = 0;
|
||||
|
||||
if (m_threaded) m_threadSetMutex.unlock();
|
||||
|
||||
@@ -546,12 +551,17 @@ RubberBandStretcher::Impl::configure()
|
||||
}
|
||||
}
|
||||
|
||||
delete m_phaseResetAudioCurve;
|
||||
m_phaseResetAudioCurve = new PercussiveAudioCurve(m_sampleRate,
|
||||
m_windowSize);
|
||||
// stretchAudioCurve is unused in RT mode; phaseResetAudioCurve,
|
||||
// silentAudioCurve and stretchCalculator however are used in all
|
||||
// modes
|
||||
|
||||
// stretchAudioCurve unused in RT mode; phaseResetAudioCurve and
|
||||
// stretchCalculator however are used in all modes
|
||||
delete m_phaseResetAudioCurve;
|
||||
m_phaseResetAudioCurve = new PercussiveAudioCurve
|
||||
(m_sampleRate, m_windowSize);
|
||||
|
||||
delete m_silentAudioCurve;
|
||||
m_silentAudioCurve = new SilentAudioCurve
|
||||
(m_sampleRate, m_windowSize);
|
||||
|
||||
if (!m_realtime) {
|
||||
delete m_stretchAudioCurve;
|
||||
@@ -602,6 +612,7 @@ RubberBandStretcher::Impl::reconfigure()
|
||||
calculateStretch();
|
||||
m_phaseResetDf.clear();
|
||||
m_stretchDf.clear();
|
||||
m_silence.clear();
|
||||
m_inputDuration = 0;
|
||||
}
|
||||
configure();
|
||||
@@ -782,8 +793,8 @@ RubberBandStretcher::Impl::study(const float *const *input, size_t samples, bool
|
||||
consumed += writable;
|
||||
}
|
||||
|
||||
while ((inbuf.getReadSpace() >= m_windowSize) ||
|
||||
(final && (inbuf.getReadSpace() >= m_windowSize/2))) {
|
||||
while ((inbuf.getReadSpace() >= int(m_windowSize)) ||
|
||||
(final && (inbuf.getReadSpace() >= int(m_windowSize/2)))) {
|
||||
|
||||
// We know we have at least m_windowSize samples available
|
||||
// in m_inbuf. We need to peek m_windowSize of them for
|
||||
@@ -811,6 +822,11 @@ RubberBandStretcher::Impl::study(const float *const *input, size_t samples, bool
|
||||
df = m_stretchAudioCurve->process(cd.fltbuf, m_increment);
|
||||
m_stretchDf.push_back(df);
|
||||
|
||||
df = m_silentAudioCurve->process(cd.fltbuf, m_increment);
|
||||
bool silent = (df > 0.f);
|
||||
if (silent) cerr << "silence found at " << m_inputDuration << endl;
|
||||
m_silence.push_back(silent);
|
||||
|
||||
// cout << df << endl;
|
||||
|
||||
// We have augmented the input by m_windowSize/2 so
|
||||
@@ -892,6 +908,20 @@ RubberBandStretcher::Impl::calculateStretch()
|
||||
m_phaseResetDf,
|
||||
m_stretchDf);
|
||||
|
||||
int history = 0;
|
||||
for (size_t i = 0; i < increments.size(); ++i) {
|
||||
if (i >= m_silence.size()) break;
|
||||
if (m_silence[i]) ++history;
|
||||
else history = 0;
|
||||
if (history >= (m_windowSize / m_increment) && increments[i] >= 0) {
|
||||
increments[i] = -increments[i];
|
||||
// if (m_debugLevel > 1) {
|
||||
std::cerr << "phase reset on silence (silent history == "
|
||||
<< history << ")" << std::endl;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if (m_outputIncrements.empty()) m_outputIncrements = increments;
|
||||
else {
|
||||
for (size_t i = 0; i < increments.size(); ++i) {
|
||||
@@ -1055,7 +1085,7 @@ RubberBandStretcher::Impl::process(const float *const *input, size_t samples, bo
|
||||
*/
|
||||
}
|
||||
|
||||
if (!allConsumed) cerr << "process looping" << endl;
|
||||
// if (!allConsumed) cerr << "process looping" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,8 @@ protected:
|
||||
size_t m_inputDuration;
|
||||
std::vector<float> m_phaseResetDf;
|
||||
std::vector<float> m_stretchDf;
|
||||
std::vector<bool> m_silence;
|
||||
int m_silentHistory;
|
||||
|
||||
class ChannelData;
|
||||
std::vector<ChannelData *> m_channelData;
|
||||
@@ -177,6 +179,7 @@ protected:
|
||||
|
||||
AudioCurve *m_phaseResetAudioCurve;
|
||||
AudioCurve *m_stretchAudioCurve;
|
||||
AudioCurve *m_silentAudioCurve;
|
||||
StretchCalculator *m_stretchCalculator;
|
||||
|
||||
float m_freq0;
|
||||
|
||||
@@ -147,8 +147,6 @@ RubberBandStretcher::Impl::consumeChannel(size_t c, const float *input,
|
||||
}
|
||||
|
||||
|
||||
// std::cerr << "resampling on INPUT" << std::endl;
|
||||
|
||||
toWrite = cd.resampler->resample(&input,
|
||||
&cd.resamplebuf,
|
||||
samples,
|
||||
@@ -445,10 +443,12 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
|
||||
// be apparent.
|
||||
|
||||
float df = 0.f;
|
||||
bool silent = false;
|
||||
|
||||
if (m_channels == 1) {
|
||||
|
||||
df = m_phaseResetAudioCurve->process(cd.mag, m_increment);
|
||||
silent = (m_silentAudioCurve->process(cd.mag, m_increment) > 0.f);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -464,6 +464,7 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
|
||||
}
|
||||
|
||||
df = m_phaseResetAudioCurve->process(tmp, m_increment);
|
||||
silent = (m_silentAudioCurve->process(tmp, m_increment) > 0.f);
|
||||
}
|
||||
|
||||
int incr = m_stretchCalculator->calculateSingle
|
||||
@@ -499,6 +500,17 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
|
||||
}
|
||||
|
||||
cd.prevIncrement = shiftIncrementRtn;
|
||||
|
||||
if (silent) ++m_silentHistory;
|
||||
else m_silentHistory = 0;
|
||||
|
||||
if (m_silentHistory >= (m_windowSize / m_increment) && !phaseReset) {
|
||||
phaseReset = true;
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "calculateIncrements: phase reset on silence (silent history == "
|
||||
<< m_silentHistory << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -852,12 +864,9 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
|
||||
dblbuf[i] /= denom;
|
||||
}
|
||||
|
||||
//!!! calculate this value -- the divisor should be the highest fundamental frequency we expect to find, plus a bit
|
||||
const int cutoff = m_sampleRate / 700;
|
||||
// const int cutoff = 1000;
|
||||
// const int cutoff = 20;
|
||||
|
||||
// cerr <<"cutoff = "<< cutoff << ", m_sampleRate/cutoff = " << m_sampleRate/cutoff << ", m_sampleRate/700 = " << m_sampleRate/700 << endl;
|
||||
// cerr <<"cutoff = "<< cutoff << ", m_sampleRate/cutoff = " << m_sampleRate/cutoff << endl;
|
||||
|
||||
dblbuf[0] /= 2;
|
||||
dblbuf[cutoff-1] /= 2;
|
||||
@@ -880,7 +889,7 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
|
||||
// scaling up, we want a new envelope that is lower by the pitch factor
|
||||
for (int target = 0; target <= hs; ++target) {
|
||||
int source = lrint(target * m_pitchScale);
|
||||
if (source > m_windowSize) {
|
||||
if (source > int(m_windowSize)) {
|
||||
envelope[target] = 0.0;
|
||||
} else {
|
||||
envelope[target] = envelope[source];
|
||||
@@ -897,7 +906,6 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
|
||||
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
mag[i] *= envelope[i];
|
||||
// mag[i] = envelope[i];
|
||||
}
|
||||
|
||||
cd.unchanged = false;
|
||||
@@ -957,10 +965,8 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel)
|
||||
|
||||
// our ffts produced unscaled results
|
||||
for (i = 0; i < sz; ++i) {
|
||||
fltbuf[i] = fltbuf[i] / float(sz * cd.oversample);
|
||||
fltbuf[i] = fltbuf[i] / denom;
|
||||
}
|
||||
// } else {
|
||||
// cerr << "unchanged on channel " << channel << endl;
|
||||
}
|
||||
|
||||
m_window->cut(fltbuf);
|
||||
@@ -1030,8 +1036,6 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
|
||||
}
|
||||
|
||||
|
||||
// std::cerr << "resampling on OUTPUT" << std::endl;
|
||||
|
||||
size_t outframes = cd.resampler->resample(&cd.accumulator,
|
||||
&cd.resamplebuf,
|
||||
si,
|
||||
|
||||
@@ -10,3 +10,5 @@
|
||||
<ladspa:PitchPlugin rdf:about="&ladspa;2979"/>
|
||||
<ladspa:PitchPlugin rdf:about="&ladspa;9792"/>
|
||||
|
||||
</rdf:RDF>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user