libsamplerate resampling

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@715 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 19 years ago
parent 4284187a82
commit ab2b4367d9

@ -27,6 +27,12 @@ CPPFLAGS += -D_DEBUG \
#LIBSPANDSP_STATIC = yes
#LIBSPANDSP_LDIR = /usr/local/lib/
# compile with sample rate conversion from secret rabbit code?
# (see http://www.mega-nerd.com/SRC/)
#
#USE_LIBSAMPLERATE = yes
LDFLAGS += -lm
OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")

@ -39,6 +39,8 @@
#include <typeinfo>
#define SYSTEM_SAMPLERATE 8000 // fixme: sr per session
/** \brief structure to hold loaded codec instances */
struct CodecContainer
{
@ -246,6 +248,10 @@ AmAudio::AmAudio()
: fmt(new AmAudioSimpleFormat(CODEC_PCM16)),
max_rec_time(-1),
rec_time(0)
#ifdef USE_LIBSAMPLERATE
, resample_state(NULL),
resample_buf_samples(0)
#endif
{
}
@ -258,6 +264,10 @@ AmAudio::AmAudio(AmAudioFormat *_fmt)
AmAudio::~AmAudio()
{
#ifdef USE_LIBSAMPLERATE
if (NULL != resample_state)
src_delete(resample_state);
#endif
}
void AmAudio::close()
@ -384,6 +394,54 @@ unsigned int AmAudio::downMix(unsigned int size)
samples.swap();
}
#ifdef USE_LIBSAMPLERATE
if (fmt->rate != SYSTEM_SAMPLERATE) {
if (!resample_state) {
int src_error;
// for better quality but more CPU usage, use SRC_SINC_ converters
resample_state = src_new(SRC_LINEAR, 1, &src_error);
if (!resample_state) {
ERROR("samplerate initialization error: ");
}
}
if (resample_state) {
if (resample_buf_samples + PCM16_B2S(s) > PCM16_B2S(AUDIO_BUFFER_SIZE) * 2) {
WARN("resample input buffer overflow! (%d)\n",
resample_buf_samples + PCM16_B2S(s));
} else {
signed short* samples_s = (signed short*)(unsigned char*)samples;
src_short_to_float_array(samples_s, &resample_in[resample_buf_samples], PCM16_B2S(s));
resample_buf_samples += PCM16_B2S(s);
}
SRC_DATA src_data;
src_data.data_in = resample_in;
src_data.input_frames = resample_buf_samples;
src_data.data_out = resample_out;
src_data.output_frames = PCM16_B2S(AUDIO_BUFFER_SIZE);
src_data.src_ratio = (double)SYSTEM_SAMPLERATE / (double)fmt->rate;
src_data.end_of_input = 0;
int src_err = src_process(resample_state, &src_data);
if (src_err) {
DBG("resample error: '%s'\n", src_strerror(src_err));
}else {
signed short* samples_s = (signed short*)(unsigned char*)samples;
src_float_to_short_array(resample_out, samples_s, src_data.output_frames_gen);
s = PCM16_S2B(src_data.output_frames_gen);
if (resample_buf_samples != (unsigned int)src_data.input_frames_used) {
memmove(resample_in, &resample_in[src_data.input_frames_used],
(resample_buf_samples - src_data.input_frames_used) * sizeof(float));
}
resample_buf_samples = resample_buf_samples - src_data.input_frames_used;
}
}
}
#endif
return s;
}

@ -40,6 +40,10 @@ using std::auto_ptr;
using std::string;
#include <map>
#ifdef USE_LIBSAMPLERATE
#include <samplerate.h>
#endif
#define PCM16_B2S(b) ((b) >> 1)
#define PCM16_S2B(s) ((s) << 1)
@ -203,6 +207,13 @@ private:
int rec_time; // in samples
int max_rec_time;
#ifdef USE_LIBSAMPLERATE
SRC_STATE* resample_state;
float resample_in[PCM16_B2S(AUDIO_BUFFER_SIZE)*2];
float resample_out[PCM16_B2S(AUDIO_BUFFER_SIZE)];
size_t resample_buf_samples;
#endif
protected:
/** Sample buffer. */
DblBuffer samples;

@ -56,6 +56,10 @@ ifdef USE_SPANDSP
CPPFLAGS += -DUSE_SPANDSP -D__STDC_LIMIT_MACROS
endif
ifdef USE_LIBSAMPLERATE
CPPFLAGS += -DUSE_LIBSAMPLERATE
LDFLAGS +=-lsamplerate
endif
# implicit rules
%.o : %.cpp %.d

Loading…
Cancel
Save