2016-10-14 10 views
1

私は、MediaCodecを使用してビデオファイルのオーディオトラックに参加することができました。両方のオーディオトラックのチャンネル数とサンプルレートが同じであれば問題ありません。48kHzから44.1kHzへのAndroidのリサンプリング、純粋なJava、またはOpenSL ES?

(オリジナルトラックが22050ヘルツであり、元のトラックが24000ヘルツであれば48000 Hzの2チャンネルオーディオを出力する場合は、何らかの理由でOMX.SEC.aac.decは常に44100 Hzの2チャンネルオーディオを出力する。)

問題が登場私は22050Hzのオーディオトラックの後に24000Hzのオーディオトラックを追加しようとします。上記の両方のトラックからなる22050 Hzのオーディオトラックを出力したいと思えば、私は24000 Hzのオーディオをリサンプリングする必要があります。

私はこれを試してみました:

private byte[] minorDownsamplingFrom48kTo44k(byte[] origByteArray) 
{ 
    int origLength = origByteArray.length; 
    int moddedLength = origLength * 147/160; 
    int delta = origLength - moddedLength; 
    byte[] resultByteArray = new byte[moddedLength]; 
    int arrayIndex = 0; 
    for(int i = 0; i < origLength; i+=11) 
    { 
     for(int j = i; j < i+10; j++) 
     { 
      resultByteArray[arrayIndex] = origByteArray[j]; 
      arrayIndex++; 
     } 
    } 
    return resultByteArray; 
} 

これは、3700-何かがバイトと非常に大きなスクランブル音の背後にエンコード...後に正しいオーディオのバイト配列を返します。

私の質問:

  1. どのように私が正しく、このようなアーティファクトを残さずにオーディオトラックをダウンサンプリングしますか?私は平均値を使うべきですか?
  2. OpenSL ESを使用して実装されたリサンプラを使用して、処理を高速かつ/またはより良くする必要がありますか?
+0

データはおそらく16ビットですが、特に2つのチャンネルの場合は、データからバイトをスキップできません。また、適切に処理したい場合は、エイリアシングアーチファクトなどがないことを確認するために最終結果をフィルタリングする必要があります。しかし、私は最初の部分が主な問題だと思います。 40バイトをコピーして4をスキップすると、それが解決される可能性があります。 –

+0

16ビットでアップサンプリングされています(ソースは22050 Hzのサンプルレートを持ち、デコーダの出力は44100 Hzでした)。とにかく、このフィルタをJavaでサンプルごとにどのように適用するのですか? – Gensoukyou1337

+0

40バイトをコピーして4つの作業をスキップしますが、最終出力ビデオのオーディオはビデオ全体をより遅い速度で再生します。 – Gensoukyou1337

答えて

1

主な問題は、あなたがサンプルをスキップしなければならないとき、あなただけのバイトをスキップしていることです。

各サンプルは16ビットなので、2バイトです。オーディオがステレオの場合は、1サンプルにつき4バイトです。あなたは常に多くのバイトをスキップしなければなりません。そうしないと、サンプルが完全に混ざります。

同じ比率(10/11)を使用すると、40/44を使用して常に4バイトのサンプルをスキップし、サンプルを適切に保つことができます。

結果のビデオが異なるスピードで再生される理由については、まったく異なるものです。

関連する問題