2016-09-20 9 views
0

ffmpeg/libswresampleを使用して、C++アプリケーションでストリーミングオーディオを再サンプリングしようとしています。サンプル幅の変更はうまくいき、期待通りの結果が得られます。しかし、サンプルレートを変更すると結果はやや割れてしまいます。私はそれがlibswresampleライブラリの誤った使用によるものか、私がリサンプリングの理論を誤解しているかどうか不安です。ここでlibswresample:サンプルが十分に生成されない

は、デモンストレーションのために簡略化され、私のリサンプリングプロセスである:

//Externally supplied data 
const uint8_t* in_samples //contains the audio data to be resampled 
int in_num_samples = 256 

//Set up resampling context 
SwrContext *swr = swr_alloc(); 
av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); 
av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); 
av_opt_set_int(swr, "in_sample_rate", 44100, 0); 
av_opt_set_int(swr, "out_sample_rate", 22050, 0); 
av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0); 
av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); 
swr_init(swr); 

//Perform the resampe 
uint8_t* out_samples; 
int out_num_samples = av_rescale_rnd(swr_get_delay(swr, in_samplerate) + in_num_samples, out_samplerate, in_samplerate, AV_ROUND_UP); 
av_samples_alloc(&out_samples, NULL, out_num_channels, out_num_samples, AV_SAMPLE_FMT_FLT, 0); 
out_num_samples = swr_convert(swr, &out_samples, out_num_samples, &in_samples, in_num_samples); 
av_freep(&out_samples); 
swr_free(&swr); 

私はリサンプリングオーディオは右鳴らない理由は、私はそれが(数128を返すことを期待swr_convert()のでリターン112、であることを疑います 4400のサンプラーレートから22050のサンプレートにダウンサンプリングすると、128サンプルが得られますが、swr_convert()は112サンプルを生成しています。オーディオの長さの観点から表現すると、これも困惑しています。 44100 = 5.8msで256サンプル、22050 = 112.7msで112サンプル。ダウンサンプリングプロセスは、リサンプリングされたオーディオの期間を変更してはいけませんか?

また、ffmpegで提供されている例を紹介しました。この例では、swr_convert()も期待していたよりも小さい数値を返します。だから、問題はlibswresampleのバグではなく、むしろ私自身の理解の欠如によるものではないかと思う。

+0

もっと大きなサイズのout_samples配列で試してみてください。計算に問題があると思われます。 –

答えて

2

サンプルの数が減少するのは、リサンプリングが時間的に隣接するいくつかのサンプルにわたってフィルタリングするためです。 32タップフィルターを使用してリサンプリングしているとします。サンプル127は127-16から127 + 16の入力が必要です(またはサンプルレート調整で補正された相当の位置)。入力サンプルは128個しかないので、この例では112まで出力できます。残りは、次の入力が使用可能になるまで内部キューに格納されます。

最後の(末尾の)サンプルを取得するには(入力が終了したとき)、入力としてNULLを入力します。これにより、内部キューがフラッシュされます。

+0

それはトリック、あなたの迅速な返答のおかげでやった!したがって、リアルタイムコンテキストで使用する場合、次回swr_convert()が呼び出されたとき、その入力サンプルは前回の呼び出しで省略された最後のものから始める必要があります。これは正しいです? – Tsherr

+0

いいえ、swr_convert()は入力サンプルをキャッシュします。入力すると同時にすべてのサンプルが出力されるとは限りません。つまり、swr_convert()にわずかな遅延が生じることが予想されます。 –

+0

私は見て、今気分になります。再度、感謝します! – Tsherr

関連する問題