6

ミキサーを構築し、すべてのシーケンスを配列に保存してからもう一度再生しました。ミックスを MP3 として保存したいのですが、ミックスを保存する方法を探していましたが、サウンドを byteArrays としてロードすることが答えでした。 (sound.extract) 私はそれを完成させましたが、MP3 として保存するためにすべてのサウンドを 1 つの ByteArray に保存する方法がよくわかりません。たとえば、2 つのオーディオ ファイルをロードして保存するこのコードを取得しました。 ByteArrays を分離し、各サウンドを再生します。2 つの byteArrays を 1 つに格納する方法を知っている人はいますか?

var mySound:Sound = new Sound(); 
var sourceSnd:Sound = new Sound(); 
var urlReq:URLRequest = new URLRequest("Track1.mp3"); 
sourceSnd.load(urlReq); 
sourceSnd.addEventListener(Event.COMPLETE, loaded); 
function loaded(event:Event):void 
{ 
    mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound); 
    //mySound.play(); 
} 

var mySound2:Sound = new Sound(); 
var sourceSnd2:Sound = new Sound(); 
var urlReq2:URLRequest = new URLRequest("Track2.mp3"); 
sourceSnd2.load(urlReq2); 
sourceSnd2.addEventListener(Event.COMPLETE, loaded2); 
function loaded2(event:Event):void 
{ 
    mySound2.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound2); 
    mySound2.play(); 
    mySound.play(); 
} 



function processSound(event:SampleDataEvent):void 
{ 
        var bytes:ByteArray = new ByteArray(); 
        sourceSnd.extract(bytes, 8192); 
    event.data.writeBytes(bytes); 
} 

function processSound2(event:SampleDataEvent):void 
{ 
        var bytes:ByteArray = new ByteArray(); 
        sourceSnd2.extract(bytes, 8192); 
    event.data.writeBytes(bytes); 
} 
4

3 に答える 3

7

しばらくの間同様のシステムに取り組んできたので、方向性を示すために最善を尽くします。

あなたのコード例は、実際には MP3 をミキシングしているわけではありません。SampleDataEvent を介してロードされた MP3 を再生するために、さらに 2 つのサウンドを作成しています。必要なことは、ミックスされたサウンドを保持/再生する「出力」サウンド ファイルを 1 つだけ作成することです。そのデータを簡単に保存し、その後そのファイルを新しい WAV/MP3/what-have-you として保存できます。

リアル/疑似コード (read:lazy) :

output = new Sound();

output.addEventListener( SampleDataEvent.SAMPLE_DATA , mixAudio );

song1 = new Sound / load the first mp3

song2 = new Sound / load the second mp3

// a byteArray for "recording" the output and subsequent file creation
recordedBytes = new ByteArray();

両方の mp3 が完全にロードされるまで待つか、エンター フレームを実行して、両方のサウンドがバッファリングされなくなったことを判断します (Sound.isBuffering )。

mp3 の準備ができたら:

// numbers to store some values

var left1:Number;
var right1:Number;

var left2:Number;
var right2:Number;

// bytearrays for extracting and mixing
var bytes1:ByteArray = new ByteArray( );
var bytes2:ByteArray = new ByteArray( );

// start the show
output.play();


function mixAudio( e:SampleDataEvent ):void{
  //set bytearray positions to 0

  bytes1.position = 0;
  bytes2.position = 0;

  //extract

  song1.extract( bytes1, 8192 );
  song2.extract( bytes2, 8192 );

  // reset bytearray positions to 0 for reading the floats

  bytes1.position = 0;
  bytes2.position = 0;

  // run through all the bytes/floats

  var b:int = 0;

  while( b < 8192 ){

     left1 = bytes1.readFloat();  // gets "left" signal
     right1 = bytes1.readFloat(); // gets "right" signal

     left2 = bytes2.readFloat();
     right2 = bytes2.readFloat();


     // mix!

     var newLeft:Number = ( left1 + left2 ) * .5; 
     var newRight:Number = ( right1 + right2 ) * .5;

     // write the new stuff to the output sound's

     e.data.writeFloat( newLeft );
     e.data.writeFloat( newRight );

     // write numbers to the "recording" byteArray
     recordedBytes.writeFloat( newLeft );
     recordedBytes.writeFloat( newRight );

     b++;

  }
}

はい - 可能な出力を -1/1 に制限する必要があります。やれ。これは非常に最適化されていません。

Ok。それは簡単な部分です!難しいのは、実際に最終的な byteArray を MP3 に変換することです。オーディオは PCM/非圧縮データとして Flash 内に存在します。MP3 は明らかに圧縮形式です。この「答え」はすでに長すぎます。この情報はすべて、非常に賢い人々から収集したものです。

「MicRecorder」を汎用のサウンド データ レコーダーに簡単に適合させることができます: http://www.bytearray.org/?p=1858

MP3 への変換は面倒です。Thibault は ByteArray.org に別の投稿をしています - LAME MP3 を検索してください。

優れた例/リソース: http://www.anttikupila.com/flash/soundfx-out-of-the-box-audio-filters-with-actionscript-3/

Andre Michelle のオープン ソース 'Tonfall' プロジェクトを Google コードで調べてください。

Kevin Goldsmith のブログとラボを参照してください。彼は、Pixel Bender をこの狂気の中で利用する素晴らしい例を持っています。

お役に立てれば!

PS - Andre からヒントを得て、オーディオ バッファの最適な長さは 3072 である必要があります。お使いのマシンで試してみてください。

于 2011-03-29T16:43:29.827 に答える
2

あなたの質問を正しく理解できれば、各サンプルの浮動小数点データを読み取り、それらを合計して、結果の値を新しいオーディオ ストリームに書き込む必要があります。これにより、正確な 50/50 ミックスが得られます。

現在、コンパイラを搭載したマシンにアクセスすることはできませんが、次のようにする必要があります (バイト 1 とバイト 2 が同じ長さの 2 つの ByteArray オブジェクトであると仮定します)。

for (int bcnt = bytes1.size(); bcnt; bcnt--)
    bytes1.setByte(bcnt - 1, bytes2.getByte(bcnt - 1) + bytes1.getByte(bcnt - 1));

もちろん、何らかのオーバーフロー チェックを行いたいと思うかもしれませんが、正しい軌道に乗せるにはそれで十分なはずです。

于 2011-03-28T00:18:19.910 に答える
0

圧縮されていないオーディオがある場合は、の個々の配列要素の値を合計するだけですByteArray。ただし、最大/最小値の上限も処理する必要があります(オーバーフローなし)。MP3をミキシングするのに相当するものはないので、デコード、ミキシング、MP3へのエンコードを再度行う必要があるかもしれません。

于 2011-03-28T00:22:26.357 に答える