(首先,我可能会因为英语不好而感到抱歉,因为这不是我的母语。)
我使用FFmpeg解码某些音频文件并通过“流”(即“队列”和“OpenAL的”队列“功能)与OpenAL一起播放。
当我使用我的程序播放.ogg文件时,我发现它有一个变量nb_samples。(由于ogg有可变的比特率??)有128 B,512 B和1024 B的nb_samples。结果,我必须在使用alBufferSamplesSOFT(类似于alBufferData)之前调用alDeleteBuffers和alGenBuffers,因为它无法在不重新创建缓冲区的情况下调用alBufferSamplesSOFT。 注意:alBufferSamplesSOFT由OpenAL Soft提供。您可以将其视为alBufferData。
然而,如果我这样做,我认为这是愚蠢和低效的。有一些聪明的方法吗?我粘贴了部分代码:
while (av_read_frame(...) == 0){
avcodec_decode_audio4(...);
swr_convert(...); // to convert PCM format from FLTP to FLT
alDeleteBuffers(1, theBuffers[?]);
alGenBuffers(1, theBuffers[?]);
alBufferSamplesSOFT(...); // put those data into OpenAL buffer
}
如果我不这样做,它将无法更新OpenAL缓冲区。是否有任何方法可以创建可变大小的缓冲区或大型缓冲区?或者有什么方法可以改变缓冲区的大小吗?
谢谢你们。
答案 0 :(得分:0)
您可以依赖libavresample的FIFO功能(由FFmpeg支持),例如:
... decode the audio into srcaudio frame...
// Resample the input into the audioSampleBuffer until we proceed the whole decoded data
if ( (err = avresample_convert( audioResampleCtx,
NULL,
0,
0,
srcaudio.data,
0,
srcaudio.nb_samples )) < 0 )
{
warning( "Error resampling decoded audio: %d", err );
return -1;
}
while( avresample_available( audioResampleCtx ) >= audioFrame->nb_samples )
{
// Read a frame audio data from the resample fifo
if ( avresample_read( audioResampleCtx, audioFrame->data, audioFrame->nb_samples ) != audioFrame->nb_samples )
{
warning( "Error reading resampled audio: %d", err );
return -1;
}
这样,您将始终通过avresample_read
返回固定大小的缓冲区。如果您以比nb_samples更多的方式从源文件中生成样本来转换音频,那么它也会带来好处。
代码片段来自我的卡拉OK歌词编辑器;如果您需要更多信息,可以查看相应的源文件here。