Update to new combined build
This commit is contained in:
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#include "AudioCurveCalculator.h"
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_CURVE_CALCULATOR_H_
|
||||
@@ -93,6 +102,13 @@ public:
|
||||
*/
|
||||
virtual double processDouble(const double *R__ mag, int increment) = 0;
|
||||
|
||||
/**
|
||||
* Obtain a confidence for the curve value (if applicable). A
|
||||
* value of 1.0 indicates perfect confidence in the curve
|
||||
* calculation, 0.0 indicates none.
|
||||
*/
|
||||
virtual double getConfidence() const { return 1.0; }
|
||||
|
||||
/**
|
||||
* Reset the calculator, forgetting the history of the audio input
|
||||
* so far.
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
/* -*- 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-2011 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_type(CompoundDetector),
|
||||
m_lastHf(0.0),
|
||||
m_lastResult(0.0),
|
||||
m_risingCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
CompoundAudioCurve::~CompoundAudioCurve()
|
||||
{
|
||||
delete m_hfFilter;
|
||||
delete m_hfDerivFilter;
|
||||
}
|
||||
|
||||
void
|
||||
CompoundAudioCurve::setType(Type type)
|
||||
{
|
||||
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::setFftSize(int newSize)
|
||||
{
|
||||
m_percussive.setFftSize(newSize);
|
||||
m_hf.setFftSize(newSize);
|
||||
m_fftSize = 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) {
|
||||
return percussive;
|
||||
}
|
||||
|
||||
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 (result < m_lastResult) {
|
||||
if (m_risingCount > 3 && m_lastResult > 0) rv = 0.5;
|
||||
m_risingCount = 0;
|
||||
} else {
|
||||
m_risingCount ++;
|
||||
}
|
||||
|
||||
if (m_type == CompoundDetector) {
|
||||
if (percussive > 0.35 && percussive > rv) {
|
||||
rv = percussive;
|
||||
}
|
||||
}
|
||||
|
||||
m_lastResult = result;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/* -*- 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-2011 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); // default is CompoundDetector
|
||||
|
||||
virtual void setFftSize(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
|
||||
@@ -1,48 +0,0 @@
|
||||
/* -*- 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-2011 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 "ConstantAudioCurve.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
|
||||
ConstantAudioCurve::ConstantAudioCurve(Parameters parameters) :
|
||||
AudioCurveCalculator(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
ConstantAudioCurve::~ConstantAudioCurve()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConstantAudioCurve::reset()
|
||||
{
|
||||
}
|
||||
|
||||
float
|
||||
ConstantAudioCurve::processFloat(const float *R__, int)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
double
|
||||
ConstantAudioCurve::processDouble(const double *R__, int)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/* -*- 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-2011 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 _CONSTANT_AUDIO_CURVE_H_
|
||||
#define _CONSTANT_AUDIO_CURVE_H_
|
||||
|
||||
#include "AudioCurveCalculator.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
class ConstantAudioCurve : public AudioCurveCalculator
|
||||
{
|
||||
public:
|
||||
ConstantAudioCurve(Parameters parameters);
|
||||
virtual ~ConstantAudioCurve();
|
||||
|
||||
virtual float processFloat(const float *R__ mag, int increment);
|
||||
virtual double processDouble(const double *R__ mag, int increment);
|
||||
virtual void reset();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
2342
src/dsp/FFT.cpp
2342
src/dsp/FFT.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#ifndef _RUBBERBAND_FFT_H_
|
||||
@@ -17,6 +26,9 @@
|
||||
|
||||
#include "system/sysutils.h"
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace RubberBand {
|
||||
|
||||
class FFTImpl;
|
||||
@@ -41,7 +53,7 @@ class FFTImpl;
|
||||
class FFT
|
||||
{
|
||||
public:
|
||||
enum Exception { InvalidSize };
|
||||
enum Exception { InvalidSize, InvalidImplementation, InternalError };
|
||||
|
||||
FFT(int size, int debugLevel = 0); // may throw InvalidSize
|
||||
~FFT();
|
||||
@@ -73,11 +85,36 @@ public:
|
||||
void initFloat();
|
||||
void initDouble();
|
||||
|
||||
static void tune();
|
||||
enum Precision {
|
||||
SinglePrecision = 0x1,
|
||||
DoublePrecision = 0x2
|
||||
};
|
||||
typedef int Precisions;
|
||||
|
||||
/**
|
||||
* Return the OR of all precisions supported by this
|
||||
* implementation. All of the functions (float and double) are
|
||||
* available regardless of the supported implementations, but they
|
||||
* will be calculated at the proper precision only if it is
|
||||
* available. (So float functions will be calculated using doubles
|
||||
* and then truncated if single-precision is unavailable, and
|
||||
* double functions will use single-precision arithmetic if double
|
||||
* is unavailable.)
|
||||
*/
|
||||
Precisions getSupportedPrecisions() const;
|
||||
|
||||
static std::set<std::string> getImplementations();
|
||||
static std::string getDefaultImplementation();
|
||||
static void setDefaultImplementation(std::string);
|
||||
|
||||
#ifdef FFT_MEASUREMENT
|
||||
static std::string tune();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
FFTImpl *d;
|
||||
static int m_method;
|
||||
static std::string m_implementation;
|
||||
static void pickDefaultImplementation();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/* -*- 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-2011 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 "HighFrequencyAudioCurve.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
|
||||
HighFrequencyAudioCurve::HighFrequencyAudioCurve(Parameters parameters) :
|
||||
AudioCurveCalculator(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
HighFrequencyAudioCurve::~HighFrequencyAudioCurve()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HighFrequencyAudioCurve::reset()
|
||||
{
|
||||
}
|
||||
|
||||
float
|
||||
HighFrequencyAudioCurve::processFloat(const float *R__ mag, int increment)
|
||||
{
|
||||
float result = 0.0;
|
||||
|
||||
const int sz = m_lastPerceivedBin;
|
||||
|
||||
for (int n = 0; n <= sz; ++n) {
|
||||
result = result + mag[n] * n;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double
|
||||
HighFrequencyAudioCurve::processDouble(const double *R__ mag, int increment)
|
||||
{
|
||||
float result = 0.0;
|
||||
|
||||
const int sz = m_lastPerceivedBin;
|
||||
|
||||
for (int n = 0; n <= sz; ++n) {
|
||||
result = result + mag[n] * n;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/* -*- 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-2011 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 _HIGHFREQUENCY_AUDIO_CURVE_H_
|
||||
#define _HIGHFREQUENCY_AUDIO_CURVE_H_
|
||||
|
||||
#include "AudioCurveCalculator.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
class HighFrequencyAudioCurve : public AudioCurveCalculator
|
||||
{
|
||||
public:
|
||||
HighFrequencyAudioCurve(Parameters parameters);
|
||||
|
||||
virtual ~HighFrequencyAudioCurve();
|
||||
|
||||
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"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#ifndef _MOVING_MEDIAN_H_
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/* -*- 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-2011 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 "PercussiveAudioCurve.h"
|
||||
|
||||
#include "system/Allocators.h"
|
||||
#include "system/VectorOps.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
|
||||
PercussiveAudioCurve::PercussiveAudioCurve(Parameters parameters) :
|
||||
AudioCurveCalculator(parameters)
|
||||
{
|
||||
m_prevMag = allocate_and_zero<double>(m_fftSize/2 + 1);
|
||||
}
|
||||
|
||||
PercussiveAudioCurve::~PercussiveAudioCurve()
|
||||
{
|
||||
deallocate(m_prevMag);
|
||||
}
|
||||
|
||||
void
|
||||
PercussiveAudioCurve::reset()
|
||||
{
|
||||
v_zero(m_prevMag, m_fftSize/2 + 1);
|
||||
}
|
||||
|
||||
void
|
||||
PercussiveAudioCurve::setFftSize(int newSize)
|
||||
{
|
||||
m_prevMag = reallocate(m_prevMag, m_fftSize/2 + 1, newSize/2 + 1);
|
||||
AudioCurveCalculator::setFftSize(newSize);
|
||||
reset();
|
||||
}
|
||||
|
||||
float
|
||||
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);
|
||||
|
||||
int count = 0;
|
||||
int nonZeroCount = 0;
|
||||
|
||||
const int sz = m_lastPerceivedBin;
|
||||
|
||||
for (int n = 1; n <= sz; ++n) {
|
||||
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;
|
||||
}
|
||||
|
||||
v_convert(m_prevMag, mag, sz + 1);
|
||||
|
||||
if (nonZeroCount == 0) return 0;
|
||||
else return float(count) / float(nonZeroCount);
|
||||
}
|
||||
|
||||
double
|
||||
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);
|
||||
|
||||
int count = 0;
|
||||
int nonZeroCount = 0;
|
||||
|
||||
const int sz = m_lastPerceivedBin;
|
||||
|
||||
for (int n = 1; n <= sz; ++n) {
|
||||
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;
|
||||
}
|
||||
|
||||
v_copy(m_prevMag, mag, sz + 1);
|
||||
|
||||
if (nonZeroCount == 0) return 0;
|
||||
else return double(count) / double(nonZeroCount);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/* -*- 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-2011 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 _PERCUSSIVE_AUDIO_CURVE_H_
|
||||
#define _PERCUSSIVE_AUDIO_CURVE_H_
|
||||
|
||||
#include "AudioCurveCalculator.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
class PercussiveAudioCurve : public AudioCurveCalculator
|
||||
{
|
||||
public:
|
||||
PercussiveAudioCurve(Parameters parameters);
|
||||
|
||||
virtual ~PercussiveAudioCurve();
|
||||
|
||||
virtual void setFftSize(int newSize);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#include "Resampler.h"
|
||||
@@ -22,6 +31,11 @@
|
||||
|
||||
#include "system/Allocators.h"
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#include <ipps.h>
|
||||
#include <ippsr.h>
|
||||
#include <ippac.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
#include <samplerate.h>
|
||||
@@ -31,12 +45,19 @@
|
||||
#include <libresample.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPEEX
|
||||
#include "speex/speex_resampler.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_IPP
|
||||
#ifndef HAVE_LIBSAMPLERATE
|
||||
#ifndef HAVE_LIBRESAMPLE
|
||||
#ifndef USE_SPEEX
|
||||
#error No resampler implementation selected!
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace RubberBand {
|
||||
|
||||
@@ -64,6 +85,360 @@ public:
|
||||
|
||||
namespace Resamplers {
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
|
||||
class D_IPP : public ResamplerImpl
|
||||
{
|
||||
public:
|
||||
D_IPP(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int debugLevel);
|
||||
~D_IPP();
|
||||
|
||||
int resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
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();
|
||||
|
||||
protected:
|
||||
IppsResamplingPolyphase_32f **m_state;
|
||||
float **m_inbuf;
|
||||
size_t m_inbufsz;
|
||||
float **m_outbuf;
|
||||
size_t m_outbufsz;
|
||||
int m_bufsize;
|
||||
int m_channels;
|
||||
int m_window;
|
||||
float m_factor;
|
||||
int m_history;
|
||||
int *m_lastread;
|
||||
double *m_time;
|
||||
int m_debugLevel;
|
||||
|
||||
void setBufSize(int);
|
||||
};
|
||||
|
||||
D_IPP::D_IPP(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int debugLevel) :
|
||||
m_state(0),
|
||||
m_channels(channels),
|
||||
m_debugLevel(debugLevel)
|
||||
{
|
||||
if (m_debugLevel > 0) {
|
||||
std::cerr << "Resampler::Resampler: using IPP implementation"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int nStep;
|
||||
IppHintAlgorithm hint;
|
||||
|
||||
switch (quality) {
|
||||
|
||||
case Resampler::Best:
|
||||
m_window = 64;
|
||||
nStep = 80;
|
||||
hint = ippAlgHintAccurate;
|
||||
break;
|
||||
|
||||
case Resampler::FastestTolerable:
|
||||
// m_window = 48;
|
||||
nStep = 16;
|
||||
m_window = 16;
|
||||
// nStep = 8;
|
||||
hint = ippAlgHintFast;
|
||||
break;
|
||||
|
||||
case Resampler::Fastest:
|
||||
m_window = 24;
|
||||
nStep = 64;
|
||||
hint = ippAlgHintFast;
|
||||
break;
|
||||
}
|
||||
|
||||
m_factor = 8; // initial upper bound on m_ratio, may be amended later
|
||||
m_history = int(m_window * 0.5 * std::max(1.0, 1.0 / m_factor)) + 1;
|
||||
|
||||
m_state = new IppsResamplingPolyphase_32f *[m_channels];
|
||||
|
||||
m_lastread = new int[m_channels];
|
||||
m_time = new double[m_channels];
|
||||
|
||||
m_bufsize = maxBufferSize + m_history;
|
||||
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "bufsize = " << m_bufsize << ", window = " << m_window << ", nStep = " << nStep << ", history = " << m_history << std::endl;
|
||||
}
|
||||
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
ippsResamplePolyphaseInitAlloc_32f(&m_state[c],
|
||||
float(m_window),
|
||||
nStep,
|
||||
0.95f,
|
||||
9.0f,
|
||||
hint);
|
||||
m_lastread[c] = m_history;
|
||||
m_time[c] = m_history;
|
||||
}
|
||||
|
||||
m_inbufsz = m_bufsize + m_history + 2;
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "inbuf allocating " << m_bufsize << " + " << m_history << " + 2 = " << m_inbufsz << std::endl;
|
||||
}
|
||||
|
||||
m_outbufsz = lrintf(ceil((m_bufsize - m_history) * m_factor + 2));
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "outbuf allocating (" << m_bufsize << " - " << m_history << ") * " << m_factor << " + 2 = " << m_outbufsz << std::endl;
|
||||
}
|
||||
|
||||
m_inbuf = allocate_and_zero_channels<float>(m_channels, m_inbufsz);
|
||||
m_outbuf = allocate_and_zero_channels<float>(m_channels, m_outbufsz);
|
||||
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "Resampler init done" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
D_IPP::~D_IPP()
|
||||
{
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
ippsResamplePolyphaseFree_32f(m_state[c]);
|
||||
}
|
||||
|
||||
deallocate_channels(m_inbuf, m_channels);
|
||||
deallocate_channels(m_outbuf, m_channels);
|
||||
|
||||
delete[] m_lastread;
|
||||
delete[] m_time;
|
||||
delete[] m_state;
|
||||
}
|
||||
|
||||
void
|
||||
D_IPP::setBufSize(int sz)
|
||||
{
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "resize bufsize " << m_bufsize << " -> ";
|
||||
}
|
||||
|
||||
m_bufsize = sz;
|
||||
|
||||
std::cerr << m_bufsize << std::endl;
|
||||
|
||||
int n1 = m_bufsize + m_history + 2;
|
||||
int n2 = lrintf(ceil((m_bufsize - m_history) * m_factor + 2));
|
||||
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "(outbufsize = " << n2 << ")" << std::endl;
|
||||
}
|
||||
|
||||
m_inbuf = reallocate_and_zero_extend_channels
|
||||
(m_inbuf, m_channels, m_inbufsz, m_channels, n1);
|
||||
|
||||
m_outbuf = reallocate_and_zero_extend_channels
|
||||
(m_outbuf, m_channels, m_outbufsz, m_channels, n2);
|
||||
|
||||
m_inbufsz = n1;
|
||||
m_outbufsz = n2;
|
||||
}
|
||||
|
||||
int
|
||||
D_IPP::resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final)
|
||||
{
|
||||
int outcount = 0;
|
||||
|
||||
if (ratio > m_factor) {
|
||||
m_factor = ratio;
|
||||
m_history = int(m_window * 0.5 * std::max(1.0, 1.0 / m_factor)) + 1;
|
||||
}
|
||||
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
if (m_lastread[c] + incount + m_history > m_bufsize) {
|
||||
setBufSize(m_lastread[c] + incount + m_history);
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
|
||||
for (int i = 0; i < incount; ++i) {
|
||||
m_inbuf[c][m_lastread[c] + i] = in[c][i];
|
||||
}
|
||||
m_lastread[c] += incount;
|
||||
|
||||
ippsResamplePolyphase_32f(m_state[c],
|
||||
m_inbuf[c],
|
||||
m_lastread[c] - m_history - int(m_time[c]),
|
||||
m_outbuf[c],
|
||||
ratio,
|
||||
0.97f,
|
||||
&m_time[c],
|
||||
&outcount);
|
||||
|
||||
v_copy(out[c], m_outbuf[c], outcount);
|
||||
|
||||
ippsMove_32f(m_inbuf[c] + int(m_time[c]) - m_history,
|
||||
m_inbuf[c],
|
||||
m_lastread[c] + m_history - int(m_time[c]));
|
||||
|
||||
m_lastread[c] -= int(m_time[c]) - m_history;
|
||||
m_time[c] -= int(m_time[c]) - m_history;
|
||||
|
||||
if (final) {
|
||||
|
||||
// Looks like this actually produces too many samples
|
||||
// (additionalcount is a few samples too large).
|
||||
|
||||
// Also, we aren't likely to have enough space in the
|
||||
// output buffer as the caller won't have allowed for
|
||||
// all the samples we're retrieving here.
|
||||
|
||||
// What to do?
|
||||
|
||||
int additionalcount = 0;
|
||||
|
||||
for (int i = 0; i < m_history; ++i) {
|
||||
m_inbuf[c][m_lastread[c] + i] = 0.f;
|
||||
}
|
||||
|
||||
ippsResamplePolyphase_32f(m_state[c],
|
||||
m_inbuf[c],
|
||||
m_lastread[c] - int(m_time[c]),
|
||||
m_outbuf[c],
|
||||
ratio,
|
||||
0.97f,
|
||||
&m_time[c],
|
||||
&additionalcount);
|
||||
|
||||
if (m_debugLevel > 2) {
|
||||
std::cerr << "incount = " << incount << ", outcount = " << outcount << ", additionalcount = " << additionalcount << ", sum " << outcount + additionalcount << ", est space = " << lrintf(ceil(incount * ratio)) <<std::endl;
|
||||
}
|
||||
|
||||
v_copy(out[c] + outcount, m_outbuf[c], additionalcount);
|
||||
|
||||
outcount += additionalcount;
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
ippsThreshold_32f_I(out[c], outcount, 1.f, ippCmpGreater);
|
||||
ippsThreshold_32f_I(out[c], outcount, -1.f, ippCmpLess);
|
||||
}
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
int
|
||||
D_IPP::resampleInterleaved(const float *const R__ in,
|
||||
float *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final)
|
||||
{
|
||||
int outcount = 0;
|
||||
|
||||
if (ratio > m_factor) {
|
||||
m_factor = ratio;
|
||||
m_history = int(m_window * 0.5 * std::max(1.0, 1.0 / m_factor)) + 1;
|
||||
}
|
||||
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
if (m_lastread[c] + incount + m_history > m_bufsize) {
|
||||
setBufSize(m_lastread[c] + incount + m_history);
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
|
||||
for (int i = 0; i < incount; ++i) {
|
||||
m_inbuf[c][m_lastread[c] + i] = in[i * m_channels + c];
|
||||
}
|
||||
m_lastread[c] += incount;
|
||||
|
||||
ippsResamplePolyphase_32f(m_state[c],
|
||||
m_inbuf[c],
|
||||
m_lastread[c] - m_history - int(m_time[c]),
|
||||
m_outbuf[c],
|
||||
ratio,
|
||||
0.97f,
|
||||
&m_time[c],
|
||||
&outcount);
|
||||
|
||||
ippsMove_32f(m_inbuf[c] + int(m_time[c]) - m_history,
|
||||
m_inbuf[c],
|
||||
m_lastread[c] + m_history - int(m_time[c]));
|
||||
|
||||
m_lastread[c] -= int(m_time[c]) - m_history;
|
||||
m_time[c] -= int(m_time[c]) - m_history;
|
||||
}
|
||||
|
||||
v_interleave(out, m_outbuf, m_channels, outcount);
|
||||
|
||||
if (final) {
|
||||
|
||||
// Looks like this actually produces too many samples
|
||||
// (additionalcount is a few samples too large).
|
||||
|
||||
// Also, we aren't likely to have enough space in the
|
||||
// output buffer as the caller won't have allowed for
|
||||
// all the samples we're retrieving here.
|
||||
|
||||
// What to do?
|
||||
|
||||
int additionalcount = 0;
|
||||
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
|
||||
for (int i = 0; i < m_history; ++i) {
|
||||
m_inbuf[c][m_lastread[c] + i] = 0.f;
|
||||
}
|
||||
|
||||
ippsResamplePolyphase_32f(m_state[c],
|
||||
m_inbuf[c],
|
||||
m_lastread[c] - int(m_time[c]),
|
||||
m_outbuf[c],
|
||||
ratio,
|
||||
0.97f,
|
||||
&m_time[c],
|
||||
&additionalcount);
|
||||
|
||||
if (m_debugLevel > 2) {
|
||||
std::cerr << "incount = " << incount << ", outcount = " << outcount << ", additionalcount = " << additionalcount << ", sum " << outcount + additionalcount << ", est space = " << lrintf(ceil(incount * ratio)) <<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
v_interleave(out + (outcount * m_channels),
|
||||
m_outbuf,
|
||||
m_channels,
|
||||
additionalcount);
|
||||
|
||||
outcount += additionalcount;
|
||||
}
|
||||
|
||||
ippsThreshold_32f_I(out, outcount * m_channels, 1.f, ippCmpGreater);
|
||||
ippsThreshold_32f_I(out, outcount * m_channels, -1.f, ippCmpLess);
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
void
|
||||
D_IPP::reset()
|
||||
{
|
||||
//!!!
|
||||
}
|
||||
|
||||
#endif /* HAVE_IPP */
|
||||
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
|
||||
@@ -126,7 +501,9 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
if (err) {
|
||||
std::cerr << "Resampler::Resampler: failed to create libsamplerate resampler: "
|
||||
<< src_strerror(err) << std::endl;
|
||||
#ifndef NO_EXCEPTIONS
|
||||
throw Resampler::ImplementationError;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (maxBufferSize > 0 && m_channels > 1) {
|
||||
@@ -184,7 +561,9 @@ D_SRC::resample(const float *const R__ *const R__ in,
|
||||
if (err) {
|
||||
std::cerr << "Resampler::process: libsamplerate error: "
|
||||
<< src_strerror(err) << std::endl;
|
||||
#ifndef NO_EXCEPTIONS
|
||||
throw Resampler::ImplementationError;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m_channels > 1) {
|
||||
@@ -220,7 +599,9 @@ D_SRC::resampleInterleaved(const float *const R__ in,
|
||||
if (err) {
|
||||
std::cerr << "Resampler::process: libsamplerate error: "
|
||||
<< src_strerror(err) << std::endl;
|
||||
#ifndef NO_EXCEPTIONS
|
||||
throw Resampler::ImplementationError;
|
||||
#endif
|
||||
}
|
||||
|
||||
m_lastRatio = ratio;
|
||||
@@ -424,6 +805,234 @@ D_Resample::reset()
|
||||
|
||||
#endif /* HAVE_LIBRESAMPLE */
|
||||
|
||||
#ifdef USE_SPEEX
|
||||
|
||||
class D_Speex : public ResamplerImpl
|
||||
{
|
||||
public:
|
||||
D_Speex(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int debugLevel);
|
||||
~D_Speex();
|
||||
|
||||
int resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
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();
|
||||
|
||||
protected:
|
||||
SpeexResamplerState *m_resampler;
|
||||
float *m_iin;
|
||||
float *m_iout;
|
||||
int m_channels;
|
||||
int m_iinsize;
|
||||
int m_ioutsize;
|
||||
float m_lastratio;
|
||||
bool m_initial;
|
||||
int m_debugLevel;
|
||||
|
||||
void setRatio(float);
|
||||
};
|
||||
|
||||
D_Speex::D_Speex(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int debugLevel) :
|
||||
m_resampler(0),
|
||||
m_iin(0),
|
||||
m_iout(0),
|
||||
m_channels(channels),
|
||||
m_iinsize(0),
|
||||
m_ioutsize(0),
|
||||
m_lastratio(1),
|
||||
m_initial(true),
|
||||
m_debugLevel(debugLevel)
|
||||
{
|
||||
int q = (quality == Resampler::Best ? 10 :
|
||||
quality == Resampler::Fastest ? 0 : 4);
|
||||
|
||||
if (m_debugLevel > 0) {
|
||||
std::cerr << "Resampler::Resampler: using Speex implementation with q = "
|
||||
<< q
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int err = 0;
|
||||
m_resampler = speex_resampler_init_frac(m_channels,
|
||||
1, 1,
|
||||
48000, 48000, // irrelevant
|
||||
q,
|
||||
&err);
|
||||
|
||||
|
||||
if (err) {
|
||||
std::cerr << "Resampler::Resampler: failed to create Speex resampler"
|
||||
<< std::endl;
|
||||
#ifndef NO_EXCEPTIONS
|
||||
throw Resampler::ImplementationError;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (maxBufferSize > 0 && m_channels > 1) {
|
||||
m_iinsize = maxBufferSize * m_channels;
|
||||
m_ioutsize = maxBufferSize * m_channels * 2;
|
||||
m_iin = allocate<float>(m_iinsize);
|
||||
m_iout = allocate<float>(m_ioutsize);
|
||||
}
|
||||
}
|
||||
|
||||
D_Speex::~D_Speex()
|
||||
{
|
||||
speex_resampler_destroy(m_resampler);
|
||||
deallocate<float>(m_iin);
|
||||
deallocate<float>(m_iout);
|
||||
}
|
||||
|
||||
void
|
||||
D_Speex::setRatio(float ratio)
|
||||
{
|
||||
// Speex wants a ratio of two unsigned integers, not a single
|
||||
// float. Let's do that.
|
||||
|
||||
unsigned int big = 272408136U;
|
||||
unsigned int denom = 1, num = 1;
|
||||
|
||||
if (ratio < 1.f) {
|
||||
denom = big;
|
||||
double dnum = double(big) * double(ratio);
|
||||
num = (unsigned int)dnum;
|
||||
} else if (ratio > 1.f) {
|
||||
num = big;
|
||||
double ddenom = double(big) / double(ratio);
|
||||
denom = (unsigned int)ddenom;
|
||||
}
|
||||
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "D_Speex: Desired ratio " << ratio << ", requesting ratio "
|
||||
<< num << "/" << denom << " = " << float(double(num)/double(denom))
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int err = speex_resampler_set_rate_frac
|
||||
(m_resampler, denom, num, 48000, 48000);
|
||||
//!!! check err
|
||||
|
||||
speex_resampler_get_ratio(m_resampler, &denom, &num);
|
||||
|
||||
if (m_debugLevel > 1) {
|
||||
std::cerr << "D_Speex: Desired ratio " << ratio << ", got ratio "
|
||||
<< num << "/" << denom << " = " << float(double(num)/double(denom))
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
m_lastratio = ratio;
|
||||
|
||||
if (m_initial) {
|
||||
speex_resampler_skip_zeros(m_resampler);
|
||||
m_initial = false;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
D_Speex::resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final)
|
||||
{
|
||||
if (ratio != m_lastratio) {
|
||||
setRatio(ratio);
|
||||
}
|
||||
|
||||
unsigned int uincount = incount;
|
||||
unsigned int outcount = lrintf(ceilf(incount * ratio)); //!!! inexact now
|
||||
|
||||
float *data_in, *data_out;
|
||||
|
||||
if (m_channels == 1) {
|
||||
data_in = const_cast<float *>(*in);
|
||||
data_out = *out;
|
||||
} else {
|
||||
if (incount * m_channels > m_iinsize) {
|
||||
m_iin = reallocate<float>(m_iin, m_iinsize, incount * m_channels);
|
||||
m_iinsize = incount * m_channels;
|
||||
}
|
||||
if (outcount * m_channels > m_ioutsize) {
|
||||
m_iout = reallocate<float>(m_iout, m_ioutsize, outcount * m_channels);
|
||||
m_ioutsize = outcount * m_channels;
|
||||
}
|
||||
v_interleave(m_iin, in, m_channels, incount);
|
||||
data_in = m_iin;
|
||||
data_out = m_iout;
|
||||
}
|
||||
|
||||
int err = speex_resampler_process_interleaved_float(m_resampler,
|
||||
data_in,
|
||||
&uincount,
|
||||
data_out,
|
||||
&outcount);
|
||||
|
||||
// if (incount != int(uincount)) {
|
||||
// std::cerr << "Resampler: NOTE: Consumed " << uincount
|
||||
// << " of " << incount << " frames" << std::endl;
|
||||
// }
|
||||
|
||||
// if (outcount != lrintf(ceilf(incount * ratio))) {
|
||||
// std::cerr << "Resampler: NOTE: Obtained " << outcount
|
||||
// << " of " << lrintf(ceilf(incount * ratio)) << " frames"
|
||||
// << std::endl;
|
||||
// }
|
||||
|
||||
//!!! check err, respond appropriately
|
||||
|
||||
if (m_channels > 1) {
|
||||
v_deinterleave(out, m_iout, m_channels, outcount);
|
||||
}
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
int
|
||||
D_Speex::resampleInterleaved(const float *const R__ in,
|
||||
float *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final)
|
||||
{
|
||||
if (ratio != m_lastratio) {
|
||||
setRatio(ratio);
|
||||
}
|
||||
|
||||
unsigned int uincount = incount;
|
||||
unsigned int outcount = lrintf(ceilf(incount * ratio)); //!!! inexact now
|
||||
|
||||
float *data_in = const_cast<float *>(in);
|
||||
float *data_out = out;
|
||||
|
||||
int err = speex_resampler_process_interleaved_float(m_resampler,
|
||||
data_in,
|
||||
&uincount,
|
||||
data_out,
|
||||
&outcount);
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
void
|
||||
D_Speex::reset()
|
||||
{
|
||||
speex_resampler_reset_mem(m_resampler);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} /* end namespace Resamplers */
|
||||
|
||||
@@ -435,6 +1044,12 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
switch (quality) {
|
||||
|
||||
case Resampler::Best:
|
||||
#ifdef HAVE_IPP
|
||||
m_method = 0;
|
||||
#endif
|
||||
#ifdef USE_SPEEX
|
||||
m_method = 2;
|
||||
#endif
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
m_method = 3;
|
||||
#endif
|
||||
@@ -444,18 +1059,30 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
break;
|
||||
|
||||
case Resampler::FastestTolerable:
|
||||
#ifdef HAVE_IPP
|
||||
m_method = 0;
|
||||
#endif
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
m_method = 3;
|
||||
#endif
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
m_method = 1;
|
||||
#endif
|
||||
#ifdef USE_SPEEX
|
||||
m_method = 2;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Resampler::Fastest:
|
||||
#ifdef HAVE_IPP
|
||||
m_method = 0;
|
||||
#endif
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
m_method = 3;
|
||||
#endif
|
||||
#ifdef USE_SPEEX
|
||||
m_method = 2;
|
||||
#endif
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
m_method = 1;
|
||||
#endif
|
||||
@@ -471,10 +1098,14 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
|
||||
switch (m_method) {
|
||||
case 0:
|
||||
#ifdef HAVE_IPP
|
||||
d = new Resamplers::D_IPP(quality, channels, maxBufferSize, debugLevel);
|
||||
#else
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize << "): No implementation available!"
|
||||
<< std::endl;
|
||||
abort();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@@ -489,10 +1120,14 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
break;
|
||||
|
||||
case 2:
|
||||
#ifdef USE_SPEEX
|
||||
d = new Resamplers::D_Speex(quality, channels, maxBufferSize, debugLevel);
|
||||
#else
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize << "): No implementation available!"
|
||||
<< std::endl;
|
||||
abort();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#ifndef _RUBBERBAND_RESAMPLER_H_
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#ifndef _SAMPLE_FILTER_H_
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/* -*- 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-2011 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(Parameters parameters) :
|
||||
AudioCurveCalculator(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
SilentAudioCurve::~SilentAudioCurve()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SilentAudioCurve::reset()
|
||||
{
|
||||
}
|
||||
|
||||
float
|
||||
SilentAudioCurve::processFloat(const float *R__ mag, int)
|
||||
{
|
||||
const int hs = m_lastPerceivedBin;
|
||||
static float threshold = powf(10.f, -6);
|
||||
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
if (mag[i] > threshold) return 0.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
double
|
||||
SilentAudioCurve::processDouble(const double *R__ mag, int)
|
||||
{
|
||||
const int hs = m_lastPerceivedBin;
|
||||
static double threshold = pow(10.0, -6);
|
||||
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
if (mag[i] > threshold) return 0.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* -*- 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-2011 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 "AudioCurveCalculator.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
class SilentAudioCurve : public AudioCurveCalculator
|
||||
{
|
||||
public:
|
||||
SilentAudioCurve(Parameters parameters);
|
||||
virtual ~SilentAudioCurve();
|
||||
|
||||
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"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#ifndef _RUBBERBAND_SINC_WINDOW_H_
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/* -*- 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-2011 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 "SpectralDifferenceAudioCurve.h"
|
||||
|
||||
#include "system/Allocators.h"
|
||||
#include "system/VectorOps.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
|
||||
SpectralDifferenceAudioCurve::SpectralDifferenceAudioCurve(Parameters parameters) :
|
||||
AudioCurveCalculator(parameters)
|
||||
{
|
||||
m_mag = allocate<double>(m_lastPerceivedBin + 1);
|
||||
m_tmpbuf = allocate<double>(m_lastPerceivedBin + 1);
|
||||
v_zero(m_mag, m_lastPerceivedBin + 1);
|
||||
}
|
||||
|
||||
SpectralDifferenceAudioCurve::~SpectralDifferenceAudioCurve()
|
||||
{
|
||||
deallocate(m_mag);
|
||||
deallocate(m_tmpbuf);
|
||||
}
|
||||
|
||||
void
|
||||
SpectralDifferenceAudioCurve::reset()
|
||||
{
|
||||
v_zero(m_mag, m_lastPerceivedBin + 1);
|
||||
}
|
||||
|
||||
void
|
||||
SpectralDifferenceAudioCurve::setFftSize(int newSize)
|
||||
{
|
||||
deallocate(m_tmpbuf);
|
||||
deallocate(m_mag);
|
||||
AudioCurveCalculator::setFftSize(newSize);
|
||||
m_mag = allocate<double>(m_lastPerceivedBin + 1);
|
||||
m_tmpbuf = allocate<double>(m_lastPerceivedBin + 1);
|
||||
reset();
|
||||
}
|
||||
|
||||
float
|
||||
SpectralDifferenceAudioCurve::processFloat(const float *R__ mag, int increment)
|
||||
{
|
||||
double result = 0.0;
|
||||
|
||||
const int hs1 = m_lastPerceivedBin + 1;
|
||||
|
||||
v_convert(m_tmpbuf, mag, hs1);
|
||||
v_square(m_tmpbuf, hs1);
|
||||
v_subtract(m_mag, m_tmpbuf, hs1);
|
||||
v_abs(m_mag, hs1);
|
||||
v_sqrt(m_mag, hs1);
|
||||
|
||||
for (int i = 0; i < hs1; ++i) {
|
||||
result += m_mag[i];
|
||||
}
|
||||
|
||||
v_copy(m_mag, m_tmpbuf, hs1);
|
||||
return result;
|
||||
}
|
||||
|
||||
double
|
||||
SpectralDifferenceAudioCurve::processDouble(const double *R__ mag, int increment)
|
||||
{
|
||||
double result = 0.0;
|
||||
|
||||
const int hs1 = m_lastPerceivedBin + 1;
|
||||
|
||||
v_convert(m_tmpbuf, mag, hs1);
|
||||
v_square(m_tmpbuf, hs1);
|
||||
v_subtract(m_mag, m_tmpbuf, hs1);
|
||||
v_abs(m_mag, hs1);
|
||||
v_sqrt(m_mag, hs1);
|
||||
|
||||
for (int i = 0; i < hs1; ++i) {
|
||||
result += m_mag[i];
|
||||
}
|
||||
|
||||
v_copy(m_mag, m_tmpbuf, hs1);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/* -*- 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-2011 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 _SPECTRALDIFFERENCE_AUDIO_CURVE_H_
|
||||
#define _SPECTRALDIFFERENCE_AUDIO_CURVE_H_
|
||||
|
||||
#include "AudioCurveCalculator.h"
|
||||
#include "Window.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
class SpectralDifferenceAudioCurve : public AudioCurveCalculator
|
||||
{
|
||||
public:
|
||||
SpectralDifferenceAudioCurve(Parameters parameters);
|
||||
|
||||
virtual ~SpectralDifferenceAudioCurve();
|
||||
|
||||
virtual void setFftSize(int newSize);
|
||||
|
||||
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;
|
||||
double *R__ m_tmpbuf;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,17 +0,0 @@
|
||||
/* -*- 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 "Window.h"
|
||||
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
Rubber Band Library
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
Copyright 2007-2012 Particular Programs Ltd.
|
||||
|
||||
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.
|
||||
|
||||
Alternatively, if you have a valid commercial licence for the
|
||||
Rubber Band Library obtained by agreement with the copyright
|
||||
holders, you may redistribute and/or modify it under the terms
|
||||
described in that licence.
|
||||
|
||||
If you wish to distribute code using the Rubber Band Library
|
||||
under terms other than those of the GNU General Public License,
|
||||
you must obtain a valid commercial licence before doing so.
|
||||
*/
|
||||
|
||||
#ifndef _RUBBERBAND_WINDOW_H_
|
||||
|
||||
Reference in New Issue
Block a user