* Some code rearrangement
* Threading fixes (corrections to condition usage) * Avoid a potential hang when faced with some peculiar stretch factors * More modular calls out to vectorizable functions * Solaris build fixes * Bump version number
This commit is contained in:
31
src/dsp/AudioCurveCalculator.cpp
Normal file
31
src/dsp/AudioCurveCalculator.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/* -*- 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-2009 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 "AudioCurveCalculator.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
AudioCurveCalculator::AudioCurveCalculator(size_t sampleRate, size_t windowSize) :
|
||||
m_sampleRate(sampleRate),
|
||||
m_windowSize(windowSize)
|
||||
{
|
||||
}
|
||||
|
||||
AudioCurveCalculator::~AudioCurveCalculator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
54
src/dsp/AudioCurveCalculator.h
Normal file
54
src/dsp/AudioCurveCalculator.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* -*- 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-2009 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 _AUDIO_CURVE_CALCULATOR_H_
|
||||
#define _AUDIO_CURVE_CALCULATOR_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#include "system/sysutils.h"
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
class AudioCurveCalculator
|
||||
{
|
||||
public:
|
||||
AudioCurveCalculator(size_t sampleRate, size_t windowSize);
|
||||
virtual ~AudioCurveCalculator();
|
||||
|
||||
size_t getSampleRate() const { return m_sampleRate; }
|
||||
size_t getWindowSize() const { return m_windowSize; }
|
||||
|
||||
virtual void setWindowSize(size_t newSize) = 0;
|
||||
|
||||
// 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 void reset() = 0;
|
||||
|
||||
protected:
|
||||
size_t m_sampleRate;
|
||||
size_t m_windowSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
53
src/dsp/ConstantAudioCurve.cpp
Normal file
53
src/dsp/ConstantAudioCurve.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/* -*- 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-2009 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(size_t sampleRate, size_t windowSize) :
|
||||
AudioCurveCalculator(sampleRate, windowSize)
|
||||
{
|
||||
}
|
||||
|
||||
ConstantAudioCurve::~ConstantAudioCurve()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConstantAudioCurve::reset()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConstantAudioCurve::setWindowSize(size_t newSize)
|
||||
{
|
||||
m_windowSize = newSize;
|
||||
}
|
||||
|
||||
float
|
||||
ConstantAudioCurve::processFloat(const float *R__, size_t)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
double
|
||||
ConstantAudioCurve::processDouble(const double *R__, size_t)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
38
src/dsp/ConstantAudioCurve.h
Normal file
38
src/dsp/ConstantAudioCurve.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2009 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(size_t sampleRate, size_t windowSize);
|
||||
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 void reset();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1404
src/dsp/FFT.cpp
Normal file
1404
src/dsp/FFT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
82
src/dsp/FFT.h
Normal file
82
src/dsp/FFT.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*- 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-2009 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 _RUBBERBAND_FFT_H_
|
||||
#define _RUBBERBAND_FFT_H_
|
||||
|
||||
#include "system/sysutils.h"
|
||||
|
||||
namespace RubberBand {
|
||||
|
||||
class FFTImpl;
|
||||
|
||||
/**
|
||||
* Provide the basic FFT computations we need, using one of a set of
|
||||
* candidate FFT implementations (depending on compile flags).
|
||||
*
|
||||
* Implements real->complex FFTs of power-of-two sizes only. Note
|
||||
* that only the first half of the output signal is returned (the
|
||||
* complex conjugates half is omitted), so the "complex" arrays need
|
||||
* room for size/2+1 elements.
|
||||
*
|
||||
* Not thread safe: use a separate instance per thread, or use a mutex.
|
||||
*/
|
||||
|
||||
//!!! it would be nice if we could redefine forwardMagnitude as forwardPower (i.e. square of magnitude)
|
||||
|
||||
class FFT
|
||||
{
|
||||
public:
|
||||
enum Exception { InvalidSize };
|
||||
|
||||
FFT(int size, int debugLevel = 0); // may throw InvalidSize
|
||||
~FFT();
|
||||
|
||||
void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut);
|
||||
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut);
|
||||
void forwardMagnitude(const double *R__ realIn, double *R__ magOut);
|
||||
|
||||
void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut);
|
||||
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut);
|
||||
void forwardMagnitude(const float *R__ realIn, float *R__ magOut);
|
||||
|
||||
void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut);
|
||||
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut);
|
||||
void inverseCepstral(const double *R__ magIn, double *R__ cepOut);
|
||||
|
||||
void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut);
|
||||
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut);
|
||||
void inverseCepstral(const float *R__ magIn, float *R__ cepOut);
|
||||
|
||||
// Calling one or both of these is optional -- if neither is
|
||||
// called, the first call to a forward or inverse method will call
|
||||
// init(). You only need call these if you don't want to risk
|
||||
// expensive allocations etc happening in forward or inverse.
|
||||
void initFloat();
|
||||
void initDouble();
|
||||
|
||||
float *getFloatTimeBuffer();
|
||||
double *getDoubleTimeBuffer();
|
||||
|
||||
static void tune();
|
||||
|
||||
protected:
|
||||
FFTImpl *d;
|
||||
static int m_method;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
69
src/dsp/HighFrequencyAudioCurve.cpp
Normal file
69
src/dsp/HighFrequencyAudioCurve.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2009 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(size_t sampleRate, size_t windowSize) :
|
||||
AudioCurveCalculator(sampleRate, windowSize)
|
||||
{
|
||||
}
|
||||
|
||||
HighFrequencyAudioCurve::~HighFrequencyAudioCurve()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HighFrequencyAudioCurve::reset()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HighFrequencyAudioCurve::setWindowSize(size_t newSize)
|
||||
{
|
||||
m_windowSize = newSize;
|
||||
}
|
||||
|
||||
float
|
||||
HighFrequencyAudioCurve::processFloat(const float *R__ mag, size_t increment)
|
||||
{
|
||||
float result = 0.0;
|
||||
|
||||
const int sz = m_windowSize / 2;
|
||||
|
||||
for (int n = 0; n <= sz; ++n) {
|
||||
result = result + mag[n] * n;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double
|
||||
HighFrequencyAudioCurve::processDouble(const double *R__ mag, size_t increment)
|
||||
{
|
||||
float result = 0.0;
|
||||
|
||||
const int sz = m_windowSize / 2;
|
||||
|
||||
for (int n = 0; n <= sz; ++n) {
|
||||
result = result + mag[n] * n;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
39
src/dsp/HighFrequencyAudioCurve.h
Normal file
39
src/dsp/HighFrequencyAudioCurve.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* -*- 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-2009 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(size_t sampleRate, size_t windowSize);
|
||||
|
||||
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 void reset();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
98
src/dsp/PercussiveAudioCurve.cpp
Normal file
98
src/dsp/PercussiveAudioCurve.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/* -*- 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-2009 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>
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
PercussiveAudioCurve::PercussiveAudioCurve(size_t sampleRate, size_t windowSize) :
|
||||
AudioCurveCalculator(sampleRate, windowSize)
|
||||
{
|
||||
m_prevMag = allocate_and_zero<double>(m_windowSize/2 + 1);
|
||||
}
|
||||
|
||||
PercussiveAudioCurve::~PercussiveAudioCurve()
|
||||
{
|
||||
deallocate(m_prevMag);
|
||||
}
|
||||
|
||||
void
|
||||
PercussiveAudioCurve::reset()
|
||||
{
|
||||
v_zero(m_prevMag, m_windowSize/2 + 1);
|
||||
}
|
||||
|
||||
void
|
||||
PercussiveAudioCurve::setWindowSize(size_t newSize)
|
||||
{
|
||||
m_prevMag = reallocate(m_prevMag, m_windowSize, newSize);
|
||||
m_windowSize = newSize;
|
||||
reset();
|
||||
}
|
||||
|
||||
float
|
||||
PercussiveAudioCurve::processFloat(const float *R__ mag, size_t 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;
|
||||
|
||||
const int sz = m_windowSize / 2;
|
||||
|
||||
for (int n = 1; n <= sz; ++n) {
|
||||
bool above = ((mag[n] / m_prevMag[n]) >= 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, size_t 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;
|
||||
|
||||
const int sz = m_windowSize / 2;
|
||||
|
||||
for (int n = 1; n <= sz; ++n) {
|
||||
bool above = ((mag[n] / m_prevMag[n]) >= 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
44
src/dsp/PercussiveAudioCurve.h
Normal file
44
src/dsp/PercussiveAudioCurve.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- 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-2009 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(size_t sampleRate, size_t windowSize);
|
||||
|
||||
virtual ~PercussiveAudioCurve();
|
||||
|
||||
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 void reset();
|
||||
|
||||
protected:
|
||||
double *R__ m_prevMag;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
267
src/dsp/Resampler.cpp
Normal file
267
src/dsp/Resampler.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
/* -*- 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-2009 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 "Resampler.h"
|
||||
#include "base/Profiler.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "system/Allocators.h"
|
||||
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
|
||||
|
||||
namespace RubberBand {
|
||||
|
||||
class ResamplerImpl
|
||||
{
|
||||
public:
|
||||
virtual ~ResamplerImpl() { }
|
||||
|
||||
virtual int resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final) = 0;
|
||||
|
||||
virtual int getChannelCount() const = 0;
|
||||
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
namespace Resamplers {
|
||||
|
||||
|
||||
|
||||
class D_SRC : public ResamplerImpl
|
||||
{
|
||||
public:
|
||||
D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int m_debugLevel);
|
||||
~D_SRC();
|
||||
|
||||
int resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final);
|
||||
|
||||
int getChannelCount() const { return m_channels; }
|
||||
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
SRC_STATE *m_src;
|
||||
float *m_iin;
|
||||
float *m_iout;
|
||||
float m_lastRatio;
|
||||
int m_channels;
|
||||
int m_iinsize;
|
||||
int m_ioutsize;
|
||||
int m_debugLevel;
|
||||
};
|
||||
|
||||
D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int debugLevel) :
|
||||
m_src(0),
|
||||
m_iin(0),
|
||||
m_iout(0),
|
||||
m_lastRatio(1.f),
|
||||
m_channels(channels),
|
||||
m_iinsize(0),
|
||||
m_ioutsize(0),
|
||||
m_debugLevel(debugLevel)
|
||||
{
|
||||
if (m_debugLevel > 0) {
|
||||
std::cerr << "Resampler::Resampler: using libsamplerate implementation"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int err = 0;
|
||||
m_src = src_new(quality == Resampler::Best ? SRC_SINC_BEST_QUALITY :
|
||||
quality == Resampler::Fastest ? SRC_LINEAR :
|
||||
SRC_SINC_FASTEST,
|
||||
channels, &err);
|
||||
|
||||
if (err) {
|
||||
std::cerr << "Resampler::Resampler: failed to create libsamplerate resampler: "
|
||||
<< src_strerror(err) << std::endl;
|
||||
throw Resampler::ImplementationError; //!!! of course, need to catch this!
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
D_SRC::~D_SRC()
|
||||
{
|
||||
src_delete(m_src);
|
||||
deallocate<float>(m_iin);
|
||||
deallocate<float>(m_iout);
|
||||
}
|
||||
|
||||
int
|
||||
D_SRC::resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final)
|
||||
{
|
||||
SRC_DATA data;
|
||||
|
||||
int outcount = lrintf(ceilf(incount * ratio));
|
||||
|
||||
if (m_channels == 1) {
|
||||
data.data_in = const_cast<float *>(*in); //!!!???
|
||||
data.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;
|
||||
}
|
||||
for (int i = 0; i < incount; ++i) {
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
m_iin[i * m_channels + c] = in[c][i];
|
||||
}
|
||||
}
|
||||
data.data_in = m_iin;
|
||||
data.data_out = m_iout;
|
||||
}
|
||||
|
||||
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!
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_lastRatio = ratio;
|
||||
|
||||
return data.output_frames_gen;
|
||||
}
|
||||
|
||||
void
|
||||
D_SRC::reset()
|
||||
{
|
||||
src_reset(m_src);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} /* end namespace Resamplers */
|
||||
|
||||
Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
int maxBufferSize, int debugLevel)
|
||||
{
|
||||
m_method = -1;
|
||||
|
||||
switch (quality) {
|
||||
|
||||
case Resampler::Best:
|
||||
m_method = 1;
|
||||
break;
|
||||
|
||||
case Resampler::FastestTolerable:
|
||||
m_method = 1;
|
||||
break;
|
||||
|
||||
case Resampler::Fastest:
|
||||
m_method = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_method == -1) {
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize << "): No implementation available!"
|
||||
<< std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (m_method) {
|
||||
case 0:
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize << "): No implementation available!"
|
||||
<< std::endl;
|
||||
abort();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
d = new Resamplers::D_SRC(quality, channels, maxBufferSize, debugLevel);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize << "): No implementation available!"
|
||||
<< std::endl;
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Resampler::~Resampler()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
int
|
||||
Resampler::resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount, float ratio, bool final)
|
||||
{
|
||||
Profiler profiler("Resampler::resample");
|
||||
return d->resample(in, out, incount, ratio, final);
|
||||
}
|
||||
|
||||
int
|
||||
Resampler::getChannelCount() const
|
||||
{
|
||||
return d->getChannelCount();
|
||||
}
|
||||
|
||||
void
|
||||
Resampler::reset()
|
||||
{
|
||||
d->reset();
|
||||
}
|
||||
|
||||
}
|
||||
57
src/dsp/Resampler.h
Normal file
57
src/dsp/Resampler.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* -*- 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-2009 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 _RUBBERBAND_RESAMPLER_H_
|
||||
#define _RUBBERBAND_RESAMPLER_H_
|
||||
|
||||
#include "system/sysutils.h"
|
||||
|
||||
namespace RubberBand {
|
||||
|
||||
class ResamplerImpl;
|
||||
|
||||
class Resampler
|
||||
{
|
||||
public:
|
||||
enum Quality { Best, FastestTolerable, Fastest };
|
||||
enum Exception { ImplementationError };
|
||||
|
||||
/**
|
||||
* Construct a resampler with the given quality level and channel
|
||||
* count. maxBufferSize gives a bound on the maximum incount size
|
||||
* that may be passed to the resample function before the
|
||||
* resampler needs to reallocate its internal buffers.
|
||||
*/
|
||||
Resampler(Quality quality, int channels, int maxBufferSize = 0,
|
||||
int debugLevel = 0);
|
||||
~Resampler();
|
||||
|
||||
int resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final = false);
|
||||
|
||||
int getChannelCount() const;
|
||||
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
ResamplerImpl *d;
|
||||
int m_method;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
69
src/dsp/SilentAudioCurve.cpp
Normal file
69
src/dsp/SilentAudioCurve.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2009 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version. See the file
|
||||
COPYING included with this distribution for more information.
|
||||
*/
|
||||
|
||||
#include "SilentAudioCurve.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace RubberBand
|
||||
{
|
||||
|
||||
SilentAudioCurve::SilentAudioCurve(size_t sampleRate, size_t windowSize) :
|
||||
AudioCurveCalculator(sampleRate, windowSize)
|
||||
{
|
||||
}
|
||||
|
||||
SilentAudioCurve::~SilentAudioCurve()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SilentAudioCurve::reset()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SilentAudioCurve::setWindowSize(size_t newSize)
|
||||
{
|
||||
m_windowSize = newSize;
|
||||
}
|
||||
|
||||
float
|
||||
SilentAudioCurve::processFloat(const float *R__ mag, size_t)
|
||||
{
|
||||
const int hs = m_windowSize / 2;
|
||||
static float threshold = powf(10.f, -6);
|
||||
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
if (mag[i] > threshold) return 0.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
double
|
||||
SilentAudioCurve::processDouble(const double *R__ mag, size_t)
|
||||
{
|
||||
const int hs = m_windowSize / 2;
|
||||
static double threshold = pow(10.0, -6);
|
||||
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
if (mag[i] > threshold) return 0.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
38
src/dsp/SilentAudioCurve.h
Normal file
38
src/dsp/SilentAudioCurve.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2009 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(size_t sampleRate, size_t windowSize);
|
||||
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 void reset();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
97
src/dsp/SpectralDifferenceAudioCurve.cpp
Normal file
97
src/dsp/SpectralDifferenceAudioCurve.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/* -*- 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-2009 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(size_t sampleRate, size_t windowSize) :
|
||||
AudioCurveCalculator(sampleRate, windowSize)
|
||||
{
|
||||
m_mag = allocate<double>(m_windowSize/2 + 1);
|
||||
m_tmpbuf = allocate<double>(m_windowSize/2 + 1);
|
||||
v_zero(m_mag, m_windowSize/2 + 1);
|
||||
}
|
||||
|
||||
SpectralDifferenceAudioCurve::~SpectralDifferenceAudioCurve()
|
||||
{
|
||||
deallocate(m_mag);
|
||||
deallocate(m_tmpbuf);
|
||||
}
|
||||
|
||||
void
|
||||
SpectralDifferenceAudioCurve::reset()
|
||||
{
|
||||
v_zero(m_mag, m_windowSize/2 + 1);
|
||||
}
|
||||
|
||||
void
|
||||
SpectralDifferenceAudioCurve::setWindowSize(size_t 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);
|
||||
reset();
|
||||
}
|
||||
|
||||
float
|
||||
SpectralDifferenceAudioCurve::processFloat(const float *R__ mag, size_t increment)
|
||||
{
|
||||
double result = 0.0;
|
||||
|
||||
const int hs1 = m_windowSize/2 + 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, size_t increment)
|
||||
{
|
||||
double result = 0.0;
|
||||
|
||||
const int hs1 = m_windowSize/2 + 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
44
src/dsp/SpectralDifferenceAudioCurve.h
Normal file
44
src/dsp/SpectralDifferenceAudioCurve.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- 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-2009 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(size_t sampleRate, size_t windowSize);
|
||||
|
||||
virtual ~SpectralDifferenceAudioCurve();
|
||||
|
||||
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 void reset();
|
||||
|
||||
protected:
|
||||
double *R__ m_mag;
|
||||
double *R__ m_tmpbuf;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
17
src/dsp/Window.cpp
Normal file
17
src/dsp/Window.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
/* -*- 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"
|
||||
|
||||
|
||||
176
src/dsp/Window.h
Normal file
176
src/dsp/Window.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/* -*- 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-2009 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 _RUBBERBAND_WINDOW_H_
|
||||
#define _RUBBERBAND_WINDOW_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
|
||||
#include "system/sysutils.h"
|
||||
#include "system/VectorOps.h"
|
||||
|
||||
namespace RubberBand {
|
||||
|
||||
enum WindowType {
|
||||
RectangularWindow,
|
||||
BartlettWindow,
|
||||
HammingWindow,
|
||||
HanningWindow,
|
||||
BlackmanWindow,
|
||||
GaussianWindow,
|
||||
ParzenWindow,
|
||||
NuttallWindow,
|
||||
BlackmanHarrisWindow
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a windower of the given type.
|
||||
*/
|
||||
Window(WindowType type, int size) : m_type(type), m_size(size) { encache(); }
|
||||
Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); }
|
||||
Window &operator=(const Window &w) {
|
||||
if (&w == this) return *this;
|
||||
m_type = w.m_type;
|
||||
m_size = w.m_size;
|
||||
encache();
|
||||
return *this;
|
||||
}
|
||||
virtual ~Window() { delete[] m_cache; }
|
||||
|
||||
inline void cut(T *const R__ block) const {
|
||||
v_multiply(block, m_cache, m_size);
|
||||
}
|
||||
|
||||
inline void cut(const T *const R__ src, T *const R__ dst) const {
|
||||
v_multiply(dst, src, m_cache, m_size);
|
||||
}
|
||||
|
||||
inline void add(T *const R__ dst, T scale) const {
|
||||
v_add_with_gain(dst, m_cache, m_size, scale);
|
||||
}
|
||||
|
||||
inline T getArea() const { return m_area; }
|
||||
inline T getValue(int i) const { return m_cache[i]; }
|
||||
|
||||
inline WindowType getType() const { return m_type; }
|
||||
inline int getSize() const { return m_size; }
|
||||
|
||||
protected:
|
||||
WindowType m_type;
|
||||
int m_size;
|
||||
T *R__ m_cache;
|
||||
T m_area;
|
||||
|
||||
void encache();
|
||||
void cosinewin(T *, T, T, T, T);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void Window<T>::encache()
|
||||
{
|
||||
int n = int(m_size);
|
||||
T *mult = new T[n];
|
||||
int i;
|
||||
for (i = 0; i < n; ++i) mult[i] = 1.0;
|
||||
|
||||
switch (m_type) {
|
||||
|
||||
case RectangularWindow:
|
||||
for (i = 0; i < n; ++i) {
|
||||
mult[i] *= 0.5;
|
||||
}
|
||||
break;
|
||||
|
||||
case BartlettWindow:
|
||||
for (i = 0; i < n/2; ++i) {
|
||||
mult[i] *= (i / T(n/2));
|
||||
mult[i + n/2] *= (1.0 - (i / T(n/2)));
|
||||
}
|
||||
break;
|
||||
|
||||
case HammingWindow:
|
||||
cosinewin(mult, 0.54, 0.46, 0.0, 0.0);
|
||||
break;
|
||||
|
||||
case HanningWindow:
|
||||
cosinewin(mult, 0.50, 0.50, 0.0, 0.0);
|
||||
break;
|
||||
|
||||
case BlackmanWindow:
|
||||
cosinewin(mult, 0.42, 0.50, 0.08, 0.0);
|
||||
break;
|
||||
|
||||
case GaussianWindow:
|
||||
for (i = 0; i < n; ++i) {
|
||||
mult[i] *= pow(2, - pow((i - (n-1)/2.0) / ((n-1)/2.0 / 3), 2));
|
||||
}
|
||||
break;
|
||||
|
||||
case ParzenWindow:
|
||||
{
|
||||
int N = n-1;
|
||||
for (i = 0; i < N/4; ++i) {
|
||||
T m = 2 * pow(1.0 - (T(N)/2 - i) / (T(N)/2), 3);
|
||||
mult[i] *= m;
|
||||
mult[N-i] *= m;
|
||||
}
|
||||
for (i = N/4; i <= N/2; ++i) {
|
||||
int wn = i - N/2;
|
||||
T m = 1.0 - 6 * pow(wn / (T(N)/2), 2) * (1.0 - abs(wn) / (T(N)/2));
|
||||
mult[i] *= m;
|
||||
mult[N-i] *= m;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NuttallWindow:
|
||||
cosinewin(mult, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
|
||||
break;
|
||||
|
||||
case BlackmanHarrisWindow:
|
||||
cosinewin(mult, 0.35875, 0.48829, 0.14128, 0.01168);
|
||||
break;
|
||||
}
|
||||
|
||||
m_cache = mult;
|
||||
|
||||
m_area = 0;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
m_area += m_cache[i];
|
||||
}
|
||||
m_area /= n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
|
||||
{
|
||||
int n = int(m_size);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
mult[i] *= (a0
|
||||
- a1 * cos(2 * M_PI * i / n)
|
||||
+ a2 * cos(4 * M_PI * i / n)
|
||||
- a3 * cos(6 * M_PI * i / n));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user