采样率转换的开源代码框架有resample、libresample、sndfile-resample、libresample4j
等。
libresample andsndfile-resample
(fromlibsamplerate
) (in the Planet CCRMA Distribution).
libsoxr
, the SoX resampler libraryssrc
(from Shibatch)- There is a project combining
ssrc
andsox
- New in 2016 is a Python (Cython) implementation:resampy
- Brick (onGithub).
- Smarc, available as a command-line program or C library.
- The resample software package contains free sampling-rate conversion and filter design utilities written in C.
- Older Version for NeXT Computers.
- Original 1983+ source for the PDP KL-10.
- Erik de Castro Lopo's "SecretRabbitCode"
libsamplerate
-
libresample
based on `resample-1.7P -
libresample4j
is a Java port oflibresample
. - Open Source Audio Library Project (OSALP) contains a C++ class based on
resample
. - The Speex speech coder/decoder.
- More at another large list of implementations and their relative performance. 文本重点介绍 libresample 的使用方法。转换器类型enum
{
SRC_SINC_BEST_QUALITY = 0,
SRC_SINC_MEDIUM_QUALITY = 1,
SRC_SINC_FASTEST = 2,
SRC_ZERO_ORDER_HOLD = 3,//零阶采样和保持器
SRC_LINEAR = 4,//插值
} ;//简单转换函数
int src_simple (SRC_DATA *data, int converter_type, int channels) ;具体参考samplerate.h头文件。 - 调用实例:
-
int convert2(unsigned char* bufferAAC, size_t buf_sizeAAC, unsigned char* bufferPCM, size_t & buf_sizePCM)
{
unsigned char* pcm_data = NULL;
if (!m_bNeAACDecInit)
{
//initialize decoder
NeAACDecInit(decoder, bufferAAC, buf_sizeAAC, &samplerate, &channels);
printf("samplerate %d, channels %d\n", samplerate, channels);
m_bNeAACDecInit = true;
}
//decode ADTS frame
pcm_data = (unsigned char*)NeAACDecDecode(decoder, &frame_info, bufferAAC, buf_sizeAAC);if (frame_info.error > 0)
{
printf("%s\n", NeAACDecGetErrorMessage(frame_info.error));
return -1;
}
else if (pcm_data && frame_info.samples > 0)
{
printf("frame info: bytesconsumed %d, channels %d, header_type %d\
object_type %d, samples %d, samplerate %d\n",
frame_info.bytesconsumed,
frame_info.channels, frame_info.header_type,
frame_info.object_type, frame_info.samples,
frame_info.samplerate);buf_sizePCM = frame_info.samples * frame_info.channels;
memcpy(bufferPCM,pcm_data,buf_sizePCM);
//采样率变成8000HZ
float in[4096] = { 0 };
float out[4096] = { 0 };
int j = 0;
for (j = 0; j < 4096 && j < buf_sizePCM; j++)
{
in[j] = pcm_data[j];
}
SRC_DATA dataResample;
dataResample.data_in = in;
dataResample.data_out = out;
dataResample.input_frames = frame_info.samples;
dataResample.output_frames = frame_info.samples;
dataResample.src_ratio = 8000.0/frame_info.samplerate;
int nRetResample = 0;
//在测试过程中发现,如果是frame_info.samplerate%8000是非整数倍,用SRC_LINEAR方法转换采样率的话,效果很差。
if(frame_info.samplerate%8000 == 0)
{
nRetResample = src_simple(&dataResample,SRC_LINEAR, frame_info.channels);
}
else
{
nRetResample = src_simple(&dataResample,SRC_ZERO_ORDER_HOLD, frame_info.channels);
}
/*
buf_sizePCM = dataResample.output_frames_gen * frame_info.channels;
for (j = 0; j < 4096 && j < buf_sizePCM; j++)
{
bufferPCM[j] = Float2UChar(dataResample.data_out[j]);
}
*/
//声道变成单声道
buf_sizePCM = dataResample.output_frames_gen * frame_info.channels;
if(frame_info.channels == 2)
{
//从双声道的数据中提取单通道
int i = 0;
for (i = 0, j = 0; i<4096 && i<buf_sizePCM && j<2048; i += 4, j += 2)
{
bufferPCM[j] = Float2UChar(out[i]);
bufferPCM[j + 1] = Float2UChar(out[i + 1]);
}
buf_sizePCM = buf_sizePCM/2;
}
else
{
memcpy(bufferPCM,out,buf_sizePCM);
}
/*
//声道变成单声道
if(frame_info.channels == 2)
{
//从双声道的数据中提取单通道
for (int i = 0, j = 0; i<4096 && i<buf_sizePCM && j<2048; i += 4, j += 2)
{
bufferPCM[j] = pcm_data[i];
bufferPCM[j + 1] = pcm_data[i + 1];
}
buf_sizePCM = buf_sizePCM/2;
memcpy(bufferPCM,bufferPCM,buf_sizePCM);
}
else
{
memcpy(bufferPCM,pcm_data,buf_sizePCM);
}
*/
return 0;
}return -1;
}
libsamplerate-vs2008下载地址: http://download.csdn.net/detail/byxdaz/9722122 - resample-1.7:http://www-ccrma.stanford.edu/~jos/resample/
-
libsample: https://github.com/minorninth/libresample
-