sonic.cpp 是一个音频处理库,可以实现倍速播放。
如果单纯通过修改pcm的采样率来实现音频倍速播放的话,就会出现声音变调的情况。
以下是通过采集windows 虚拟声卡获取到的音频数据,
我的声卡采样率是44100次/秒,audio_buffer_size 设置为100,这样每次采样的样本数是4410次,相当于采集100ms的pcm数据。
AVFormatContext* avFormatCxt = NULL;
AVDictionary* options = NULL;
char* devicename = const_cast<char*>("audio=Line 1 (Virtual Audio Cable)");
string devicename_utf8_str = GbkToUtf8(devicename);
char* devicename_utf8 = const_cast<char*>(devicename_utf8_str.c_str());
avdevice_register_all();
AVInputFormat* inFormat = av_find_input_format("dshow");
av_dict_set(&options, "audio_buffer_size", "100", 0);
int ret = avformat_open_input(&avFormatCxt, devicename_utf8, inFormat, &options);
AVPacket av_packet;
FILE* out_file_ptr2 = fopen(".\\speed15x.pcm", "wb+");// 初始化部分:先创建一个流
sonicStream tempoStream_;
// 参数为采样率和声道数
tempoStream_ = sonicCreateStream(44100, 2); //采样率与通道数
float speed = 1.5;//1.5倍速
sonicSetSpeed(tempoStream_, speed);
sonicSetPitch(tempoStream_, 1.0);
sonicSetRate(tempoStream_, 1.0);uint8_t** src_data;
int src_linesize = 0;
// 88200/2/2
// 给src_data 分配空间 创建输入缓冲区
av_samples_alloc_array_and_samples(&src_data, // 输出缓冲区地址&src_linesize, // 缓冲区大小2, // 通道数2 4410, // 采样个数 多少算一个音频帧呢?AV_SAMPLE_FMT_S16, // 采样格式 0);while (av_read_frame(avFormatCxt, &av_packet) == 0) {memcpy((void *)src_data[0], (void *)av_packet.data, av_packet.size);ret = sonicWriteShortToStream(tempoStream_, (short*)src_data[0], 4410); //4410为每次采样的样本数量int numSamples = 4410 / speed;int new_buffer_size = 0;if (ret) {// 从流中读取处理好的数据new_buffer_size = sonicReadShortFromStream(tempoStream_, (short*)src_data[0], numSamples); //返回的是采样数}fwrite(src_data[0], new_buffer_size * 2 * 2, 1, out_file_ptr2);// av_packet_unref(&av_packet); //释放内存
}
fclose(out_file_ptr2);
sonicDestroyStream(tempoStream_);
// 释放输入输出缓冲区
if (src_data) {av_freep(&src_data[0]);
}
av_freep(&src_data);
avformat_close_input(&avFormatCxt);