音频重采样

采样率转换的开源代码框架有resample、libresamplesndfile-resamplelibresample4j等。

libresample andsndfile-resample (fromlibsamplerate) (in the Planet CCRMA Distribution).

libsoxr , the SoX resampler library ssrc  (from Shibatch) There is a project combining  ssrc andsox New in 2016 is a Python (Cython) implementation: resampy Brick  (on Github ). 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. 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/

猜你喜欢

转载自blog.csdn.net/jzjhome/article/details/75270441