PCM声音重采样库libsample的使用

在openwrt上使用ALSA播放语音, 因为要适应不同的采样率的声音源

alsa声卡播出统一使用48k采样率,声音源不是48K的, 需要使用 libsamplerate库进行resample

这里有下载:

https://src.fedoraproject.org/repo/pkgs/libsamplerate/libsamplerate-0.1.8.tar.gz/1c7fb25191b4e6e3628d198a66a84f47/libsamplerate-0.1.8.tar.gz

在openwrt SDK环境下make menuconfig -> Libraries->libsamplerate 就可以编译出动态库和静态库

我用的静态库libsamplerate.a直接link到程序中。

1)使用src_simple单个函数就可以了:

               SRC_DATA    src_data;

                src_data.end_of_input = 0 ; /* Set this later. */
                /* Start with zero to force load in while loop. */
                src_data.input_frames  = payload_bytes ;//待转数据帧数
                src_data.output_frames = AUDIO_FRAME_SIZE ;//转换结果数据缓冲区帧数
                src_data.data_in  = pcm_resample_in ;//转换输入缓冲区
                src_data.data_out = pcm_resample_out ;//转换输出缓冲区
                src_data.src_ratio = 1.0*AUDIO_FRAME_SIZE/payload_bytes ;//等同于新采样率除以原采样率

                if(0 == src_simple(&src_data, SRC_LINEAR, 1)){
                    memset(pcm16R, 0, sizeof(pcm16R));
                    for(i=0;i<AUDIO_FRAME_SIZE; i++){
                        pcm16L[i] = (int16_t)pcm_resample_out[i];
                    }

                    
                    play_sound(pcm16L, pcm16R, AUDIO_FRAME_SIZE);

                }

//---------------在连续转换多个AUDIO_FRAME_SIZE时,播放由咔咔声

2)使用src_process进行连续转换可以消除咔咔声(参考代码在库自带的exaple/sndfile-resample.c

      初始化:

                  static SRC_STATE    *src_state =NULL;

                  static SRC_DATA    src_data ;

                   int error =-1;
                   src_state = src_new (SRC_LINEAR, 1, &error);

                src_data.data_in = pcm_resample_in ;
                src_data.src_ratio = 1.0*AUDIO_FRAME_SIZE/payload_bytes ; //等同于新采样率除以原采样率
                src_data.data_out = pcm_resample_out ;//转换输出缓冲区
                src_data.output_frames = AUDIO_FRAME_SIZE /1/*channels*/ ;//转换输出缓冲区的大小

      2) 连续转换

           while(1)    {

                   if (src_data.input_frames == 0)                {

                    src_data.input_frames = payload_bytes; //下一段待转数据缓冲区,
                    src_data.data_in = pcm_resample_in ;//待转数据帧数,也就是采样次数
                }

                //这种resample方法效率比src_simple()高点, 不 容易出现咔咔声音

                if ((0 == src_process (src_state, &src_data)) && (src_data.output_frames_gen >0)){
                    memset(pcm16R, 0, sizeof(pcm16R));
                    for(i=0;i<src_data.output_frames_gen; i++){//src_data.output_frames_gen 是转换成功的帧数(新采样率为标准)
                        pcm16L[i] = (int16_t)pcm_resample_out[i];
                    }
                    play_sound(pcm16L, pcm16R, src_data.output_frames_gen);


                    src_data.data_in      += src_data.input_frames_used * 1/*channel*/ ;
                    src_data.input_frames -= src_data.input_frames_used ;
                    src_data.output_frames_gen = 0;

                }

         }

分析: 2)不带咔咔声, 因为每次转换衔接处实现了平滑过渡, 而1)做不到平滑过渡

猜你喜欢

转载自blog.csdn.net/twd_1991/article/details/80349286