Update from main repo.

* Add a more reliable transient detection mode, and make the mode
   selectable using OptionDetectorXXX flags -- the new method is
   the default
 * Band-limit transient detectors to avoid being distracted by
   inaudible garbage
 * Add a key-frame mapping facility for variable stretch ratio
   management during offline stretches
This commit is contained in:
Chris Cannam
2010-03-24 09:44:51 +00:00
parent 45a7ec1868
commit 87dc720243
53 changed files with 1287 additions and 294 deletions

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -14,18 +14,50 @@
#include "AudioCurveCalculator.h"
#include <iostream>
namespace RubberBand
{
AudioCurveCalculator::AudioCurveCalculator(size_t sampleRate, size_t windowSize) :
m_sampleRate(sampleRate),
m_windowSize(windowSize)
static const int MaxPerceivedFreq = 16000;
AudioCurveCalculator::AudioCurveCalculator(Parameters parameters) :
m_sampleRate(parameters.sampleRate),
m_windowSize(parameters.windowSize)
{
recalculateLastPerceivedBin();
}
AudioCurveCalculator::~AudioCurveCalculator()
{
}
void
AudioCurveCalculator::setSampleRate(int newRate)
{
m_sampleRate = newRate;
recalculateLastPerceivedBin();
}
void
AudioCurveCalculator::setWindowSize(int newSize)
{
m_windowSize = newSize;
recalculateLastPerceivedBin();
}
void
AudioCurveCalculator::recalculateLastPerceivedBin()
{
if (m_sampleRate == 0) {
m_lastPerceivedBin = 0;
return;
}
m_lastPerceivedBin = ((MaxPerceivedFreq * m_windowSize) / m_sampleRate);
if (m_lastPerceivedBin > m_windowSize/2) {
m_lastPerceivedBin = m_windowSize/2;
}
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -26,28 +26,51 @@ namespace RubberBand
class AudioCurveCalculator
{
public:
AudioCurveCalculator(size_t sampleRate, size_t windowSize);
struct Parameters {
Parameters(int _sampleRate, int _windowSize) :
sampleRate(_sampleRate),
windowSize(_windowSize)
{ }
int sampleRate;
int windowSize;
};
AudioCurveCalculator(Parameters parameters);
virtual ~AudioCurveCalculator();
size_t getSampleRate() const { return m_sampleRate; }
size_t getWindowSize() const { return m_windowSize; }
int getSampleRate() const { return m_sampleRate; }
int getWindowSize() const { return m_windowSize; }
virtual void setWindowSize(size_t newSize) = 0;
virtual void setSampleRate(int newRate);
virtual void setWindowSize(int newSize);
Parameters getParameters() const {
return Parameters(m_sampleRate, m_windowSize);
}
void setParameters(Parameters p) {
setSampleRate(p.sampleRate);
setWindowSize(p.windowSize);
}
// You may not mix calls to the various process functions on a
// given instance
virtual float processFloat(const float *R__ mag, size_t increment) = 0;
virtual double processDouble(const double *R__ mag, size_t increment) = 0;
virtual float processFloat(const float *R__ mag, int increment) = 0;
virtual double processDouble(const double *R__ mag, int increment) = 0;
virtual void reset() = 0;
virtual const char *getUnit() const { return ""; }
protected:
size_t m_sampleRate;
size_t m_windowSize;
int m_sampleRate;
int m_windowSize;
int m_lastPerceivedBin;
void recalculateLastPerceivedBin();
};
}
#endif

View File

@@ -0,0 +1,164 @@
/* -*- 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-2010 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 "CompoundAudioCurve.h"
#include "MovingMedian.h"
#include <iostream>
namespace RubberBand
{
CompoundAudioCurve::CompoundAudioCurve(Parameters parameters) :
AudioCurveCalculator(parameters),
m_percussive(parameters),
m_hf(parameters),
m_hfFilter(new MovingMedian<double>(19, 85)),
m_hfDerivFilter(new MovingMedian<double>(19, 90)),
m_lastHf(0.0),
m_lastResult(0.0),
m_risingCount(0)
{
std::cerr << "CompoundAudioCurve::CompoundAudioCurve: window "
<< parameters.windowSize << ", rate " << parameters.sampleRate
<< std::endl;
}
CompoundAudioCurve::~CompoundAudioCurve()
{
delete m_hfFilter;
delete m_hfDerivFilter;
}
void
CompoundAudioCurve::setType(Type type)
{
std::cerr << "CompoundAudioCurve::setType to " << type << std::endl;
m_type = type;
}
void
CompoundAudioCurve::reset()
{
m_percussive.reset();
m_hf.reset();
m_hfFilter->reset();
m_hfDerivFilter->reset();
m_lastHf = 0.0;
m_lastResult = 0.0;
}
void
CompoundAudioCurve::setWindowSize(int newSize)
{
m_percussive.setWindowSize(newSize);
m_hf.setWindowSize(newSize);
m_windowSize = newSize;
m_lastHf = 0.0;
m_lastResult = 0.0;
}
float
CompoundAudioCurve::processFloat(const float *R__ mag, int increment)
{
float percussive = 0.f;
float hf = 0.f;
switch (m_type) {
case PercussiveDetector:
percussive = m_percussive.processFloat(mag, increment);
break;
case CompoundDetector:
percussive = m_percussive.processFloat(mag, increment);
hf = m_hf.processFloat(mag, increment);
break;
case SoftDetector:
hf = m_hf.processFloat(mag, increment);
break;
}
return processFiltering(percussive, hf);
}
double
CompoundAudioCurve::processDouble(const double *R__ mag, int increment)
{
double percussive = 0.0;
double hf = 0.0;
switch (m_type) {
case PercussiveDetector:
percussive = m_percussive.processDouble(mag, increment);
break;
case CompoundDetector:
percussive = m_percussive.processDouble(mag, increment);
hf = m_hf.processDouble(mag, increment);
break;
case SoftDetector:
hf = m_hf.processDouble(mag, increment);
break;
}
return processFiltering(percussive, hf);
}
double
CompoundAudioCurve::processFiltering(double percussive, double hf)
{
if (m_type == PercussiveDetector) {
if (percussive > 0.35) {
return 1.0;
} else {
return 0.0;
}
}
double rv = 0.f;
double hfDeriv = hf - m_lastHf;
m_hfFilter->push(hf);
m_hfDerivFilter->push(hfDeriv);
double hfFiltered = m_hfFilter->get();
double hfDerivFiltered = m_hfDerivFilter->get();
m_lastHf = hf;
double result = 0.f;
double hfExcess = hf - hfFiltered;
if (hfExcess > 0.0) {
result = hfDeriv - hfDerivFiltered;
}
if (m_type != SoftDetector && percussive > 0.35 && hfExcess > 0.0) {
rv = 1.0;
m_risingCount = 0;
} else {
if (result < m_lastResult) {
if (m_risingCount > 3 && m_lastResult > 0) rv = 0.5;
m_risingCount = 0;
} else {
m_risingCount ++;
}
}
m_lastResult = result;
return rv;
}
}

View File

@@ -0,0 +1,65 @@
/* -*- 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-2010 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 _COMPOUND_AUDIO_CURVE_H_
#define _COMPOUND_AUDIO_CURVE_H_
#include "AudioCurveCalculator.h"
#include "PercussiveAudioCurve.h"
#include "HighFrequencyAudioCurve.h"
#include "SampleFilter.h"
namespace RubberBand
{
class CompoundAudioCurve : public AudioCurveCalculator
{
public:
CompoundAudioCurve(Parameters parameters);
virtual ~CompoundAudioCurve();
enum Type {
PercussiveDetector,
CompoundDetector,
SoftDetector
};
virtual void setType(Type);
virtual void setWindowSize(int newSize);
virtual float processFloat(const float *R__ mag, int increment);
virtual double processDouble(const double *R__ mag, int increment);
virtual void reset();
protected:
PercussiveAudioCurve m_percussive;
HighFrequencyAudioCurve m_hf;
SampleFilter<double> *m_hfFilter;
SampleFilter<double> *m_hfDerivFilter;
Type m_type;
double m_lastHf;
double m_lastResult;
int m_risingCount;
double processFiltering(double percussive, double hf);
};
}
#endif

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -17,8 +17,9 @@
namespace RubberBand
{
ConstantAudioCurve::ConstantAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurveCalculator(sampleRate, windowSize)
ConstantAudioCurve::ConstantAudioCurve(Parameters parameters) :
AudioCurveCalculator(parameters)
{
}
@@ -31,20 +32,14 @@ ConstantAudioCurve::reset()
{
}
void
ConstantAudioCurve::setWindowSize(size_t newSize)
{
m_windowSize = newSize;
}
float
ConstantAudioCurve::processFloat(const float *R__, size_t)
ConstantAudioCurve::processFloat(const float *R__, int)
{
return 1.f;
}
double
ConstantAudioCurve::processDouble(const double *R__, size_t)
ConstantAudioCurve::processDouble(const double *R__, int)
{
return 1.0;
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -23,13 +23,11 @@ namespace RubberBand
class ConstantAudioCurve : public AudioCurveCalculator
{
public:
ConstantAudioCurve(size_t sampleRate, size_t windowSize);
ConstantAudioCurve(Parameters parameters);
virtual ~ConstantAudioCurve();
virtual void setWindowSize(size_t newSize);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, int increment);
virtual double processDouble(const double *R__ mag, int increment);
virtual void reset();
};

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -17,8 +17,9 @@
namespace RubberBand
{
HighFrequencyAudioCurve::HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurveCalculator(sampleRate, windowSize)
HighFrequencyAudioCurve::HighFrequencyAudioCurve(Parameters parameters) :
AudioCurveCalculator(parameters)
{
}
@@ -31,18 +32,12 @@ HighFrequencyAudioCurve::reset()
{
}
void
HighFrequencyAudioCurve::setWindowSize(size_t newSize)
{
m_windowSize = newSize;
}
float
HighFrequencyAudioCurve::processFloat(const float *R__ mag, size_t increment)
HighFrequencyAudioCurve::processFloat(const float *R__ mag, int increment)
{
float result = 0.0;
const int sz = m_windowSize / 2;
const int sz = m_lastPerceivedBin;
for (int n = 0; n <= sz; ++n) {
result = result + mag[n] * n;
@@ -52,11 +47,11 @@ HighFrequencyAudioCurve::processFloat(const float *R__ mag, size_t increment)
}
double
HighFrequencyAudioCurve::processDouble(const double *R__ mag, size_t increment)
HighFrequencyAudioCurve::processDouble(const double *R__ mag, int increment)
{
float result = 0.0;
const int sz = m_windowSize / 2;
const int sz = m_lastPerceivedBin;
for (int n = 0; n <= sz; ++n) {
result = result + mag[n] * n;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -23,15 +23,14 @@ namespace RubberBand
class HighFrequencyAudioCurve : public AudioCurveCalculator
{
public:
HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize);
HighFrequencyAudioCurve(Parameters parameters);
virtual ~HighFrequencyAudioCurve();
virtual void setWindowSize(size_t newSize);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, int increment);
virtual double processDouble(const double *R__ mag, int increment);
virtual void reset();
virtual const char *getUnit() const { return "Vbin"; }
};
}

95
src/dsp/MovingMedian.h Normal file
View File

@@ -0,0 +1,95 @@
/* -*- 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-2010 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 _MOVING_MEDIAN_H_
#define _MOVING_MEDIAN_H_
#include "SampleFilter.h"
#include "system/Allocators.h"
#include <algorithm>
namespace RubberBand
{
template <typename T>
class MovingMedian : public SampleFilter<T>
{
typedef SampleFilter<T> P;
public:
MovingMedian(int size, float percentile = 50.f) :
SampleFilter<T>(size),
m_frame(allocate_and_zero<T>(size)),
m_sorted(allocate_and_zero<T>(size)),
m_sortend(m_sorted + P::m_size - 1) {
setPercentile(percentile);
}
~MovingMedian() {
deallocate(m_frame);
deallocate(m_sorted);
}
void setPercentile(float p) {
m_index = int((P::m_size * p) / 100.f);
if (m_index >= P::m_size) m_index = P::m_size-1;
if (m_index < 0) m_index = 0;
}
void push(T value) {
drop(m_frame[0]);
v_move(m_frame, m_frame+1, P::m_size-1);
m_frame[P::m_size-1] = value;
put(value);
}
T get() const {
return m_sorted[m_index];
}
void reset() {
v_zero(m_frame, P::m_size);
v_zero(m_sorted, P::m_size);
}
private:
T *const m_frame;
T *const m_sorted;
T *const m_sortend;
int m_index;
void put(T value) {
// precondition: m_sorted contains m_size-1 values, packed at start
// postcondition: m_sorted contains m_size values, one of which is value
T *index = std::lower_bound(m_sorted, m_sortend, value);
v_move(index + 1, index, m_sortend - index);
*index = value;
}
void drop(T value) {
// precondition: m_sorted contains m_size values, one of which is value
// postcondition: m_sorted contains m_size-1 values, packed at start
T *index = std::lower_bound(m_sorted, m_sortend + 1, value);
assert(*index == value);
v_move(index, index + 1, m_sortend - index);
*m_sortend = T(0);
}
};
}
#endif

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -18,12 +18,13 @@
#include "system/VectorOps.h"
#include <cmath>
#include <iostream>
namespace RubberBand
{
PercussiveAudioCurve::PercussiveAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurveCalculator(sampleRate, windowSize)
PercussiveAudioCurve::PercussiveAudioCurve(Parameters parameters) :
AudioCurveCalculator(parameters)
{
m_prevMag = allocate_and_zero<double>(m_windowSize/2 + 1);
}
@@ -40,26 +41,29 @@ PercussiveAudioCurve::reset()
}
void
PercussiveAudioCurve::setWindowSize(size_t newSize)
PercussiveAudioCurve::setWindowSize(int newSize)
{
m_prevMag = reallocate(m_prevMag, m_windowSize, newSize);
m_windowSize = newSize;
AudioCurveCalculator::setWindowSize(newSize);
reset();
}
float
PercussiveAudioCurve::processFloat(const float *R__ mag, size_t increment)
PercussiveAudioCurve::processFloat(const float *R__ mag, int increment)
{
static float threshold = powf(10.f, 0.15f); // 3dB rise in square of magnitude
static float zeroThresh = powf(10.f, -8);
size_t count = 0;
size_t nonZeroCount = 0;
int count = 0;
int nonZeroCount = 0;
const int sz = m_windowSize / 2;
const int sz = m_lastPerceivedBin;
for (int n = 1; n <= sz; ++n) {
bool above = ((mag[n] / m_prevMag[n]) >= threshold);
float v = 0.f;
if (m_prevMag[n] > zeroThresh) v = mag[n] / m_prevMag[n];
else if (mag[n] > zeroThresh) v = threshold;
bool above = (v >= threshold);
if (above) ++count;
if (mag[n] > zeroThresh) ++nonZeroCount;
}
@@ -71,18 +75,21 @@ PercussiveAudioCurve::processFloat(const float *R__ mag, size_t increment)
}
double
PercussiveAudioCurve::processDouble(const double *R__ mag, size_t increment)
PercussiveAudioCurve::processDouble(const double *R__ mag, int increment)
{
static double threshold = powf(10., 0.15); // 3dB rise in square of magnitude
static double zeroThresh = powf(10., -8);
size_t count = 0;
size_t nonZeroCount = 0;
int count = 0;
int nonZeroCount = 0;
const int sz = m_windowSize / 2;
const int sz = m_lastPerceivedBin;
for (int n = 1; n <= sz; ++n) {
bool above = ((mag[n] / m_prevMag[n]) >= threshold);
double v = 0.0;
if (m_prevMag[n] > zeroThresh) v = mag[n] / m_prevMag[n];
else if (mag[n] > zeroThresh) v = threshold;
bool above = (v >= threshold);
if (above) ++count;
if (mag[n] > zeroThresh) ++nonZeroCount;
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -23,17 +23,18 @@ namespace RubberBand
class PercussiveAudioCurve : public AudioCurveCalculator
{
public:
PercussiveAudioCurve(size_t sampleRate, size_t windowSize);
PercussiveAudioCurve(Parameters parameters);
virtual ~PercussiveAudioCurve();
virtual void setWindowSize(size_t newSize);
virtual void setWindowSize(int newSize);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, int increment);
virtual double processDouble(const double *R__ mag, int increment);
virtual void reset();
virtual const char *getUnit() const { return "bin/total"; }
protected:
double *R__ m_prevMag;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -39,6 +39,12 @@ public:
int incount,
float ratio,
bool final) = 0;
virtual int resampleInterleaved(const float *const R__ in,
float *const R__ out,
int incount,
float ratio,
bool final) = 0;
virtual int getChannelCount() const = 0;
@@ -62,6 +68,12 @@ public:
float ratio,
bool final);
int resampleInterleaved(const float *const R__ in,
float *const R__ out,
int incount,
float ratio,
bool final = false);
int getChannelCount() const { return m_channels; }
void reset();
@@ -145,11 +157,7 @@ D_SRC::resample(const float *const R__ *const R__ in,
m_iout = reallocate<float>(m_iout, m_ioutsize, outcount * m_channels);
m_ioutsize = outcount * m_channels;
}
for (int i = 0; i < incount; ++i) {
for (int c = 0; c < m_channels; ++c) {
m_iin[i * m_channels + c] = in[c][i];
}
}
v_interleave(m_iin, in, m_channels, incount);
data.data_in = m_iin;
data.data_out = m_iout;
}
@@ -168,11 +176,39 @@ D_SRC::resample(const float *const R__ *const R__ in,
}
if (m_channels > 1) {
for (int i = 0; i < data.output_frames_gen; ++i) {
for (int c = 0; c < m_channels; ++c) {
out[c][i] = m_iout[i * m_channels + c];
}
}
v_deinterleave(out, m_iout, m_channels, data.output_frames_gen);
}
m_lastRatio = ratio;
return data.output_frames_gen;
}
int
D_SRC::resampleInterleaved(const float *const R__ in,
float *const R__ out,
int incount,
float ratio,
bool final)
{
SRC_DATA data;
int outcount = lrintf(ceilf(incount * ratio));
data.data_in = const_cast<float *>(in);
data.data_out = out;
data.input_frames = incount;
data.output_frames = outcount;
data.src_ratio = ratio;
data.end_of_input = (final ? 1 : 0);
int err = src_process(m_src, &data);
if (err) {
std::cerr << "Resampler::process: libsamplerate error: "
<< src_strerror(err) << std::endl;
throw Resampler::ImplementationError; //!!! of course, need to catch this!
}
m_lastRatio = ratio;
@@ -252,6 +288,15 @@ Resampler::resample(const float *const R__ *const R__ in,
return d->resample(in, out, incount, ratio, final);
}
int
Resampler::resampleInterleaved(const float *const R__ in,
float *const R__ out,
int incount, float ratio, bool final)
{
Profiler profiler("Resampler::resample");
return d->resampleInterleaved(in, out, incount, ratio, final);
}
int
Resampler::getChannelCount() const
{

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -37,12 +37,29 @@ public:
int debugLevel = 0);
~Resampler();
/**
* Resample the given multi-channel buffers, where incount is the
* number of frames in the input buffers. Returns the number of
* frames written to the output buffers.
*/
int resample(const float *const R__ *const R__ in,
float *const R__ *const R__ out,
int incount,
float ratio,
bool final = false);
/**
* Resample the given interleaved buffer, where incount is the
* number of frames in the input buffer (i.e. it has incount *
* getChannelCount() samples). Returns the number of frames
* written to the output buffer.
*/
int resampleInterleaved(const float *const R__ in,
float *const R__ out,
int incount,
float ratio,
bool final = false);
int getChannelCount() const;
void reset();

50
src/dsp/SampleFilter.h Normal file
View File

@@ -0,0 +1,50 @@
/* -*- 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-2010 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 _SAMPLE_FILTER_H_
#define _SAMPLE_FILTER_H_
#include <cassert>
namespace RubberBand
{
template <typename T>
class SampleFilter
{
public:
SampleFilter(int size) : m_size(size) {
assert(m_size > 0);
}
virtual ~SampleFilter() { }
int getSize() const { return m_size; }
virtual void push(T) = 0;
virtual T get() const = 0;
virtual void reset() = 0;
protected:
const int m_size;
private:
SampleFilter(const SampleFilter &);
SampleFilter &operator=(const SampleFilter &);
};
}
#endif

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -19,8 +19,9 @@
namespace RubberBand
{
SilentAudioCurve::SilentAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurveCalculator(sampleRate, windowSize)
SilentAudioCurve::SilentAudioCurve(Parameters parameters) :
AudioCurveCalculator(parameters)
{
}
@@ -33,16 +34,10 @@ SilentAudioCurve::reset()
{
}
void
SilentAudioCurve::setWindowSize(size_t newSize)
{
m_windowSize = newSize;
}
float
SilentAudioCurve::processFloat(const float *R__ mag, size_t)
SilentAudioCurve::processFloat(const float *R__ mag, int)
{
const int hs = m_windowSize / 2;
const int hs = m_lastPerceivedBin;
static float threshold = powf(10.f, -6);
for (int i = 0; i <= hs; ++i) {
@@ -53,9 +48,9 @@ SilentAudioCurve::processFloat(const float *R__ mag, size_t)
}
double
SilentAudioCurve::processDouble(const double *R__ mag, size_t)
SilentAudioCurve::processDouble(const double *R__ mag, int)
{
const int hs = m_windowSize / 2;
const int hs = m_lastPerceivedBin;
static double threshold = pow(10.0, -6);
for (int i = 0; i <= hs; ++i) {

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -23,14 +23,13 @@ namespace RubberBand
class SilentAudioCurve : public AudioCurveCalculator
{
public:
SilentAudioCurve(size_t sampleRate, size_t windowSize);
SilentAudioCurve(Parameters parameters);
virtual ~SilentAudioCurve();
virtual void setWindowSize(size_t newSize);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, int increment);
virtual double processDouble(const double *R__ mag, int increment);
virtual void reset();
virtual const char *getUnit() const { return "bool"; }
};
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -20,12 +20,13 @@
namespace RubberBand
{
SpectralDifferenceAudioCurve::SpectralDifferenceAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurveCalculator(sampleRate, windowSize)
SpectralDifferenceAudioCurve::SpectralDifferenceAudioCurve(Parameters parameters) :
AudioCurveCalculator(parameters)
{
m_mag = allocate<double>(m_windowSize/2 + 1);
m_tmpbuf = allocate<double>(m_windowSize/2 + 1);
v_zero(m_mag, m_windowSize/2 + 1);
m_mag = allocate<double>(m_lastPerceivedBin + 1);
m_tmpbuf = allocate<double>(m_lastPerceivedBin + 1);
v_zero(m_mag, m_lastPerceivedBin + 1);
}
SpectralDifferenceAudioCurve::~SpectralDifferenceAudioCurve()
@@ -37,26 +38,26 @@ SpectralDifferenceAudioCurve::~SpectralDifferenceAudioCurve()
void
SpectralDifferenceAudioCurve::reset()
{
v_zero(m_mag, m_windowSize/2 + 1);
v_zero(m_mag, m_lastPerceivedBin + 1);
}
void
SpectralDifferenceAudioCurve::setWindowSize(size_t newSize)
SpectralDifferenceAudioCurve::setWindowSize(int newSize)
{
deallocate(m_tmpbuf);
deallocate(m_mag);
m_windowSize = newSize;
m_mag = allocate<double>(m_windowSize/2 + 1);
m_tmpbuf = allocate<double>(m_windowSize/2 + 1);
AudioCurveCalculator::setWindowSize(newSize);
m_mag = allocate<double>(m_lastPerceivedBin + 1);
m_tmpbuf = allocate<double>(m_lastPerceivedBin + 1);
reset();
}
float
SpectralDifferenceAudioCurve::processFloat(const float *R__ mag, size_t increment)
SpectralDifferenceAudioCurve::processFloat(const float *R__ mag, int increment)
{
double result = 0.0;
const int hs1 = m_windowSize/2 + 1;
const int hs1 = m_lastPerceivedBin + 1;
v_convert(m_tmpbuf, mag, hs1);
v_square(m_tmpbuf, hs1);
@@ -73,11 +74,11 @@ SpectralDifferenceAudioCurve::processFloat(const float *R__ mag, size_t incremen
}
double
SpectralDifferenceAudioCurve::processDouble(const double *R__ mag, size_t increment)
SpectralDifferenceAudioCurve::processDouble(const double *R__ mag, int increment)
{
double result = 0.0;
const int hs1 = m_windowSize/2 + 1;
const int hs1 = m_lastPerceivedBin + 1;
v_convert(m_tmpbuf, mag, hs1);
v_square(m_tmpbuf, hs1);

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -24,15 +24,16 @@ namespace RubberBand
class SpectralDifferenceAudioCurve : public AudioCurveCalculator
{
public:
SpectralDifferenceAudioCurve(size_t sampleRate, size_t windowSize);
SpectralDifferenceAudioCurve(Parameters parameters);
virtual ~SpectralDifferenceAudioCurve();
virtual void setWindowSize(size_t newSize);
virtual void setWindowSize(int newSize);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, int increment);
virtual double processDouble(const double *R__ mag, int increment);
virtual void reset();
virtual const char *getUnit() const { return "V"; }
protected:
double *R__ m_mag;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2009 Chris Cannam.
Copyright 2007-2010 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
@@ -153,7 +153,7 @@ void Window<T>::encache()
m_cache = mult;
m_area = 0;
for (int i = 0; i < n; ++i) {
for (i = 0; i < n; ++i) {
m_area += m_cache[i];
}
m_area /= n;