音频重采样

来源:互联网 发布:网络连接失败 编辑:程序博客网 时间:2024/06/05 04:28

采样率转换的开源代码框架有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 (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 onresample.
  • 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