mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-11 09:31:13 +02:00
This commit is partial effort toward more libsoxr integration, that implements Rob Sykes's latest patch. I have no idea whether the Linux-specific stuff from the patch (e.g., M4 file) is still correct in this.
For Resample.* and QualityPrefs.cpp, this commit has my restructuring for distinguishing constant-rate vs variable-rate resamplers more generally. I think it's complete and ready for const-rate, but I have more review and testing to do for the var-rate cases. Variable-rate resampling is not implemented here, so Time Tracks are still broken, but this is a milestone in getting to a more general and correct structure. Also I think this fixes AboutDialog issues Steve noticed.
This commit is contained in:
parent
13c7562a7d
commit
5460b5c668
46
m4/audacity_checklib_libresample.m4
Normal file
46
m4/audacity_checklib_libresample.m4
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
dnl Add Audacity license?
|
||||||
|
dnl Please increment the serial number below whenever you alter this macro
|
||||||
|
dnl for the benefit of automatic macro update systems
|
||||||
|
# audacity_checklib_libresample.m4 serial 1
|
||||||
|
|
||||||
|
AC_DEFUN([AUDACITY_CHECKLIB_LIBRESAMPLE], [
|
||||||
|
|
||||||
|
AC_ARG_WITH(libresample,
|
||||||
|
[AS_HELP_STRING([--with-libresample],
|
||||||
|
[use libresample for sample rate conversion: [yes,no]])],
|
||||||
|
LIBRESAMPLE_ARGUMENT=$withval,
|
||||||
|
LIBRESAMPLE_ARGUMENT="unspecified")
|
||||||
|
|
||||||
|
if false ; then
|
||||||
|
AC_DEFINE(USE_LIBRESAMPLE, 1,
|
||||||
|
[Define if libresample support should be enabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl see if libresample is installed on the system
|
||||||
|
|
||||||
|
dnl ... but libresample isn't generally installed as a system library...
|
||||||
|
|
||||||
|
LIBRESAMPLE_SYSTEM_AVAILABLE="no"
|
||||||
|
|
||||||
|
dnl see if libresample is available locally
|
||||||
|
|
||||||
|
AC_CHECK_FILE(${srcdir}/lib-src/libresample/include/libresample.h,
|
||||||
|
resample_h_found="yes",
|
||||||
|
resample_h_found="no")
|
||||||
|
|
||||||
|
if test "x$resample_h_found" = "xyes" ; then
|
||||||
|
LIBRESAMPLE_LOCAL_AVAILABLE="yes"
|
||||||
|
LIBRESAMPLE_LOCAL_LIBS="libresample.a"
|
||||||
|
LIBRESAMPLE_LOCAL_CXXFLAGS='-I$(top_srcdir)/lib-src/libresample/include'
|
||||||
|
LIBRESAMPLE_LOCAL_CPPSYMBOLS="USE_LIBRESAMPLE"
|
||||||
|
|
||||||
|
if test ! -f lib-src/libresample/Makefile ; then
|
||||||
|
LIBRESAMPLE_LOCAL_CONFIG_SUBDIRS="lib-src/libresample"
|
||||||
|
fi
|
||||||
|
AC_MSG_NOTICE([libresample libraries are available in the local tree])
|
||||||
|
else
|
||||||
|
LIBRESAMPLE_LOCAL_AVAILABLE="no"
|
||||||
|
AC_MSG_NOTICE([libresample libraries are NOT available in the local tree])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
@ -414,16 +414,19 @@ void AboutDialog::PopulateInformationPage( ShuttleGui & S )
|
|||||||
#elif USE_LIBSAMPLERATE
|
#elif USE_LIBSAMPLERATE
|
||||||
AddBuildinfoRow(&informationStr, wxT("libsamplerate"),
|
AddBuildinfoRow(&informationStr, wxT("libsamplerate"),
|
||||||
_("Sample rate conversion"), enabled);
|
_("Sample rate conversion"), enabled);
|
||||||
#elif USE_LIBSOXR
|
|
||||||
AddBuildinfoRow(&informationStr, wxT("libsoxr"),
|
|
||||||
_("Sample rate conversion"), enabled);
|
|
||||||
#else
|
#else
|
||||||
AddBuildinfoRow(&informationStr, wxT("libresample"),
|
AddBuildinfoRow(&informationStr, wxT("libresample"),
|
||||||
_("Sample rate conversion"), disabled);
|
_("Sample rate conversion"), disabled);
|
||||||
AddBuildinfoRow(&informationStr, wxT("libsamplerate"),
|
AddBuildinfoRow(&informationStr, wxT("libsamplerate"),
|
||||||
_("Sample rate conversion"), disabled);
|
_("Sample rate conversion"), disabled);
|
||||||
AddBuildinfoRow(&informationStr, wxT("libsoxr"),
|
#endif
|
||||||
_("Sample rate conversion"), disabled);
|
|
||||||
|
#if USE_LIBSOXR
|
||||||
|
AddBuildinfoRow(&informationStr, wxT("libsoxr"),
|
||||||
|
_("Sample rate conversion"), enabled);
|
||||||
|
#else
|
||||||
|
AddBuildinfoRow(&informationStr, wxT("libsoxr"),
|
||||||
|
_("Sample rate conversion"), disabled);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AddBuildinfoRow(&informationStr, wxT("PortAudio"),
|
AddBuildinfoRow(&informationStr, wxT("PortAudio"),
|
||||||
|
@ -1314,7 +1314,7 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mCaptureBuffers = new RingBuffer* [mCaptureTracks.GetCount()];
|
mCaptureBuffers = new RingBuffer* [mCaptureTracks.GetCount()];
|
||||||
mResample = new Resample* [mCaptureTracks.GetCount()];
|
mResample = new ConstRateResample* [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.
|
||||||
@ -1325,7 +1325,7 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks,
|
|||||||
{
|
{
|
||||||
mCaptureBuffers[i] = new RingBuffer( mCaptureTracks[i]->GetSampleFormat(),
|
mCaptureBuffers[i] = new RingBuffer( mCaptureTracks[i]->GetSampleFormat(),
|
||||||
captureBufferSize );
|
captureBufferSize );
|
||||||
mResample[i] = new Resample( true, mFactor, mFactor );
|
mResample[i] = new ConstRateResample(true, mFactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
class AudioIO;
|
class AudioIO;
|
||||||
class RingBuffer;
|
class RingBuffer;
|
||||||
class Mixer;
|
class Mixer;
|
||||||
class Resample;
|
class ConstRateResample;
|
||||||
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
|
||||||
Resample **mResample;
|
ConstRateResample **mResample;
|
||||||
RingBuffer **mCaptureBuffers;
|
RingBuffer **mCaptureBuffers;
|
||||||
WaveTrackArray mCaptureTracks;
|
WaveTrackArray mCaptureTracks;
|
||||||
RingBuffer **mPlaybackBuffers;
|
RingBuffer **mPlaybackBuffers;
|
||||||
|
@ -281,7 +281,7 @@ Mixer::Mixer(int numInputTracks, WaveTrack **inputTracks,
|
|||||||
mQueueStart = new int[mNumInputTracks];
|
mQueueStart = new int[mNumInputTracks];
|
||||||
mQueueLen = new int[mNumInputTracks];
|
mQueueLen = new int[mNumInputTracks];
|
||||||
mSampleQueue = new float *[mNumInputTracks];
|
mSampleQueue = new float *[mNumInputTracks];
|
||||||
mSRC = new Resample*[mNumInputTracks];
|
mSRC = new Resample*[mNumInputTracks]; //vvvvv
|
||||||
for(i=0; i<mNumInputTracks; i++) {
|
for(i=0; i<mNumInputTracks; i++) {
|
||||||
double factor = (mRate / mInputTrack[i]->GetRate());
|
double factor = (mRate / mInputTrack[i]->GetRate());
|
||||||
double lowFactor = factor, highFactor = factor;
|
double lowFactor = factor, highFactor = factor;
|
||||||
@ -289,7 +289,7 @@ Mixer::Mixer(int numInputTracks, WaveTrack **inputTracks,
|
|||||||
highFactor /= timeTrack->GetRangeLower() / 100.0;
|
highFactor /= timeTrack->GetRangeLower() / 100.0;
|
||||||
lowFactor /= timeTrack->GetRangeUpper() / 100.0;
|
lowFactor /= timeTrack->GetRangeUpper() / 100.0;
|
||||||
}
|
}
|
||||||
mSRC[i] = new Resample(highQuality, lowFactor, highFactor);
|
mSRC[i] = new Resample(); //vvvvv
|
||||||
mSampleQueue[i] = new float[mQueueMaxLen];
|
mSampleQueue[i] = new float[mQueueMaxLen];
|
||||||
mQueueStart[i] = 0;
|
mQueueStart[i] = 0;
|
||||||
mQueueLen[i] = 0;
|
mQueueLen[i] = 0;
|
||||||
|
269
src/Resample.cpp
269
src/Resample.cpp
@ -1,54 +1,139 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|
||||||
Audacity: A Digital Audio Editor
|
Audacity: A Digital Audio Editor
|
||||||
|
Audacity(R) is copyright (c) 1999-2012 Audacity Team.
|
||||||
|
License: GPL v2. See License.txt.
|
||||||
|
|
||||||
Dominic Mazzoni
|
Resample.cpp
|
||||||
|
Dominic Mazzoni, Rob Sykes, Vaughan Johnson
|
||||||
|
|
||||||
*******************************************************************//*!
|
******************************************************************//**
|
||||||
|
|
||||||
\class Resample
|
\class Resample
|
||||||
\brief Combined interface to libresample and libsamplerate (which libsoxr emulates).
|
\brief Combined interface to libresample, libsamplerate, and libsoxr.
|
||||||
|
|
||||||
This class abstracts the interface to two different resampling
|
This class abstracts the interface to two different variable-rate
|
||||||
libraries:
|
resampling libraries:
|
||||||
|
|
||||||
libresample, written by Dominic Mazzoni based on Resample-1.7
|
libresample, written by Dominic Mazzoni based on Resample-1.7
|
||||||
by Julius Smith. LGPL.
|
by Julius Smith. LGPL.
|
||||||
|
|
||||||
libsamplerate, written by Erik de Castro Lopo. GPL. The author
|
libsamplerate, written by Erik de Castro Lopo. GPL. The author
|
||||||
of libsamplerate requests that you not distribute a binary version
|
of libsamplerate requests that you not distribute a binary version
|
||||||
of Audacity that links to libsamplerate and also has plug-in support.
|
of Audacity that links to libsamplerate and also has plug-in support.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
and the fixed-rate resampling library:
|
||||||
|
|
||||||
|
libsoxr, written by Rob Sykes. LGPL.
|
||||||
|
|
||||||
*//*******************************************************************/
|
*//*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "Resample.h"
|
#include "Resample.h"
|
||||||
#include "Prefs.h"
|
|
||||||
|
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
|
|
||||||
int Resample::GetFastMethod()
|
//v Currently unused.
|
||||||
{
|
//void Resample::SetFastMethod(int index)
|
||||||
return gPrefs->Read(GetFastMethodKey(), GetFastMethodDefault());
|
//{
|
||||||
}
|
// gPrefs->Write(GetFastMethodKey(), (long)index);
|
||||||
|
// gPrefs->Flush();
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void Resample::SetBestMethod(int index)
|
||||||
|
//{
|
||||||
|
// gPrefs->Write(GetBestMethodKey(), (long)index);
|
||||||
|
// gPrefs->Flush();
|
||||||
|
//}
|
||||||
|
|
||||||
int Resample::GetBestMethod()
|
// constant-rate resampler(s)
|
||||||
{
|
#ifdef USE_LIBSOXR
|
||||||
return gPrefs->Read(GetBestMethodKey(), GetBestMethodDefault());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resample::SetFastMethod(int index)
|
#include <soxr.h>
|
||||||
{
|
|
||||||
gPrefs->Write(GetFastMethodKey(), (long)index);
|
|
||||||
gPrefs->Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resample::SetBestMethod(int index)
|
ConstRateResample::ConstRateResample(const bool useBestMethod, const double dFactor)
|
||||||
{
|
: Resample()
|
||||||
gPrefs->Write(GetBestMethodKey(), (long)index);
|
{
|
||||||
gPrefs->Flush();
|
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()
|
||||||
|
{
|
||||||
|
delete mHandle;
|
||||||
|
mHandle = NULL;
|
||||||
|
soxr_delete((soxr_t)mHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//v Currently unused.
|
||||||
|
//wxString ConstRateResample::GetResamplingLibraryName()
|
||||||
|
//{
|
||||||
|
// return _("Libsoxr by Rob Sykes");
|
||||||
|
//}
|
||||||
|
|
||||||
|
int ConstRateResample::GetNumMethods() { return 4; }
|
||||||
|
|
||||||
|
static char const * const soxr_method_names[] = {
|
||||||
|
"Quick & dirty", "Basic quality", "High quality", "Very high quality"
|
||||||
|
};
|
||||||
|
|
||||||
|
wxString ConstRateResample::GetMethodName(int index)
|
||||||
|
{
|
||||||
|
return wxString(wxString::FromAscii(soxr_method_names[index]));
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString ConstRateResample::GetFastMethodKey()
|
||||||
|
{
|
||||||
|
return wxT("/Quality/SampleRateConverter");
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString ConstRateResample::GetBestMethodKey()
|
||||||
|
{
|
||||||
|
return wxT("/Quality/HQSampleRateConverter");
|
||||||
|
}
|
||||||
|
|
||||||
|
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_set_oi_ratio((soxr_t)mHandle, factor);
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||||
|
|
||||||
#if USE_LIBRESAMPLE
|
#if USE_LIBRESAMPLE
|
||||||
|
|
||||||
@ -59,10 +144,11 @@ bool Resample::ResamplingEnabled()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString Resample::GetResamplingLibraryName()
|
//v Currently unused.
|
||||||
{
|
//wxString Resample::GetResamplingLibraryName()
|
||||||
return _("Libresample by Dominic Mazzoni and Julius Smith");
|
//{
|
||||||
}
|
// return _("Libresample by Dominic Mazzoni and Julius Smith");
|
||||||
|
//}
|
||||||
|
|
||||||
int Resample::GetNumMethods()
|
int Resample::GetNumMethods()
|
||||||
{
|
{
|
||||||
@ -129,7 +215,7 @@ Resample::~Resample()
|
|||||||
resample_close(mHandle);
|
resample_close(mHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif USE_LIBSAMPLERATE || USE_LIBSOXR
|
#elif USE_LIBSAMPLERATE
|
||||||
|
|
||||||
#include <samplerate.h>
|
#include <samplerate.h>
|
||||||
|
|
||||||
@ -138,16 +224,17 @@ bool Resample::ResamplingEnabled()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString Resample::GetResamplingLibraryName()
|
//v Currently unused.
|
||||||
{
|
//wxString Resample::GetResamplingLibraryName()
|
||||||
#ifdef USE_LIBSAMPLERATE
|
//{
|
||||||
return _("Libsamplerate by Erik de Castro Lopo");
|
//#ifdef USE_LIBSAMPLERATE
|
||||||
#elif USE_LIBSOXR
|
// return _("Libsamplerate by Erik de Castro Lopo");
|
||||||
return _("Libsoxr by Rob Sykes");
|
//#elif USE_LIBSOXR
|
||||||
#else
|
// return _("Libsoxr by Rob Sykes");
|
||||||
return _("Unknown");
|
//#else
|
||||||
#endif
|
// return _("Unknown");
|
||||||
}
|
//#endif
|
||||||
|
//}
|
||||||
|
|
||||||
int Resample::GetNumMethods()
|
int Resample::GetNumMethods()
|
||||||
{
|
{
|
||||||
@ -248,96 +335,4 @@ Resample::~Resample()
|
|||||||
src_delete((SRC_STATE *)mHandle);
|
src_delete((SRC_STATE *)mHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // No resampling support
|
|
||||||
|
|
||||||
bool Resample::ResamplingEnabled()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString Resample::GetResamplingLibraryName()
|
|
||||||
{
|
|
||||||
return _("Resampling disabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int Resample::GetNumMethods()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString Resample::GetMethodName(int index)
|
|
||||||
{
|
|
||||||
return _("Resampling disabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString Resample::GetFastMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/DisabledConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString Resample::GetBestMethodKey()
|
|
||||||
{
|
|
||||||
return wxT("/Quality/DisabledConverter");
|
|
||||||
}
|
|
||||||
|
|
||||||
int Resample::GetFastMethodDefault()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Resample::GetBestMethodDefault()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Resample::Resample(bool, double, double)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Resample::Ok()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Resample::Process(double factor,
|
|
||||||
float *inBuffer,
|
|
||||||
int inBufferLen,
|
|
||||||
bool lastFlag,
|
|
||||||
int *inBufferUsed,
|
|
||||||
float *outBuffer,
|
|
||||||
int outBufferLen)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int len = inBufferLen;
|
|
||||||
|
|
||||||
if (len > outBufferLen)
|
|
||||||
len = outBufferLen;
|
|
||||||
|
|
||||||
for(i=0; i<len; i++)
|
|
||||||
outBuffer[i] = inBuffer[i];
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
Resample::~Resample()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
|
||||||
// version control system. Please do not modify past this point.
|
|
||||||
//
|
|
||||||
// Local Variables:
|
|
||||||
// c-basic-offset: 3
|
|
||||||
// indent-tabs-mode: nil
|
|
||||||
// End:
|
|
||||||
//
|
|
||||||
// vim: et sts=3 sw=3
|
|
||||||
// arch-tag: ceb8c6d0-3df6-4b6f-b763-100fe856f6fb
|
|
||||||
|
|
||||||
|
154
src/Resample.h
154
src/Resample.h
@ -1,22 +1,11 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|
||||||
Audacity: A Digital Audio Editor
|
Audacity: A Digital Audio Editor
|
||||||
|
Audacity(R) is copyright (c) 1999-2012 Audacity Team.
|
||||||
|
License: GPL v2. See License.txt.
|
||||||
|
|
||||||
Dominic Mazzoni
|
Resample.cpp
|
||||||
|
Dominic Mazzoni, Rob Sykes, Vaughan Johnson
|
||||||
This class abstracts the interface to two different resampling
|
|
||||||
libraries:
|
|
||||||
|
|
||||||
libresample, written by Dominic Mazzoni based on Resample-1.7
|
|
||||||
by Julius Smith. LGPL.
|
|
||||||
|
|
||||||
libsamplerate, written by Erik de Castro Lopo. GPL. The author
|
|
||||||
of libsamplerate requests that you not distribute a binary version
|
|
||||||
of Audacity that links to libsamplerate and also has plug-in support.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
@ -27,51 +16,54 @@
|
|||||||
|
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
#include "Prefs.h"
|
||||||
#include "SampleFormat.h"
|
#include "SampleFormat.h"
|
||||||
|
|
||||||
class Resample
|
class Resample
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// The first parameter lets you select either the best method or
|
||||||
/// This will return true if Audacity is being compiled with
|
/// the fast method.
|
||||||
/// resampling support.
|
//v (The particular method used was previously set by
|
||||||
static bool ResamplingEnabled();
|
/// SetFastMethod or SetBestMethod.)
|
||||||
|
// minFactor and maxFactor
|
||||||
|
/// specify the range of factors that will be used, if you plan
|
||||||
|
/// to vary the factor over time. Otherwise set minFactor and
|
||||||
|
/// maxFactor to the same value for optimized performance.
|
||||||
|
Resample()
|
||||||
|
{
|
||||||
|
mMethod = 0;
|
||||||
|
mHandle = NULL;
|
||||||
|
mInitial = false;
|
||||||
|
};
|
||||||
|
virtual ~Resample() {};
|
||||||
|
|
||||||
/// Returns the name of the library used for resampling
|
/// Returns the name of the library used for resampling
|
||||||
/// (long format, may include author name and version number).
|
/// (long format, may include author name and version number).
|
||||||
static wxString GetResamplingLibraryName();
|
//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. This lets you query
|
/// tradeoff between speed and quality. This lets you query
|
||||||
/// the various methods available.
|
/// the various methods available.
|
||||||
static int GetNumMethods();
|
static int GetNumMethods() { return 1; };
|
||||||
static wxString GetMethodName(int index);
|
static wxString GetMethodName(int index) { return _("Resampling disabled."); };
|
||||||
|
|
||||||
/// 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. These are saved
|
/// method intended for mixing and exporting.
|
||||||
/// in the preferences when you call Set[Best,Fast]Method.
|
//v (These were previously saved
|
||||||
static int GetFastMethod();
|
/// in the preferences when you call Set[Best,Fast]Method.)
|
||||||
static int GetBestMethod();
|
int GetFastMethod() { return gPrefs->Read(GetFastMethodKey(), GetFastMethodDefault()); };
|
||||||
static void SetFastMethod(int index);
|
int GetBestMethod() { return gPrefs->Read(GetBestMethodKey(), GetBestMethodDefault()); };
|
||||||
static void SetBestMethod(int index);
|
//v Currently unused.
|
||||||
|
//static void SetFastMethod(int index);
|
||||||
|
//static void SetBestMethod(int index);
|
||||||
|
|
||||||
static const wxString GetFastMethodKey();
|
static const wxString GetFastMethodKey() { return wxT("/Quality/DisabledConverter"); };
|
||||||
static const wxString GetBestMethodKey();
|
static const wxString GetBestMethodKey() { return wxT("/Quality/DisabledConverter"); };
|
||||||
static int GetFastMethodDefault();
|
static int GetFastMethodDefault() { return 0; };
|
||||||
static int GetBestMethodDefault();
|
static int GetBestMethodDefault() { return 0; };
|
||||||
|
|
||||||
/// Constructor.
|
|
||||||
/// The first parameter lets you select either the best method or
|
|
||||||
/// the fast method - the particular method used was set by
|
|
||||||
/// SetFastMethod or SetBestMethod, above. minFactor and maxFactor
|
|
||||||
/// specify the range of factors that will be used, if you plan
|
|
||||||
/// to vary the factor over time. Otherwise set minFactor and
|
|
||||||
/// maxFactor to the same value for optimized performance.
|
|
||||||
Resample(bool useBestMethod, double minFactor, double maxFactor);
|
|
||||||
|
|
||||||
/// Returns true if the constructor succeeded.
|
|
||||||
bool Ok();
|
|
||||||
|
|
||||||
/** @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.
|
||||||
@ -95,33 +87,57 @@ 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
|
||||||
*/
|
*/
|
||||||
int Process(double factor,
|
virtual int Process(double factor,
|
||||||
float *inBuffer,
|
float *inBuffer,
|
||||||
int inBufferLen,
|
int inBufferLen,
|
||||||
bool lastFlag,
|
bool lastFlag,
|
||||||
int *inBufferUsed,
|
int *inBufferUsed,
|
||||||
float *outBuffer,
|
float *outBuffer,
|
||||||
int outBufferLen);
|
int outBufferLen)
|
||||||
|
{
|
||||||
|
// Base class method just copies data with no change.
|
||||||
|
int i;
|
||||||
|
int len = inBufferLen;
|
||||||
|
|
||||||
// Destructor
|
if (len > outBufferLen)
|
||||||
~Resample();
|
len = outBufferLen;
|
||||||
|
|
||||||
private:
|
for(i=0; i<len; i++)
|
||||||
int mMethod;
|
outBuffer[i] = inBuffer[i];
|
||||||
void *mHandle;
|
|
||||||
|
return len;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int mMethod; // resampler-specific enum for resampling method
|
||||||
|
void* mHandle; // constant-rate or variable-rate resampler (XOR per instance)
|
||||||
bool mInitial;
|
bool mInitial;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConstRateResample : public Resample
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConstRateResample(const bool useBestMethod, const double dFactor);
|
||||||
|
virtual ~ConstRateResample();
|
||||||
|
|
||||||
|
// Override base class methods only if we actually have a const-rate library.
|
||||||
|
#if 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);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#endif // __AUDACITY_RESAMPLE_H__
|
#endif // __AUDACITY_RESAMPLE_H__
|
||||||
|
|
||||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
|
||||||
// version control system. Please do not modify past this point.
|
|
||||||
//
|
|
||||||
// Local Variables:
|
|
||||||
// c-basic-offset: 3
|
|
||||||
// indent-tabs-mode: nil
|
|
||||||
// End:
|
|
||||||
//
|
|
||||||
// vim: et sts=3 sw=3
|
|
||||||
// arch-tag: bffbe34c-3029-47dc-af4c-f83d9a26002c
|
|
||||||
|
|
||||||
|
@ -1523,7 +1523,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;
|
||||||
::Resample* resample = new ::Resample(true, factor, factor);
|
ConstRateResample* resample = new ConstRateResample(true, factor);
|
||||||
|
|
||||||
int bufsize = 65536;
|
int bufsize = 65536;
|
||||||
float* inBuffer = new float[bufsize];
|
float* inBuffer = new float[bufsize];
|
||||||
|
@ -209,7 +209,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.
|
||||||
Resample resample(true, mFactor, mFactor);
|
ConstRateResample resample(true, mFactor);
|
||||||
|
|
||||||
//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.
|
||||||
|
@ -109,11 +109,17 @@ void QualityPrefs::GetNamesAndLabels()
|
|||||||
//------------- Converter Names
|
//------------- Converter Names
|
||||||
// We used to set and get best/fast method via Resample.cpp.
|
// We used to set and get best/fast method via Resample.cpp.
|
||||||
// Need to ensure that preferences strings in Resample.cpp match.
|
// 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.
|
||||||
// int converterHQ = Resample::GetBestMethod();
|
// int converterHQ = Resample::GetBestMethod();
|
||||||
// int converter = Resample::GetFastMethod();
|
// int converter = Resample::GetFastMethod();
|
||||||
int numConverters = Resample::GetNumMethods();
|
//
|
||||||
|
//vvvvv Note that we're now using libsoxr for constant-rate resampling
|
||||||
|
// and either libresample or libsamplerate for variable-rate,
|
||||||
|
// and currently *not* allowing 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(Resample::GetMethodName(i));
|
mConverterNames.Add(ConstRateResample::GetMethodName(i));
|
||||||
mConverterLabels.Add(i);
|
mConverterLabels.Add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,8 +175,8 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.SetStretchyCol(2);
|
S.SetStretchyCol(2);
|
||||||
|
|
||||||
S.TieChoice(_("Sample Rate Con&verter:"),
|
S.TieChoice(_("Sample Rate Con&verter:"),
|
||||||
Resample::GetFastMethodKey(),
|
ConstRateResample::GetFastMethodKey(),
|
||||||
Resample::GetFastMethodDefault(),
|
ConstRateResample::GetFastMethodDefault(),
|
||||||
mConverterNames,
|
mConverterNames,
|
||||||
mConverterLabels),
|
mConverterLabels),
|
||||||
S.SetSizeHints(mConverterNames);
|
S.SetSizeHints(mConverterNames);
|
||||||
@ -191,8 +197,8 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.StartMultiColumn(2);
|
S.StartMultiColumn(2);
|
||||||
{
|
{
|
||||||
S.TieChoice(_("Sample Rate Conver&ter:"),
|
S.TieChoice(_("Sample Rate Conver&ter:"),
|
||||||
Resample::GetBestMethodKey(),
|
ConstRateResample::GetBestMethodKey(),
|
||||||
Resample::GetBestMethodDefault(),
|
ConstRateResample::GetBestMethodDefault(),
|
||||||
mConverterNames,
|
mConverterNames,
|
||||||
mConverterLabels),
|
mConverterLabels),
|
||||||
S.SetSizeHints(mConverterNames);
|
S.SetSizeHints(mConverterNames);
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="2"
|
Optimization="2"
|
||||||
AdditionalIncludeDirectories=""$(WXWIN)\lib\vc_dll\mswu";"$(WXWIN)\include";..\..;..\..\..\src\include\win32;..\..\..\src\include;"..\..\..\lib-src\FileDialog";"..\..\..\lib-src\expat";"..\..\..\lib-src\ffmpeg\win32";"..\..\..\lib-src\ffmpeg";"..\..\..\lib-src\lib-widget-extra";"..\..\..\lib-src\libflac\include";"..\..\..\lib-src\libid3tag";"..\..\..\lib-src\liblrdf";"..\..\..\lib-src\libmad";"..\..\..\lib-src\libnyquist";"..\..\..\lib-src\libogg\include";"..\..\..\lib-src\libresample\include";"..\..\..\lib-src\libsamplerate\src";"..\..\..\lib-src\libscorealign";..\libsndfile;"..\..\..\lib-src\libvamp";"..\..\..\lib-src\libvorbis\include";"..\..\..\lib-src\portaudio-v19\include";"..\..\..\lib-src\portmixer\include";"..\..\..\lib-src\portsmf";"..\..\..\lib-src\redland\raptor\src";"..\..\..\lib-src\slv2";"..\..\..\lib-src\sbsms\include";"..\..\..\lib-src\soundtouch\include";"..\..\..\lib-src\twolame\libtwolame";"..\..\..\lib-src\portmidi\pm_common";"..\..\..\lib-src\portmidi\pm_win";"..\..\..\lib-src\portmidi\porttime""
|
AdditionalIncludeDirectories=""$(WXWIN)\lib\vc_dll\mswu";"$(WXWIN)\include";..\..;..\..\..\src\include\win32;..\..\..\src\include;"..\..\..\lib-src\FileDialog";"..\..\..\lib-src\expat";"..\..\..\lib-src\ffmpeg\win32";"..\..\..\lib-src\ffmpeg";"..\..\..\lib-src\lib-widget-extra";"..\..\..\lib-src\libflac\include";"..\..\..\lib-src\libid3tag";"..\..\..\lib-src\liblrdf";"..\..\..\lib-src\libmad";"..\..\..\lib-src\libnyquist";"..\..\..\lib-src\libogg\include";"..\..\..\lib-src\libresample\include";"..\..\..\lib-src\libsamplerate\src";"..\..\..\lib-src\libscorealign";..\libsndfile;"..\..\..\lib-src\libsoxr\src";"..\..\..\lib-src\libvamp";"..\..\..\lib-src\libvorbis\include";"..\..\..\lib-src\portaudio-v19\include";"..\..\..\lib-src\portmixer\include";"..\..\..\lib-src\portsmf";"..\..\..\lib-src\redland\raptor\src";"..\..\..\lib-src\slv2";"..\..\..\lib-src\sbsms\include";"..\..\..\lib-src\soundtouch\include";"..\..\..\lib-src\twolame\libtwolame";"..\..\..\lib-src\portmidi\pm_common";"..\..\..\lib-src\portmidi\pm_win";"..\..\..\lib-src\portmidi\porttime""
|
||||||
PreprocessorDefinitions="BUILDING_AUDACITY;FLAC__NO_DLL;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;NDEBUG;WIN32;STRICT"
|
PreprocessorDefinitions="BUILDING_AUDACITY;FLAC__NO_DLL;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;NDEBUG;WIN32;STRICT"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
@ -133,7 +133,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories=""$(WXWIN)\lib\vc_dll\mswud";"$(WXWIN)\include";..\..;..\..\..\src\include\win32;..\..\..\src\include;"..\..\..\lib-src\FileDialog";"..\..\..\lib-src\expat";"..\..\..\lib-src\lib-widget-extra";"..\..\..\lib-src\libflac\include";"..\..\..\lib-src\libid3tag";"..\..\..\lib-src\liblrdf";"..\..\..\lib-src\libmad";"..\..\..\lib-src\libnyquist";"..\..\..\lib-src\libogg\include";"..\..\..\lib-src\libresample\include";"..\..\..\lib-src\libsamplerate\src";"..\..\..\lib-src\libscorealign";..\libsndfile;"..\..\..\lib-src\libvamp";"..\..\..\lib-src\libvorbis\include";"..\..\..\lib-src\portaudio-v19\include";"..\..\..\lib-src\portmixer\include";"..\..\..\lib-src\portsmf";"..\..\..\lib-src\redland\raptor\src";"..\..\..\lib-src\slv2";"..\..\..\lib-src\sbsms\include";"..\..\..\lib-src\soundtouch\include";"..\..\..\lib-src\twolame\libtwolame";"..\..\..\lib-src\portmidi\pm_common";"..\..\..\lib-src\portmidi\pm_win";"..\..\..\lib-src\portmidi\porttime";"..\..\..\lib-src\ffmpeg\win32";"..\..\..\lib-src\ffmpeg""
|
AdditionalIncludeDirectories=""$(WXWIN)\lib\vc_dll\mswud";"$(WXWIN)\include";..\..;..\..\..\src\include\win32;..\..\..\src\include;"..\..\..\lib-src\FileDialog";"..\..\..\lib-src\expat";"..\..\..\lib-src\lib-widget-extra";"..\..\..\lib-src\libflac\include";"..\..\..\lib-src\libid3tag";"..\..\..\lib-src\liblrdf";"..\..\..\lib-src\libmad";"..\..\..\lib-src\libnyquist";"..\..\..\lib-src\libogg\include";"..\..\..\lib-src\libresample\include";"..\..\..\lib-src\libsamplerate\src";"..\..\..\lib-src\libscorealign";..\libsndfile;"..\..\..\lib-src\libsoxr\src";"..\..\..\lib-src\libvamp";"..\..\..\lib-src\libvorbis\include";"..\..\..\lib-src\portaudio-v19\include";"..\..\..\lib-src\portmixer\include";"..\..\..\lib-src\portsmf";"..\..\..\lib-src\redland\raptor\src";"..\..\..\lib-src\slv2";"..\..\..\lib-src\sbsms\include";"..\..\..\lib-src\soundtouch\include";"..\..\..\lib-src\twolame\libtwolame";"..\..\..\lib-src\portmidi\pm_common";"..\..\..\lib-src\portmidi\pm_win";"..\..\..\lib-src\portmidi\porttime";"..\..\..\lib-src\ffmpeg\win32";"..\..\..\lib-src\ffmpeg""
|
||||||
PreprocessorDefinitions="BUILDING_AUDACITY;FLAC__NO_DLL;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;__WXDEBUG__;_DEBUG;WIN32;STRICT"
|
PreprocessorDefinitions="BUILDING_AUDACITY;FLAC__NO_DLL;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;__WXDEBUG__;_DEBUG;WIN32;STRICT"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
|
@ -111,7 +111,9 @@ Global
|
|||||||
{7AA41BED-41B0-427A-9148-DEA40549D158}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
|
{7AA41BED-41B0-427A-9148-DEA40549D158}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
|
||||||
{7AA41BED-41B0-427A-9148-DEA40549D158}.Unicode Release|Win32.Build.0 = Unicode Release|Win32
|
{7AA41BED-41B0-427A-9148-DEA40549D158}.Unicode Release|Win32.Build.0 = Unicode Release|Win32
|
||||||
{F00717F2-67C8-44E1-AF00-541DFA9CB7F2}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
|
{F00717F2-67C8-44E1-AF00-541DFA9CB7F2}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
|
||||||
|
{F00717F2-67C8-44E1-AF00-541DFA9CB7F2}.Unicode Debug|Win32.Build.0 = Unicode Debug|Win32
|
||||||
{F00717F2-67C8-44E1-AF00-541DFA9CB7F2}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
|
{F00717F2-67C8-44E1-AF00-541DFA9CB7F2}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
|
||||||
|
{F00717F2-67C8-44E1-AF00-541DFA9CB7F2}.Unicode Release|Win32.Build.0 = Unicode Release|Win32
|
||||||
{3DDDCAA9-276D-4FC3-A15C-485F7B9B24CC}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
|
{3DDDCAA9-276D-4FC3-A15C-485F7B9B24CC}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
|
||||||
{3DDDCAA9-276D-4FC3-A15C-485F7B9B24CC}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
|
{3DDDCAA9-276D-4FC3-A15C-485F7B9B24CC}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
|
||||||
{F4B4A272-4ED3-4951-A6EE-B7BAAC1C4952}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
|
{F4B4A272-4ED3-4951-A6EE-B7BAAC1C4952}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
|
||||||
|
@ -22,10 +22,14 @@
|
|||||||
// #define USE_LIBLRDF 1
|
// #define USE_LIBLRDF 1
|
||||||
#define USE_LIBMAD 1
|
#define USE_LIBMAD 1
|
||||||
|
|
||||||
// Resampling -- should build only one of these.
|
// Resamplers
|
||||||
|
// libsoxr is used for constant-rate resampling.
|
||||||
|
#define USE_LIBSOXR 1
|
||||||
|
// Should build only one of libresample or libsamplerate for variable-rate resampling,
|
||||||
|
// but if both are defined, USE_LIBRESAMPLE is used and USE_LIBSAMPLERATE is not.
|
||||||
|
//vvvvv Turn back on after completing refactoring.
|
||||||
#undef USE_LIBRESAMPLE
|
#undef USE_LIBRESAMPLE
|
||||||
#undef USE_LIBSAMPLERATE
|
#undef USE_LIBSAMPLERATE
|
||||||
#define USE_LIBSOXR 1
|
|
||||||
|
|
||||||
#define USE_LIBTWOLAME 1
|
#define USE_LIBTWOLAME 1
|
||||||
#define USE_LIBVORBIS 1
|
#define USE_LIBVORBIS 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user