2

libswresample を使用して、任意の PCM 形式から 44.1kHz、16 ビット int、ステレオにリサンプリングしています。

得られたオーディオ ストリームのオーディオ ボリューム分析をいじっていたところ、ソースとして 44.1kHz、16 ビット int モノラルを使用している場合、おおよそ次のようなフォーミュラーがあることがわかりました。

leftSample = sourceSample / sqrt(2);
rightSample = sourceSample / sqrt(2);

しかし、私は期待していました:

leftSample = sourceSample;
rightSample = sourceSample;

(ソースがステレオの場合は、単純にleftSample = leftSourceSample; rightSample = rightSourceSample;.)

私の期待は、いくつかの情報源から来ています。

  1. それが、おそらく私自身の率直な解決策だったでしょう。
  2. 私は少し調べてみましたが、他の人も同じことをしているようです
  3. 非常に一般的な ReplayGain 実装 (私が実際に知っている唯一のもので、基本的にどこでも使用されています。最初は mp3gain からだと思います。1 つのコピーはここで見ることができます) では、次のことも行います。

    switch ( num_channels) {
    case  1: right_samples = left_samples;
    case  2: break;
    default: return GAIN_ANALYSIS_ERROR;
    }
    

    これは特にです。ReplayGainは、モノラルのリファレンス サウンド (ピンク ノイズ、ここからダウンロードできます) を使用して、この実装によって調整されているためです。

    ReplayGain 仕様では、このようにも計算されます (こちらを参照)。

ReplayGain を自分で実装しようとしたときに混乱が生じ、これに出くわしました。

それで、いくつかの質問:

  1. libswresample がこれを行うのはなぜですか?
  2. これは libswresample またはバグで予想されますか? (ソース (例:ここ)から理解しようとしていますが、まだ完全には理解していません。) バグ レポートをここに追加しました。
  3. 「正しい」解決策は何ですか?
  4. 他のプレイヤーは何をしていますか?
  5. モノサンプルを供給した場合、一般的なサウンドカードは何をしますか?

(私はこの質問をavp.stackexchangeにも投稿しました。おそらく、これについて質問するのに適した場所です。よくわかりません。)

4

1 に答える 1

3

この実装は、モノラル信号をステレオ フィールドに「パンニング」する正しい実装の 1 つです。パンする場合、代わりに左端または右端に信号強度を中央でパンした場合と同じにする必要があるため、左にパンした場合は次のようになります。

//left panning
leftSample = sourceSample;
rightSample = 0;
//right panning
leftSample = 0;
rightSample = sourceSample;
//center panning (same power as hard left/right conversion/)
leftSample = sourceSample * sqrt(2)/2;
rightSample = sourceSample * sqrt(2)/2;

ただし、モノラルからステレオに変換している場合は、その直感は正しいです。中央の信号とパンされた信号を比較することはないので、レベルを下げる理由はありません。最善の方法は、信号を最大強度のままにしておくことです。

//mono to stereo conversion
leftSample = sourceSample;
rightSample = sourceSample;

また、S/R 変換後のゲインの変化がいくらか残っている可能性もありますが、そのレベルは恣意的に見えます。

于 2012-10-04T02:09:20.167 に答える