1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/**********************************************************************
Audacity: A Digital Audio Editor
Audacity(R) is copyright (c) 1999-2012 Audacity Team.
License: GPL v2 or later. 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,
3, // Also best quality as modern PCs are probably fast enough.
// 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,
const 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();
}
|