mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-20 17:41:13 +02:00
Resample into lib-math; Audacity doesn't use libsoxr directly
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
A library of mathematical utilities and manipulation of samples
|
||||
]]#
|
||||
|
||||
addlib( libsoxr soxr SOXR YES YES "soxr >= 0.1.1" )
|
||||
|
||||
set( SOURCES
|
||||
Dither.cpp
|
||||
Dither.h
|
||||
@@ -13,6 +15,8 @@ set( SOURCES
|
||||
Matrix.h
|
||||
RealFFTf.cpp
|
||||
RealFFTf.h
|
||||
Resample.cpp
|
||||
Resample.h
|
||||
SampleCount.cpp
|
||||
SampleCount.h
|
||||
SampleFormat.cpp
|
||||
@@ -22,6 +26,7 @@ set( SOURCES
|
||||
float_cast.h
|
||||
)
|
||||
set( LIBRARIES
|
||||
libsoxr
|
||||
lib-preferences-interface
|
||||
PRIVATE
|
||||
wxBase
|
||||
|
120
libraries/lib-math/Resample.cpp
Normal file
120
libraries/lib-math/Resample.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
Audacity(R) is copyright (c) 1999-2012 Audacity Team.
|
||||
License: GPL v2. See License.txt.
|
||||
|
||||
Resample.cpp
|
||||
Dominic Mazzoni, Rob Sykes, Vaughan Johnson
|
||||
|
||||
******************************************************************//**
|
||||
|
||||
\class Resample
|
||||
\brief Interface to libsoxr.
|
||||
|
||||
This class abstracts the interface to different resampling libraries:
|
||||
|
||||
libsoxr, written by Rob Sykes. LGPL.
|
||||
|
||||
Since Audacity always does resampling on mono streams that are
|
||||
contiguous in memory, this class doesn't support multiple channels
|
||||
or some of the other optional features of some of these resamplers.
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#include "Resample.h"
|
||||
#include "Prefs.h"
|
||||
#include "Internat.h"
|
||||
#include "ComponentInterface.h"
|
||||
|
||||
#include <soxr.h>
|
||||
|
||||
Resample::Resample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
||||
{
|
||||
this->SetMethod(useBestMethod);
|
||||
soxr_quality_spec_t q_spec;
|
||||
if (dMinFactor == dMaxFactor)
|
||||
{
|
||||
mbWantConstRateResampling = true; // constant rate resampling
|
||||
q_spec = soxr_quality_spec("\0\1\4\6"[mMethod], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbWantConstRateResampling = false; // variable rate resampling
|
||||
q_spec = soxr_quality_spec(SOXR_HQ, SOXR_VR);
|
||||
}
|
||||
mHandle.reset(soxr_create(1, dMinFactor, 1, 0, 0, &q_spec, 0));
|
||||
}
|
||||
|
||||
Resample::~Resample()
|
||||
{
|
||||
}
|
||||
|
||||
//////////
|
||||
static const std::initializer_list<EnumValueSymbol> methodNames{
|
||||
{ wxT("LowQuality"), XO("Low Quality (Fastest)") },
|
||||
{ wxT("MediumQuality"), XO("Medium Quality") },
|
||||
{ wxT("HighQuality"), XO("High Quality") },
|
||||
{ wxT("BestQuality"), XO("Best Quality (Slowest)") }
|
||||
};
|
||||
|
||||
static auto intChoicesMethod = {
|
||||
0, 1, 2, 3
|
||||
};
|
||||
|
||||
EnumSetting< int > Resample::FastMethodSetting{
|
||||
wxT("/Quality/LibsoxrSampleRateConverterChoice"),
|
||||
methodNames,
|
||||
1, // Medium Quality
|
||||
|
||||
// for migrating old preferences:
|
||||
intChoicesMethod,
|
||||
wxT("/Quality/LibsoxrSampleRateConverter")
|
||||
};
|
||||
|
||||
EnumSetting< int > Resample::BestMethodSetting
|
||||
{
|
||||
wxT("/Quality/LibsoxrHQSampleRateConverterChoice"),
|
||||
methodNames,
|
||||
3, // Best Quality,
|
||||
|
||||
// for migrating old preferences:
|
||||
intChoicesMethod,
|
||||
wxT("/Quality/LibsoxrHQSampleRateConverter")
|
||||
};
|
||||
|
||||
//////////
|
||||
std::pair<size_t, size_t>
|
||||
Resample::Process(double factor,
|
||||
float *inBuffer,
|
||||
size_t inBufferLen,
|
||||
bool lastFlag,
|
||||
float *outBuffer,
|
||||
size_t outBufferLen)
|
||||
{
|
||||
size_t idone, odone;
|
||||
if (mbWantConstRateResampling)
|
||||
{
|
||||
soxr_process(mHandle.get(),
|
||||
inBuffer , (lastFlag? ~inBufferLen : inBufferLen), &idone,
|
||||
outBuffer, outBufferLen, &odone);
|
||||
}
|
||||
else
|
||||
{
|
||||
soxr_set_io_ratio(mHandle.get(), 1/factor, 0);
|
||||
|
||||
inBufferLen = lastFlag? ~inBufferLen : inBufferLen;
|
||||
soxr_process(mHandle.get(),
|
||||
inBuffer , inBufferLen , &idone,
|
||||
outBuffer, outBufferLen, &odone);
|
||||
}
|
||||
return { idone, odone };
|
||||
}
|
||||
|
||||
void Resample::SetMethod(const bool useBestMethod)
|
||||
{
|
||||
if (useBestMethod)
|
||||
mMethod = BestMethodSetting.ReadEnum();
|
||||
else
|
||||
mMethod = FastMethodSetting.ReadEnum();
|
||||
}
|
84
libraries/lib-math/Resample.h
Normal file
84
libraries/lib-math/Resample.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
Audacity(R) is copyright (c) 1999-2012 Audacity Team.
|
||||
License: GPL v2. See License.txt.
|
||||
|
||||
Resample.cpp
|
||||
Dominic Mazzoni, Rob Sykes, Vaughan Johnson
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_RESAMPLE_H__
|
||||
#define __AUDACITY_RESAMPLE_H__
|
||||
|
||||
#include "SampleFormat.h"
|
||||
|
||||
template< typename Enum > class EnumSetting;
|
||||
|
||||
struct soxr;
|
||||
extern "C" void soxr_delete(soxr*);
|
||||
struct soxr_deleter {
|
||||
void operator () (soxr *p) const { if (p) soxr_delete(p); }
|
||||
};
|
||||
using soxrHandle = std::unique_ptr<soxr, soxr_deleter>;
|
||||
|
||||
class MATH_API Resample final
|
||||
{
|
||||
public:
|
||||
/// Resamplers may have more than one method, offering a
|
||||
/// tradeoff between speed and quality.
|
||||
/// Audacity identifies two methods out of all of the choices:
|
||||
/// a Fast method intended for real-time audio I/O, and a Best
|
||||
/// method intended for mixing and exporting.
|
||||
//
|
||||
/// The first parameter lets you select either the best method or
|
||||
/// the fast method.
|
||||
// dMinFactor and dMaxFactor specify the range of factors for variable-rate resampling.
|
||||
// For constant-rate, pass the same value for both.
|
||||
Resample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor);
|
||||
~Resample();
|
||||
|
||||
static EnumSetting< int > FastMethodSetting;
|
||||
static EnumSetting< int > BestMethodSetting;
|
||||
|
||||
/** @brief Main processing function. Resamples from the input buffer to the
|
||||
* output buffer.
|
||||
*
|
||||
* Reads samples from the input buffer, and writes samples to the output
|
||||
* buffer. Stops when either is exhausted, or we reach a convenient block
|
||||
* end, unless lastFlag is set to force emptying the input buffer.
|
||||
* The number of input samples used is returned in inBufferUsed, and the
|
||||
* number of output samples generated is the return value of the function.
|
||||
* This function may do nothing if you don't pass a large enough output
|
||||
* buffer (i.e. there is no where to put a full block of output data)
|
||||
@param factor The scaling factor to resample by.
|
||||
@param inBuffer Buffer of input samples to be processed (mono)
|
||||
@param inBufferLen Length of the input buffer, in samples.
|
||||
@param lastFlag Flag to indicate this is the last lot of input samples and
|
||||
the buffer needs to be emptied out into the rate converter.
|
||||
(unless lastFlag is true, we don't guarantee to process all the samples in
|
||||
the input this time, we may leave some for next time)
|
||||
@param outBuffer Buffer to write output (converted) samples to.
|
||||
@param outBufferLen How big outBuffer is.
|
||||
@return Number of input samples consumed, and number of output samples
|
||||
created by this call
|
||||
*/
|
||||
std::pair<size_t, size_t>
|
||||
Process(double factor,
|
||||
float *inBuffer,
|
||||
size_t inBufferLen,
|
||||
bool lastFlag,
|
||||
float *outBuffer,
|
||||
size_t outBufferLen);
|
||||
|
||||
protected:
|
||||
void SetMethod(const bool useBestMethod);
|
||||
|
||||
protected:
|
||||
int mMethod; // resampler-specific enum for resampling method
|
||||
soxrHandle mHandle; // constant-rate or variable-rate resampler (XOR per instance)
|
||||
bool mbWantConstRateResampling;
|
||||
};
|
||||
|
||||
#endif // __AUDACITY_RESAMPLE_H__
|
Reference in New Issue
Block a user