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);