2

mp3ファイルを使ってギャップレスループを再生しようとしています。いくつかのチュートリアルを読んで、エンコーダー/デコレートされた遅延のようなものがあり、いくつかのツールを使用して適切な音楽データでそのギャップを埋めることができることを学びました. それも問題なく機能しましたが、その音楽をフラッシュで再生しようとすると(実際にはhaxe nmeですが、違いはないと思います)、別の遅延があることを発見しました。これは、おそらくフラッシュによって作成されたものです.media.Sound (実際、インターネットのコードでこのようなコメントがいくつか見つかりました)。

サウンドをより速くまたはより遅く再生する必要がある場合があるため、これが私のプレーヤーの動作方法です。

  • 抽出されたバイトはバイト var に格納されます
  • speed は float 変数、デフォルト = 1
  • 実際の位置をバイト単位で示す position var があります (バイトは多くのサウンド オブジェクトで共有されるため、bytes.position を簡単に使用することはできません)。
  • サウンドを再生しているときに、SampleDataEvent ハンドラーで、bytes.position = position * 8 を設定し、2 つのフロートを読み取って再生し、位置 += 速度を更新します。

私がすでに何か間違ったことをしている場合は、指摘してください。

その遅延を取り除くために、私は次のことを試みました。

  • DELAY変数を追加
  • audacity から読み取ったサウンドの長さをハードコーディングします (flash.media.Sound object.length は正確ではないようです。よくわかりませんが、mp3 デコーダー/エンコーダーの遅延が原因だと思います)。
  • 各サウンドが 128kbps、44.1kHz であると仮定する
  • DELAY を flash.media.Sound オブジェクトの bytesTotal に設定します - DELAY = ハードコードされた長さ * 128kbps

再生されますが、次のとおりです。

  1. audacity の mp3 には、まだ厄介なギャップがあります。
  2. mp3 ギャップを埋めるツール (ここからhttp://www.compuphase.com/mp3/mp3loops.htm ) からの mp3 は、より良く再生されますが、最初の音はクリアではありません。
  3. 音を止めた後、耳障りな「カチッ」という音が聞こえます。

(1) が発生する理由と、3 つの問題すべてを解決する方法を理解するのを手伝ってもらえますか?

4

1 に答える 1

0

Flash でギャップレス ループを実現するのは面倒ですが、可能です。

  • ギャップのない MP3 を作成するのは難しいため、この問題を完全に回避してください。MP3 ではなく、WAV ファイルとしてループをインポートします。WAV にはエンコーダーの遅延がなく、シームレスなループを簡単に作成できます。

  • サウンドをループするには、 Sound.play()の loops パラメータを使用します。オーディオが本当にギャップレスである場合、シームレスなループが生成されます。SOUND_COMPLETEイベントを使用してサウンドをループさせないでください。このイベントはフレーム レートに関連付けられており、実際にサウンドが終了したときではなく、サウンドが終了した直後に発生するため、常にギャップが発生します。

  • お気づきのように、Sound.length は通常正確ではありません。正確なサンプル数が本当に必要な場合は、Sound.extract()を使用して完全なオーディオ データを抽出します。抽出されたサンプルの数を返します。

  • 何らかの理由でギャップレス WAV ファイルを埋め込むことができない場合、または MP3 を外部の場所からストリーミングする必要がある場合は、次のようにします。

    1. Sound.extract() を使用してオーディオ データを抽出します。
    2. データの先頭と末尾の無音部分を切り取ります。ハードコードされた値を使用してこれを行うか、サンプルをいくつかの小さなイプシロンと比較して賢く切り取ることができます。
    3. Sound.loadPCMFromByteArray()を使用して、切り取ったデータをサウンド クリップに再読み込みします。
    4. トリミングされたクリップは、Sound.play と loops パラメータでループできるようになりました。

サンプルコードは次のとおりです。

// load our original audio track and extract the samples
var music:Sound = new Music();
var data:ByteArray = new ByteArray();
music.extract(data,99999999);
data.position = 0;

// crop off silent samples from the beginning
// TODO: you should also do this for the end
var i:uint = 0;
const EPSILON:Number = 0.05;
var sample:Number = 0;
// step forward until the magnitude exceeds some threshold
while(data.bytesAvailable > 8 && sample < EPSILON) {
    sample = Math.abs(data.readFloat()) + Math.abs(data.readFloat());
}

// now, data.position is the location where the audio first kicks in
// let's crop it
var croppedData:ByteArray = new ByteArray();
croppedData.writeBytes(data, data.position);
croppedData.position = 0;

// load our newly cropped data and loop
music = new Sound();
music.loadPCMFromByteArray(croppedData, croppedData.length / 8);
music.play(0,99999);

これは、SampleDataEvent を使用してリアルタイムでギャップをスキップしようとするよりもはるかに簡単で、プロセッサへの負荷も少なくなります。SampleDataEvent を使用して動的な再生が本当に必要な場合でも、この方法は、ギャップのないオーディオ データの適切なチャンクを提供するのに役立ちます。

上記は Flash にのみ適用されることに注意してください。NME を使用しているため、パッケージ化中に NME がサウンドをいじる可能性があり、上記の機能がすべてのターゲットで使用できるわけではないため、これによりしわが追加されます。ただし、Flash ターゲットのみをパブリッシュしている場合でも、これらの手法は有効です。

于 2013-03-15T12:07:04.430 に答える