* 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:
Chris Cannam
2008-07-02 21:20:22 +00:00
parent 6b277bd8dd
commit 1e2cae8e2d
9 changed files with 178 additions and 24 deletions

View File

@@ -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 \

View File

@@ -15,6 +15,9 @@
#ifndef _RUBBERBANDSTRETCHER_H_
#define _RUBBERBANDSTRETCHER_H_
#define RUBBERBAND_API_MAJOR_VERSION 2
#define RUBBERBAND_API_MINOR_VERSION 0
#include <vector>
/**

View File

@@ -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
View 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
View 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

View File

@@ -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();
@@ -361,8 +366,8 @@ RubberBandStretcher::Impl::calculateSizes()
outputIncrement /= 2;
inputIncrement = int(outputIncrement / r);
}
size_t minwin = roundUp(lrint(outputIncrement * windowIncrRatio));
if (windowSize < minwin) windowSize = minwin;
size_t minwin = roundUp(lrint(outputIncrement * windowIncrRatio));
if (windowSize < minwin) windowSize = minwin;
if (rsb) {
// cerr << "adjusting window size from " << windowSize;
@@ -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;
}

View File

@@ -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;

View File

@@ -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,7 +464,8 @@ 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
(getEffectiveRatio(), df, m_increment);
@@ -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,

View File

@@ -10,3 +10,5 @@
<ladspa:PitchPlugin rdf:about="&ladspa;2979"/>
<ladspa:PitchPlugin rdf:about="&ladspa;9792"/>
</rdf:RDF>