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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
164
src/dsp/CompoundAudioCurve.cpp
Normal file
164
src/dsp/CompoundAudioCurve.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
65
src/dsp/CompoundAudioCurve.h
Normal file
65
src/dsp/CompoundAudioCurve.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
95
src/dsp/MovingMedian.h
Normal 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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
50
src/dsp/SampleFilter.h
Normal 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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user