mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Go back to simpler architecture for Resample class, now that libsoxr is proven for variable rate resampling.
This commit is contained in:
parent
51e0391b7d
commit
030d2450a8
@ -127,13 +127,13 @@ void AboutDialog::CreateCreditsList()
|
|||||||
AddCredit(wxT("LAME"), roleLibrary);
|
AddCredit(wxT("LAME"), roleLibrary);
|
||||||
AddCredit(wxT("libmad"), roleLibrary);
|
AddCredit(wxT("libmad"), roleLibrary);
|
||||||
#if USE_LIBRESAMPLE
|
#if USE_LIBRESAMPLE
|
||||||
AddCredit(wxT("libresample"), roleLibrary);
|
AddCredit(wxT("libresample, by Dominic Mazzoni and Julius Smith"), roleLibrary);
|
||||||
#endif
|
#endif
|
||||||
#if USE_LIBSAMPLERATE
|
#if USE_LIBSAMPLERATE
|
||||||
AddCredit(wxT("libsamplerate, by Erik de Castro Lopo"), roleLibrary);
|
AddCredit(wxT("libsamplerate, by Erik de Castro Lopo"), roleLibrary);
|
||||||
#endif
|
#endif
|
||||||
#if USE_LIBSOXR
|
#if USE_LIBSOXR
|
||||||
AddCredit(wxT("libsoxr"), roleLibrary);
|
AddCredit(wxT("libsoxr, by Rob Sykes"), roleLibrary);
|
||||||
#endif
|
#endif
|
||||||
AddCredit(wxT("libsndfile"), roleLibrary);
|
AddCredit(wxT("libsndfile"), roleLibrary);
|
||||||
AddCredit(wxT("Nyquist"), roleLibrary);
|
AddCredit(wxT("Nyquist"), roleLibrary);
|
||||||
|
@ -1322,18 +1322,18 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mCaptureBuffers = new RingBuffer* [mCaptureTracks.GetCount()];
|
mCaptureBuffers = new RingBuffer* [mCaptureTracks.GetCount()];
|
||||||
mResample = new ConstRateResample* [mCaptureTracks.GetCount()];
|
mResample = new Resample* [mCaptureTracks.GetCount()];
|
||||||
mFactor = sampleRate / mRate;
|
mFactor = sampleRate / mRate;
|
||||||
|
|
||||||
// Set everything to zero in case we have to delete these due to a memory exception.
|
// Set everything to zero in case we have to delete these due to a memory exception.
|
||||||
memset(mCaptureBuffers, 0, sizeof(RingBuffer*)*mCaptureTracks.GetCount());
|
memset(mCaptureBuffers, 0, sizeof(RingBuffer*)*mCaptureTracks.GetCount());
|
||||||
memset(mResample, 0, sizeof(ConstRateResample*)*mCaptureTracks.GetCount());
|
memset(mResample, 0, sizeof(Resample*)*mCaptureTracks.GetCount());
|
||||||
|
|
||||||
for( unsigned int i = 0; i < mCaptureTracks.GetCount(); i++ )
|
for( unsigned int i = 0; i < mCaptureTracks.GetCount(); i++ )
|
||||||
{
|
{
|
||||||
mCaptureBuffers[i] = new RingBuffer( mCaptureTracks[i]->GetSampleFormat(),
|
mCaptureBuffers[i] = new RingBuffer( mCaptureTracks[i]->GetSampleFormat(),
|
||||||
captureBufferSize );
|
captureBufferSize );
|
||||||
mResample[i] = new ConstRateResample(true, mFactor);
|
mResample[i] = new Resample(true, mFactor, mFactor); // constant rate resampling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
class AudioIO;
|
class AudioIO;
|
||||||
class RingBuffer;
|
class RingBuffer;
|
||||||
class Mixer;
|
class Mixer;
|
||||||
class ConstRateResample;
|
class Resample;
|
||||||
class TimeTrack;
|
class TimeTrack;
|
||||||
class AudioThread;
|
class AudioThread;
|
||||||
class Meter;
|
class Meter;
|
||||||
@ -474,7 +474,7 @@ private:
|
|||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
AudioThread *mMidiThread;
|
AudioThread *mMidiThread;
|
||||||
#endif
|
#endif
|
||||||
ConstRateResample **mResample;
|
Resample **mResample;
|
||||||
RingBuffer **mCaptureBuffers;
|
RingBuffer **mCaptureBuffers;
|
||||||
WaveTrackArray mCaptureTracks;
|
WaveTrackArray mCaptureTracks;
|
||||||
RingBuffer **mPlaybackBuffers;
|
RingBuffer **mPlaybackBuffers;
|
||||||
|
@ -286,11 +286,12 @@ Mixer::Mixer(int numInputTracks, WaveTrack **inputTracks,
|
|||||||
for(i=0; i<mNumInputTracks; i++) {
|
for(i=0; i<mNumInputTracks; i++) {
|
||||||
double factor = (mRate / mInputTrack[i]->GetRate());
|
double factor = (mRate / mInputTrack[i]->GetRate());
|
||||||
if (timeTrack) {
|
if (timeTrack) {
|
||||||
mResample[i] = new VarRateResample(highQuality,
|
// variable rate resampling
|
||||||
factor / timeTrack->GetRangeUpper(),
|
mResample[i] = new Resample(highQuality,
|
||||||
factor / timeTrack->GetRangeLower());
|
factor / timeTrack->GetRangeUpper(),
|
||||||
|
factor / timeTrack->GetRangeLower());
|
||||||
} else {
|
} else {
|
||||||
mResample[i] = new ConstRateResample(highQuality, factor);
|
mResample[i] = new Resample(highQuality, factor, factor); // constant rate resampling
|
||||||
}
|
}
|
||||||
mSampleQueue[i] = new float[mQueueMaxLen];
|
mSampleQueue[i] = new float[mQueueMaxLen];
|
||||||
mQueueStart[i] = 0;
|
mQueueStart[i] = 0;
|
||||||
|
387
src/Resample.cpp
387
src/Resample.cpp
@ -32,281 +32,11 @@
|
|||||||
|
|
||||||
#include "Resample.h"
|
#include "Resample.h"
|
||||||
|
|
||||||
//v Currently unused.
|
|
||||||
//void Resample::SetFastMethod(int index)
|
|
||||||
//{
|
|
||||||
// gPrefs->Write(GetFastMethodKey(), (long)index);
|
|
||||||
// gPrefs->Flush();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//void Resample::SetBestMethod(int index)
|
|
||||||
//{
|
|
||||||
// gPrefs->Write(GetBestMethodKey(), (long)index);
|
|
||||||
// gPrefs->Flush();
|
|
||||||
//}
|
|
||||||
|
|
||||||
// constant-rate resamplers
|
|
||||||
#if USE_LIBRESAMPLE
|
#if USE_LIBRESAMPLE
|
||||||
|
|
||||||
#include "libresample.h"
|
#include "libresample.h"
|
||||||
|
|
||||||
ConstRateResample::ConstRateResample(const bool useBestMethod, const double dFactor)
|
Resample::Resample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
||||||
: Resample()
|
|
||||||
{
|
|
||||||
this->SetMethod(useBestMethod);
|
|
||||||
mHandle = resample_open(mMethod, dFactor, dFactor);
|
|
||||||
if(mHandle == NULL) {
|
|
||||||
fprintf(stderr, "libresample doesn't support factor %f.\n", dFactor);
|
|
||||||
// FIX-ME: Audacity will hang after this if branch.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstRateResample::~ConstRateResample()
|
|
||||||
{
|
|
||||||
resample_close(mHandle);
|
|
||||||
mHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//v Currently unused.
|
|
||||||
//wxString ConstRateResample::GetResamplingLibraryName()
|
|
||||||
//{
|
|
||||||
// return _("Libresample by Dominic Mazzoni and Julius Smith");
|
|
||||||
//}
|
|
||||||
|
|
||||||
int ConstRateResample::GetNumMethods() { return 2; }
|
|
||||||
|
|
||||||
wxString ConstRateResample::GetMethodName(int index)
|
|
||||||
{
|
|
||||||
if (index == 1)
|
|
||||||
return _("High-quality Sinc Interpolation");
|
|
||||||
|
|
||||||
return _("Fast Sinc Interpolation");
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString ConstRateResample::GetFastMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/LibresampleSampleRateConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString ConstRateResample::GetBestMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/LibresampleHQSampleRateConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
int ConstRateResample::GetFastMethodDefault() { return 0; }
|
|
||||||
int ConstRateResample::GetBestMethodDefault() { return 1; }
|
|
||||||
|
|
||||||
int ConstRateResample::Process(double factor,
|
|
||||||
float *inBuffer,
|
|
||||||
int inBufferLen,
|
|
||||||
bool lastFlag,
|
|
||||||
int *inBufferUsed,
|
|
||||||
float *outBuffer,
|
|
||||||
int outBufferLen)
|
|
||||||
{
|
|
||||||
return resample_process(mHandle, factor, inBuffer, inBufferLen,
|
|
||||||
(int)lastFlag, inBufferUsed, outBuffer, outBufferLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif USE_LIBSAMPLERATE
|
|
||||||
|
|
||||||
#include <samplerate.h>
|
|
||||||
|
|
||||||
ConstRateResample::ConstRateResample(const bool useBestMethod, const double dFactor)
|
|
||||||
: Resample()
|
|
||||||
{
|
|
||||||
this->SetMethod(useBestMethod);
|
|
||||||
if (!src_is_valid_ratio(dFactor))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "libsamplerate supports only resampling factors between 1/SRC_MAX_RATIO and SRC_MAX_RATIO.\n");
|
|
||||||
// FIX-ME: Audacity will hang after this if branch.
|
|
||||||
mHandle = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int err;
|
|
||||||
SRC_STATE *state = src_new(mMethod, 1, &err);
|
|
||||||
mHandle = (void *)state;
|
|
||||||
mShouldReset = false;
|
|
||||||
mSamplesLeft = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstRateResample::~ConstRateResample()
|
|
||||||
{
|
|
||||||
src_delete((SRC_STATE *)mHandle);
|
|
||||||
mHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//v Currently unused.
|
|
||||||
//wxString ConstRateResample::GetResamplingLibraryName()
|
|
||||||
//{
|
|
||||||
// return _("Libsamplerate by Erik de Castro Lopo");
|
|
||||||
//}
|
|
||||||
|
|
||||||
int ConstRateResample::GetNumMethods()
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while(src_get_name(i))
|
|
||||||
i++;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString ConstRateResample::GetMethodName(int index)
|
|
||||||
{
|
|
||||||
return wxString(wxString::FromAscii(src_get_name(index)));
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString ConstRateResample::GetFastMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/SampleRateConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString ConstRateResample::GetBestMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/HQSampleRateConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
int ConstRateResample::GetFastMethodDefault()
|
|
||||||
{
|
|
||||||
return SRC_SINC_FASTEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ConstRateResample::GetBestMethodDefault()
|
|
||||||
{
|
|
||||||
return SRC_SINC_BEST_QUALITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ConstRateResample::Process(double factor,
|
|
||||||
float *inBuffer,
|
|
||||||
int inBufferLen,
|
|
||||||
bool lastFlag,
|
|
||||||
int *inBufferUsed,
|
|
||||||
float *outBuffer,
|
|
||||||
int outBufferLen)
|
|
||||||
{
|
|
||||||
src_set_ratio((SRC_STATE *)mHandle, factor);
|
|
||||||
|
|
||||||
if(mShouldReset) {
|
|
||||||
if(inBufferLen > mSamplesLeft) {
|
|
||||||
mShouldReset = false;
|
|
||||||
src_reset((SRC_STATE *)mHandle);
|
|
||||||
} else {
|
|
||||||
mSamplesLeft -= inBufferLen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SRC_DATA data;
|
|
||||||
|
|
||||||
data.data_in = inBuffer;
|
|
||||||
data.data_out = outBuffer;
|
|
||||||
data.input_frames = inBufferLen;
|
|
||||||
data.output_frames = outBufferLen;
|
|
||||||
data.input_frames_used = 0;
|
|
||||||
data.output_frames_gen = 0;
|
|
||||||
data.end_of_input = (int)lastFlag;
|
|
||||||
data.src_ratio = factor;
|
|
||||||
|
|
||||||
int err = src_process((SRC_STATE *)mHandle, &data);
|
|
||||||
if (err) {
|
|
||||||
wxFprintf(stderr, _("Libsamplerate error: %d\n"), err);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lastFlag) {
|
|
||||||
mShouldReset = true;
|
|
||||||
mSamplesLeft = inBufferLen - (int)data.input_frames_used;
|
|
||||||
}
|
|
||||||
|
|
||||||
*inBufferUsed = (int)data.input_frames_used;
|
|
||||||
return (int)data.output_frames_gen;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif USE_LIBSOXR
|
|
||||||
|
|
||||||
#include <soxr.h>
|
|
||||||
|
|
||||||
ConstRateResample::ConstRateResample(const bool useBestMethod, const double dFactor)
|
|
||||||
: Resample()
|
|
||||||
{
|
|
||||||
this->SetMethod(useBestMethod);
|
|
||||||
soxr_quality_spec_t q_spec = soxr_quality_spec("\0\1\4\6"[mMethod], 0);
|
|
||||||
mHandle = (void *)soxr_create(1, dFactor, 1, 0, 0, &q_spec, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstRateResample::~ConstRateResample()
|
|
||||||
{
|
|
||||||
soxr_delete((soxr_t)mHandle);
|
|
||||||
mHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//v Currently unused.
|
|
||||||
//wxString ConstRateResample::GetResamplingLibraryName()
|
|
||||||
//{
|
|
||||||
// return _("Libsoxr by Rob Sykes");
|
|
||||||
//}
|
|
||||||
|
|
||||||
int ConstRateResample::GetNumMethods() { return 4; }
|
|
||||||
|
|
||||||
wxString ConstRateResample::GetMethodName(int index)
|
|
||||||
{
|
|
||||||
static char const * const soxr_method_names[] = {
|
|
||||||
"Low Quality (Fastest)", "Medium Quality", "High Quality", "Best Quality (Slowest)"
|
|
||||||
};
|
|
||||||
|
|
||||||
return wxString(wxString::FromAscii(soxr_method_names[index]));
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString ConstRateResample::GetFastMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/LibsoxrSampleRateConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString ConstRateResample::GetBestMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/LibsoxrHQSampleRateConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
int ConstRateResample::GetFastMethodDefault() {return 1;}
|
|
||||||
int ConstRateResample::GetBestMethodDefault() {return 3;}
|
|
||||||
|
|
||||||
int ConstRateResample::Process(double factor,
|
|
||||||
float *inBuffer,
|
|
||||||
int inBufferLen,
|
|
||||||
bool lastFlag,
|
|
||||||
int *inBufferUsed,
|
|
||||||
float *outBuffer,
|
|
||||||
int outBufferLen)
|
|
||||||
{
|
|
||||||
size_t idone , odone;
|
|
||||||
soxr_process((soxr_t)mHandle,
|
|
||||||
inBuffer , (size_t)(lastFlag? ~inBufferLen : inBufferLen), &idone,
|
|
||||||
outBuffer, (size_t) outBufferLen, &odone);
|
|
||||||
*inBufferUsed = (int)idone;
|
|
||||||
return (int)odone;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // no const-rate resampler
|
|
||||||
ConstRateResample::ConstRateResample(const bool useBestMethod, const double dFactor)
|
|
||||||
: Resample()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstRateResample::~ConstRateResample()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// variable-rate resamplers
|
|
||||||
#if USE_LIBRESAMPLE
|
|
||||||
|
|
||||||
#include "libresample.h"
|
|
||||||
|
|
||||||
VarRateResample::VarRateResample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
|
||||||
: Resample()
|
|
||||||
{
|
{
|
||||||
this->SetMethod(useBestMethod);
|
this->SetMethod(useBestMethod);
|
||||||
mHandle = resample_open(mMethod, dMinFactor, dMaxFactor);
|
mHandle = resample_open(mMethod, dMinFactor, dMaxFactor);
|
||||||
@ -317,21 +47,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VarRateResample::~VarRateResample()
|
Resample::~Resample()
|
||||||
{
|
{
|
||||||
resample_close(mHandle);
|
resample_close(mHandle);
|
||||||
mHandle = NULL;
|
mHandle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//v Currently unused.
|
int Resample::GetNumMethods() { return 2; }
|
||||||
//wxString VarRateResample::GetResamplingLibraryName()
|
|
||||||
//{
|
|
||||||
// return _("Libresample by Dominic Mazzoni and Julius Smith");
|
|
||||||
//}
|
|
||||||
|
|
||||||
int VarRateResample::GetNumMethods() { return 2; }
|
wxString Resample::GetMethodName(int index)
|
||||||
|
|
||||||
wxString VarRateResample::GetMethodName(int index)
|
|
||||||
{
|
{
|
||||||
if (index == 1)
|
if (index == 1)
|
||||||
return _("High-quality Sinc Interpolation");
|
return _("High-quality Sinc Interpolation");
|
||||||
@ -339,20 +63,20 @@
|
|||||||
return _("Fast Sinc Interpolation");
|
return _("Fast Sinc Interpolation");
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString VarRateResample::GetFastMethodKey()
|
const wxString Resample::GetFastMethodKey()
|
||||||
{
|
{
|
||||||
return wxT("/Quality/LibresampleSampleRateConverter");
|
return wxT("/Quality/LibresampleSampleRateConverter");
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString VarRateResample::GetBestMethodKey()
|
const wxString Resample::GetBestMethodKey()
|
||||||
{
|
{
|
||||||
return wxT("/Quality/LibresampleHQSampleRateConverter");
|
return wxT("/Quality/LibresampleHQSampleRateConverter");
|
||||||
}
|
}
|
||||||
|
|
||||||
int VarRateResample::GetFastMethodDefault() { return 0; }
|
int Resample::GetFastMethodDefault() { return 0; }
|
||||||
int VarRateResample::GetBestMethodDefault() { return 1; }
|
int Resample::GetBestMethodDefault() { return 1; }
|
||||||
|
|
||||||
int VarRateResample::Process(double factor,
|
int Resample::Process(double factor,
|
||||||
float *inBuffer,
|
float *inBuffer,
|
||||||
int inBufferLen,
|
int inBufferLen,
|
||||||
bool lastFlag,
|
bool lastFlag,
|
||||||
@ -368,8 +92,7 @@
|
|||||||
|
|
||||||
#include <samplerate.h>
|
#include <samplerate.h>
|
||||||
|
|
||||||
VarRateResample::VarRateResample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
Resample::Resample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
||||||
: Resample()
|
|
||||||
{
|
{
|
||||||
this->SetMethod(useBestMethod);
|
this->SetMethod(useBestMethod);
|
||||||
if (!src_is_valid_ratio (dMinFactor) || !src_is_valid_ratio (dMaxFactor)) {
|
if (!src_is_valid_ratio (dMinFactor) || !src_is_valid_ratio (dMaxFactor)) {
|
||||||
@ -386,19 +109,13 @@
|
|||||||
mSamplesLeft = 0;
|
mSamplesLeft = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VarRateResample::~VarRateResample()
|
Resample::~Resample()
|
||||||
{
|
{
|
||||||
src_delete((SRC_STATE *)mHandle);
|
src_delete((SRC_STATE *)mHandle);
|
||||||
mHandle = NULL;
|
mHandle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//v Currently unused.
|
int Resample::GetNumMethods()
|
||||||
//wxString Resample::GetResamplingLibraryName()
|
|
||||||
//{
|
|
||||||
// return _("Libsamplerate by Erik de Castro Lopo");
|
|
||||||
//}
|
|
||||||
|
|
||||||
int VarRateResample::GetNumMethods()
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@ -408,32 +125,32 @@
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString VarRateResample::GetMethodName(int index)
|
wxString Resample::GetMethodName(int index)
|
||||||
{
|
{
|
||||||
return wxString(wxString::FromAscii(src_get_name(index)));
|
return wxString(wxString::FromAscii(src_get_name(index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString VarRateResample::GetFastMethodKey()
|
const wxString Resample::GetFastMethodKey()
|
||||||
{
|
{
|
||||||
return wxT("/Quality/SampleRateConverter");
|
return wxT("/Quality/SampleRateConverter");
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString VarRateResample::GetBestMethodKey()
|
const wxString Resample::GetBestMethodKey()
|
||||||
{
|
{
|
||||||
return wxT("/Quality/HQSampleRateConverter");
|
return wxT("/Quality/HQSampleRateConverter");
|
||||||
}
|
}
|
||||||
|
|
||||||
int VarRateResample::GetFastMethodDefault()
|
int Resample::GetFastMethodDefault()
|
||||||
{
|
{
|
||||||
return SRC_SINC_FASTEST;
|
return SRC_SINC_FASTEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VarRateResample::GetBestMethodDefault()
|
int Resample::GetBestMethodDefault()
|
||||||
{
|
{
|
||||||
return SRC_SINC_BEST_QUALITY;
|
return SRC_SINC_BEST_QUALITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VarRateResample::Process(double factor,
|
int Resample::Process(double factor,
|
||||||
float *inBuffer,
|
float *inBuffer,
|
||||||
int inBufferLen,
|
int inBufferLen,
|
||||||
bool lastFlag,
|
bool lastFlag,
|
||||||
@ -443,8 +160,6 @@
|
|||||||
{
|
{
|
||||||
src_set_ratio((SRC_STATE *)mHandle, factor);
|
src_set_ratio((SRC_STATE *)mHandle, factor);
|
||||||
|
|
||||||
SRC_DATA data;
|
|
||||||
|
|
||||||
if(mShouldReset) {
|
if(mShouldReset) {
|
||||||
if(inBufferLen > mSamplesLeft) {
|
if(inBufferLen > mSamplesLeft) {
|
||||||
mShouldReset = false;
|
mShouldReset = false;
|
||||||
@ -454,6 +169,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SRC_DATA data;
|
||||||
data.data_in = inBuffer;
|
data.data_in = inBuffer;
|
||||||
data.data_out = outBuffer;
|
data.data_out = outBuffer;
|
||||||
data.input_frames = inBufferLen;
|
data.input_frames = inBufferLen;
|
||||||
@ -479,29 +195,35 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif USE_LIBSOXR
|
#elif USE_LIBSOXR
|
||||||
// Note that as we currently do not distinguish USE_* flags for var-rate vs const-rate,
|
|
||||||
// we need to have USE_LIBSOXR last in the var-rate #if/#elif implementations, because
|
|
||||||
// it's always #defined in standard configuration, for use as the sole const-rate resampler.
|
|
||||||
|
|
||||||
#include <soxr.h>
|
#include <soxr.h>
|
||||||
|
|
||||||
VarRateResample::VarRateResample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
Resample::Resample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
||||||
: Resample()
|
|
||||||
{
|
{
|
||||||
this->SetMethod(useBestMethod);
|
this->SetMethod(useBestMethod);
|
||||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_HQ, SOXR_VR);
|
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 = (void *)soxr_create(1, dMinFactor, 1, 0, 0, &q_spec, 0);
|
mHandle = (void *)soxr_create(1, dMinFactor, 1, 0, 0, &q_spec, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarRateResample::~VarRateResample()
|
Resample::~Resample()
|
||||||
{
|
{
|
||||||
soxr_delete((soxr_t)mHandle);
|
soxr_delete((soxr_t)mHandle);
|
||||||
mHandle = NULL;
|
mHandle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VarRateResample::GetNumMethods() { return 4; }
|
int Resample::GetNumMethods() { return 4; }
|
||||||
|
|
||||||
wxString VarRateResample::GetMethodName(int index)
|
wxString Resample::GetMethodName(int index)
|
||||||
{
|
{
|
||||||
static char const * const soxr_method_names[] = {
|
static char const * const soxr_method_names[] = {
|
||||||
"Low Quality (Fastest)", "Medium Quality", "High Quality", "Best Quality (Slowest)"
|
"Low Quality (Fastest)", "Medium Quality", "High Quality", "Best Quality (Slowest)"
|
||||||
@ -510,20 +232,20 @@
|
|||||||
return wxString(wxString::FromAscii(soxr_method_names[index]));
|
return wxString(wxString::FromAscii(soxr_method_names[index]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString VarRateResample::GetFastMethodKey()
|
const wxString Resample::GetFastMethodKey()
|
||||||
{
|
{
|
||||||
return wxT("/Quality/LibsoxrSampleRateConverter");
|
return wxT("/Quality/LibsoxrSampleRateConverter");
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString VarRateResample::GetBestMethodKey()
|
const wxString Resample::GetBestMethodKey()
|
||||||
{
|
{
|
||||||
return wxT("/Quality/LibsoxrHQSampleRateConverter");
|
return wxT("/Quality/LibsoxrHQSampleRateConverter");
|
||||||
}
|
}
|
||||||
|
|
||||||
int VarRateResample::GetFastMethodDefault() {return 1;}
|
int Resample::GetFastMethodDefault() {return 1;}
|
||||||
int VarRateResample::GetBestMethodDefault() {return 3;}
|
int Resample::GetBestMethodDefault() {return 3;}
|
||||||
|
|
||||||
int VarRateResample::Process(double factor,
|
int Resample::Process(double factor,
|
||||||
float *inBuffer,
|
float *inBuffer,
|
||||||
int inBufferLen,
|
int inBufferLen,
|
||||||
bool lastFlag,
|
bool lastFlag,
|
||||||
@ -531,24 +253,23 @@
|
|||||||
float *outBuffer,
|
float *outBuffer,
|
||||||
int outBufferLen)
|
int outBufferLen)
|
||||||
{
|
{
|
||||||
soxr_set_io_ratio((soxr_t)mHandle, 1/factor, 0);
|
size_t idone, odone;
|
||||||
|
if (mbWantConstRateResampling)
|
||||||
|
{
|
||||||
|
soxr_process((soxr_t)mHandle,
|
||||||
|
inBuffer , (size_t)(lastFlag? ~inBufferLen : inBufferLen), &idone,
|
||||||
|
outBuffer, (size_t) outBufferLen, &odone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
soxr_set_io_ratio((soxr_t)mHandle, 1/factor, 0);
|
||||||
|
|
||||||
size_t idone , odone;
|
inBufferLen = lastFlag? ~inBufferLen : inBufferLen;
|
||||||
inBufferLen = lastFlag? ~inBufferLen : inBufferLen;
|
soxr_process((soxr_t)mHandle,
|
||||||
soxr_process((soxr_t)mHandle,
|
inBuffer , (size_t)inBufferLen , &idone,
|
||||||
inBuffer , (size_t)inBufferLen , &idone,
|
outBuffer, (size_t)outBufferLen, &odone);
|
||||||
outBuffer, (size_t)outBufferLen, &odone);
|
}
|
||||||
*inBufferUsed = (int)idone;
|
*inBufferUsed = (int)idone;
|
||||||
return (int)odone;
|
return (int)odone;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // no var-rate resampler
|
|
||||||
VarRateResample::VarRateResample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor)
|
|
||||||
: Resample()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VarRateResample::~VarRateResample()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
154
src/Resample.h
154
src/Resample.h
@ -23,33 +23,26 @@
|
|||||||
class Resample
|
class Resample
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The first parameter lets you select either the best method or
|
|
||||||
/// the fast method.
|
|
||||||
//v (The particular method used was previously set by
|
|
||||||
/// SetFastMethod or SetBestMethod.)
|
|
||||||
Resample()
|
|
||||||
{
|
|
||||||
mMethod = 0;
|
|
||||||
mHandle = NULL;
|
|
||||||
};
|
|
||||||
virtual ~Resample() {};
|
|
||||||
|
|
||||||
/// Returns the name of the library used for resampling
|
|
||||||
/// (long format, may include author name and version number).
|
|
||||||
//v Currently unused.
|
|
||||||
// virtual wxString GetResamplingLibraryName() { return _("Resampling disabled."); };
|
|
||||||
|
|
||||||
/// Resamplers may have more than one method, offering a
|
/// Resamplers may have more than one method, offering a
|
||||||
/// tradeoff between speed and quality.
|
/// tradeoff between speed and quality.
|
||||||
/// Audacity identifies two methods out of all of the choices:
|
/// Audacity identifies two methods out of all of the choices:
|
||||||
/// a Fast method intended for real-time audio I/O, and a Best
|
/// a Fast method intended for real-time audio I/O, and a Best
|
||||||
/// method intended for mixing and exporting.
|
/// method intended for mixing and exporting.
|
||||||
//v (These were previously saved
|
//
|
||||||
// in the preferences when you call Set[Best,Fast]Method.
|
/// The first parameter lets you select either the best method or
|
||||||
// Now done with TieChoice() in QualityPrefs.
|
/// the fast method.
|
||||||
// Implemented in descendant classes, for class-specificity.)
|
// dMinFactor and dMaxFactor specify the range of factors for variable-rate resampling.
|
||||||
//static void SetFastMethod(int index);
|
// For constant-rate, pass the same value for both.
|
||||||
//static void SetBestMethod(int index);
|
Resample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor);
|
||||||
|
virtual ~Resample();
|
||||||
|
|
||||||
|
static int GetNumMethods();
|
||||||
|
static wxString GetMethodName(int index);
|
||||||
|
|
||||||
|
static const wxString GetFastMethodKey();
|
||||||
|
static const wxString GetBestMethodKey();
|
||||||
|
static int GetFastMethodDefault();
|
||||||
|
static int GetBestMethodDefault();
|
||||||
|
|
||||||
/** @brief Main processing function. Resamples from the input buffer to the
|
/** @brief Main processing function. Resamples from the input buffer to the
|
||||||
* output buffer.
|
* output buffer.
|
||||||
@ -73,25 +66,21 @@ class Resample
|
|||||||
@param outBufferLen How big outBuffer is.
|
@param outBufferLen How big outBuffer is.
|
||||||
@return Number of output samples created by this call
|
@return Number of output samples created by this call
|
||||||
*/
|
*/
|
||||||
virtual int Process(double WXUNUSED(factor),
|
virtual int Process(double factor,
|
||||||
float *inBuffer,
|
float *inBuffer,
|
||||||
int inBufferLen,
|
int inBufferLen,
|
||||||
bool WXUNUSED(lastFlag),
|
bool lastFlag,
|
||||||
int * WXUNUSED(inBufferUsed),
|
int *inBufferUsed,
|
||||||
float *outBuffer,
|
float *outBuffer,
|
||||||
int outBufferLen)
|
int outBufferLen);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetMethod(const bool useBestMethod)
|
||||||
{
|
{
|
||||||
// Base class method just copies data with no change.
|
if (useBestMethod)
|
||||||
int i;
|
mMethod = gPrefs->Read(GetBestMethodKey(), GetBestMethodDefault());
|
||||||
int len = inBufferLen;
|
else
|
||||||
|
mMethod = gPrefs->Read(GetFastMethodKey(), GetFastMethodDefault());
|
||||||
if (len > outBufferLen)
|
|
||||||
len = outBufferLen;
|
|
||||||
|
|
||||||
for(i=0; i<len; i++)
|
|
||||||
outBuffer[i] = inBuffer[i];
|
|
||||||
|
|
||||||
return len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -100,96 +89,9 @@ class Resample
|
|||||||
#if USE_LIBSAMPLERATE
|
#if USE_LIBSAMPLERATE
|
||||||
bool mShouldReset; // whether the resampler should be reset because lastFlag has been set previously
|
bool mShouldReset; // whether the resampler should be reset because lastFlag has been set previously
|
||||||
int mSamplesLeft; // number of samples left before a reset is needed
|
int mSamplesLeft; // number of samples left before a reset is needed
|
||||||
|
#elif USE_LIBSOXR
|
||||||
|
bool mbWantConstRateResampling;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConstRateResample : public Resample
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConstRateResample(const bool useBestMethod, const double dFactor);
|
|
||||||
virtual ~ConstRateResample();
|
|
||||||
|
|
||||||
// Override base class methods only if we actually have a sample rate conversion library.
|
|
||||||
#if USE_LIBRESAMPLE || USE_LIBSAMPLERATE || USE_LIBSOXR
|
|
||||||
static int GetNumMethods();
|
|
||||||
static wxString GetMethodName(int index);
|
|
||||||
|
|
||||||
static const wxString GetFastMethodKey();
|
|
||||||
static const wxString GetBestMethodKey();
|
|
||||||
static int GetFastMethodDefault();
|
|
||||||
static int GetBestMethodDefault();
|
|
||||||
|
|
||||||
virtual int Process(double factor,
|
|
||||||
float *inBuffer,
|
|
||||||
int inBufferLen,
|
|
||||||
bool lastFlag,
|
|
||||||
int *inBufferUsed,
|
|
||||||
float *outBuffer,
|
|
||||||
int outBufferLen);
|
|
||||||
#else
|
|
||||||
static int GetNumMethods() { return 1; };
|
|
||||||
static wxString GetMethodName(int WXUNUSED(index)) { return _("Resampling disabled."); };
|
|
||||||
static const wxString GetFastMethodKey() { return wxT("/Quality/DisabledConverter"); };
|
|
||||||
static const wxString GetBestMethodKey() { return wxT("/Quality/DisabledConverter"); };
|
|
||||||
static int GetFastMethodDefault() { return 0; };
|
|
||||||
static int GetBestMethodDefault() { return 0; };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SetMethod(const bool useBestMethod)
|
|
||||||
{
|
|
||||||
if (useBestMethod)
|
|
||||||
mMethod = gPrefs->Read(GetBestMethodKey(), GetBestMethodDefault());
|
|
||||||
else
|
|
||||||
mMethod = gPrefs->Read(GetFastMethodKey(), GetFastMethodDefault());
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class VarRateResample : public Resample
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// dMinFactor and dMaxFactor specify the range of factors for variable-rate resampling.
|
|
||||||
VarRateResample(const bool useBestMethod, const double dMinFactor, const double dMaxFactor);
|
|
||||||
virtual ~VarRateResample();
|
|
||||||
|
|
||||||
// Override base class methods only if we actually have a sample rate conversion library.
|
|
||||||
#if USE_LIBRESAMPLE || USE_LIBSAMPLERATE || USE_LIBSOXR
|
|
||||||
//vvv Note that we're not actually calling any of these Get* methods
|
|
||||||
// for var-rate, as the decision was to not allow QualityPrefs for it.
|
|
||||||
// However the methods already existed for libresample and libsamplerate,
|
|
||||||
// so they're now implemented for all, in case we decide to provide prefs.
|
|
||||||
static int GetNumMethods();
|
|
||||||
static wxString GetMethodName(int index);
|
|
||||||
|
|
||||||
static const wxString GetFastMethodKey();
|
|
||||||
static const wxString GetBestMethodKey();
|
|
||||||
static int GetFastMethodDefault();
|
|
||||||
static int GetBestMethodDefault();
|
|
||||||
|
|
||||||
virtual int Process(double factor,
|
|
||||||
float *inBuffer,
|
|
||||||
int inBufferLen,
|
|
||||||
bool lastFlag,
|
|
||||||
int *inBufferUsed,
|
|
||||||
float *outBuffer,
|
|
||||||
int outBufferLen);
|
|
||||||
#else
|
|
||||||
static int GetNumMethods() { return 1; };
|
|
||||||
static wxString GetMethodName(int WXUNUSED(index)) { return _("Resampling disabled."); };
|
|
||||||
static const wxString GetFastMethodKey() { return wxT("/Quality/DisabledConverter"); };
|
|
||||||
static const wxString GetBestMethodKey() { return wxT("/Quality/DisabledConverter"); };
|
|
||||||
static int GetFastMethodDefault() { return 0; };
|
|
||||||
static int GetBestMethodDefault() { return 0; };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SetMethod(const bool useBestMethod)
|
|
||||||
{
|
|
||||||
if (useBestMethod)
|
|
||||||
mMethod = gPrefs->Read(GetBestMethodKey(), GetBestMethodDefault());
|
|
||||||
else
|
|
||||||
mMethod = gPrefs->Read(GetFastMethodKey(), GetFastMethodDefault());
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __AUDACITY_RESAMPLE_H__
|
#endif // __AUDACITY_RESAMPLE_H__
|
||||||
|
@ -1526,7 +1526,7 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress)
|
|||||||
return true; // Nothing to do
|
return true; // Nothing to do
|
||||||
|
|
||||||
double factor = (double)rate / (double)mRate;
|
double factor = (double)rate / (double)mRate;
|
||||||
ConstRateResample* resample = new ConstRateResample(true, factor);
|
::Resample* resample = new ::Resample(true, factor, factor); // constant rate resampling
|
||||||
|
|
||||||
int bufsize = 65536;
|
int bufsize = 65536;
|
||||||
float* inBuffer = new float[bufsize];
|
float* inBuffer = new float[bufsize];
|
||||||
|
@ -214,7 +214,7 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track,
|
|||||||
float * outBuffer = new float[outBufferSize];
|
float * outBuffer = new float[outBufferSize];
|
||||||
|
|
||||||
// Set up the resampling stuff for this track.
|
// Set up the resampling stuff for this track.
|
||||||
ConstRateResample resample(true, mFactor);
|
Resample resample(true, mFactor, mFactor); // constant rate resampling
|
||||||
|
|
||||||
//Go through the track one buffer at a time. samplePos counts which
|
//Go through the track one buffer at a time. samplePos counts which
|
||||||
//sample the current buffer starts at.
|
//sample the current buffer starts at.
|
||||||
@ -437,7 +437,7 @@ bool ChangeSpeedDialog::TransferDataFromWindow()
|
|||||||
|
|
||||||
// handler implementations for ChangeSpeedDialog
|
// handler implementations for ChangeSpeedDialog
|
||||||
|
|
||||||
void ChangeSpeedDialog::OnText_PercentChange(wxCommandEvent & event)
|
void ChangeSpeedDialog::OnText_PercentChange(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (mbLoopDetect)
|
if (mbLoopDetect)
|
||||||
return;
|
return;
|
||||||
@ -457,7 +457,7 @@ void ChangeSpeedDialog::OnText_PercentChange(wxCommandEvent & event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangeSpeedDialog::OnSlider_PercentChange(wxCommandEvent & event)
|
void ChangeSpeedDialog::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (mbLoopDetect)
|
if (mbLoopDetect)
|
||||||
return;
|
return;
|
||||||
@ -475,7 +475,7 @@ void ChangeSpeedDialog::OnSlider_PercentChange(wxCommandEvent & event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangeSpeedDialog::OnChoice_FromVinyl(wxCommandEvent & event)
|
void ChangeSpeedDialog::OnChoice_FromVinyl(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (mbLoopDetect)
|
if (mbLoopDetect)
|
||||||
return;
|
return;
|
||||||
@ -489,7 +489,7 @@ void ChangeSpeedDialog::OnChoice_FromVinyl(wxCommandEvent & event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangeSpeedDialog::OnChoice_ToVinyl(wxCommandEvent & event)
|
void ChangeSpeedDialog::OnChoice_ToVinyl(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (mbLoopDetect)
|
if (mbLoopDetect)
|
||||||
return;
|
return;
|
||||||
|
@ -107,17 +107,9 @@ void QualityPrefs::GetNamesAndLabels()
|
|||||||
mSampleFormatNames.Add(wxT("32-bit float")); mSampleFormatLabels.Add(floatSample);
|
mSampleFormatNames.Add(wxT("32-bit float")); mSampleFormatLabels.Add(floatSample);
|
||||||
|
|
||||||
//------------- Converter Names
|
//------------- Converter Names
|
||||||
// We used to set and get best/fast method via Resample.cpp.
|
int numConverters = Resample::GetNumMethods();
|
||||||
// Need to ensure that preferences strings in Resample.cpp match.
|
|
||||||
// Note that these methods used to be public and static, but are now protected and pure virtual.
|
|
||||||
//
|
|
||||||
//vvv Note that we're now using libsoxr for constant-rate resampling
|
|
||||||
// and either libresample, libsamplerate, or libsoxr for variable-rate,
|
|
||||||
// and currently not allowing prefs method choice for variable-rate,
|
|
||||||
// per discussion on -devel.
|
|
||||||
int numConverters = ConstRateResample::GetNumMethods();
|
|
||||||
for (int i = 0; i < numConverters; i++) {
|
for (int i = 0; i < numConverters; i++) {
|
||||||
mConverterNames.Add(ConstRateResample::GetMethodName(i));
|
mConverterNames.Add(Resample::GetMethodName(i));
|
||||||
mConverterLabels.Add(i);
|
mConverterLabels.Add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,8 +165,8 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.SetStretchyCol(2);
|
S.SetStretchyCol(2);
|
||||||
|
|
||||||
S.TieChoice(_("Sample Rate Con&verter:"),
|
S.TieChoice(_("Sample Rate Con&verter:"),
|
||||||
ConstRateResample::GetFastMethodKey(),
|
Resample::GetFastMethodKey(),
|
||||||
ConstRateResample::GetFastMethodDefault(),
|
Resample::GetFastMethodDefault(),
|
||||||
mConverterNames,
|
mConverterNames,
|
||||||
mConverterLabels),
|
mConverterLabels),
|
||||||
S.SetSizeHints(mConverterNames);
|
S.SetSizeHints(mConverterNames);
|
||||||
@ -195,8 +187,8 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.StartMultiColumn(2);
|
S.StartMultiColumn(2);
|
||||||
{
|
{
|
||||||
S.TieChoice(_("Sample Rate Conver&ter:"),
|
S.TieChoice(_("Sample Rate Conver&ter:"),
|
||||||
ConstRateResample::GetBestMethodKey(),
|
Resample::GetBestMethodKey(),
|
||||||
ConstRateResample::GetBestMethodDefault(),
|
Resample::GetBestMethodDefault(),
|
||||||
mConverterNames,
|
mConverterNames,
|
||||||
mConverterLabels),
|
mConverterLabels),
|
||||||
S.SetSizeHints(mConverterNames);
|
S.SetSizeHints(mConverterNames);
|
||||||
@ -215,7 +207,7 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
|
|
||||||
/// Enables or disables the Edit box depending on
|
/// Enables or disables the Edit box depending on
|
||||||
/// whether we selected 'Other...' or not.
|
/// whether we selected 'Other...' or not.
|
||||||
void QualityPrefs::OnSampleRateChoice(wxCommandEvent & e)
|
void QualityPrefs::OnSampleRateChoice(wxCommandEvent & WXUNUSED(e))
|
||||||
{
|
{
|
||||||
int sel = mSampleRates->GetSelection();
|
int sel = mSampleRates->GetSelection();
|
||||||
mOtherSampleRate->Enable(sel == (int)mSampleRates->GetCount() - 1);
|
mOtherSampleRate->Enable(sel == (int)mSampleRates->GetCount() - 1);
|
||||||
|
@ -22,16 +22,13 @@
|
|||||||
// #define USE_LIBLRDF 1
|
// #define USE_LIBLRDF 1
|
||||||
#define USE_LIBMAD 1
|
#define USE_LIBMAD 1
|
||||||
|
|
||||||
// Resamplers.
|
// Resamplers:
|
||||||
// Only one of each type of resampler (constant or variable rate) should be defined.
|
// Exactly one resampler should be defined.
|
||||||
// libsoxr is used for constant-rate and var-rate resampling.
|
// Should build only one of libsoxr, libresample, or libsamplerate for resampling,
|
||||||
// libsoxr currently our only const-rate resampler, so should always be #defined.
|
|
||||||
#define USE_LIBSOXR 1
|
|
||||||
|
|
||||||
// Should build only one of libsoxr, libresample, or libsamplerate for variable-rate resampling,
|
|
||||||
// but if more than one are defined, priority is libresample over libsamplerate over libsoxr.
|
// but if more than one are defined, priority is libresample over libsamplerate over libsoxr.
|
||||||
// We cannot release builds with libsamplerate, due to licensing.
|
// We cannot release builds with libsamplerate, due to licensing.
|
||||||
// Standard configuration is to have only USE_LIBSOXR #defined.
|
// Standard configuration is to have only USE_LIBSOXR #defined.
|
||||||
|
#define USE_LIBSOXR 1
|
||||||
#undef USE_LIBRESAMPLE
|
#undef USE_LIBRESAMPLE
|
||||||
#undef USE_LIBSAMPLERATE
|
#undef USE_LIBSAMPLERATE
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user