микширование 2 звуков от ByteArray - PullRequest
6 голосов
/ 28 марта 2011

Я собрал микшер и сохранил всю последовательность в массиве, а затем воспроизвел ее снова, теперь я хочу сохранить микс в формате MP3, я искал любой способ сохранить микс, и ответ заключается в том, чтобы загрузитьЗвучит как byteArrays (sound.extract) У меня есть подтверждение, но я не знаю, как сохранить все звуки только в одном ByteArray, чтобы сохранить его как MP3, я получил этот код, например, загружая 2 аудио файла исохраняйте их в отдельных байтовых массивах и воспроизводите каждый звук, знает ли кто-нибудь из них, как хранить 2 байтовых массива в одном?

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); 
} 

Ответы [ 3 ]

7 голосов
/ 29 марта 2011

некоторое время работал над подобной системой, я сделаю все возможное, чтобы дать вам какое-то указание:

Ваш пример кода на самом деле не смешивает MP3 - он создает еще 2 звука для воспроизведения загруженных MP3 через SampleDataEvent. Что вам нужно сделать, это создать только один «выходной» звуковой файл, который будет удерживать / воспроизводить полученный смешанный звук. Вы можете легко сохранить эти данные, как это происходит, и впоследствии сохранить этот файл как новый WAV / MP3 / что-у-вас.

реальный / псевдо-код (читай: ленивый):

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-файлов, либо запустите enter-frame, чтобы определить, когда оба звука больше не буферизуются (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. Аудио существует во Flash как PCM / несжатые данные, MP3, очевидно, является сжатым форматом. Этот «ответ» уже слишком длинный, и всю эту информацию я почерпнул у нескольких очень умных людей.

Вы можете легко адаптировать 'MicRecorder' к обычному устройству записи звука: http://www.bytearray.org/?p=1858

конвертация в MP3 будет непростой задачей: у Тибо есть еще один пост на ByteArray.org - поиск LAME MP3.

Отличный пример / ресурс: http://www.anttikupila.com/flash/soundfx-out-of-the-box-audio-filters-with-actionscript-3/

Найдите в Google код открытого проекта Андре Мишель "Tonfall".

Посмотрите блог и лаборатории Кевина Голдсмита - у него есть отличный пример использования Pixel Bender со всем этим безумием.

надеюсь, это поможет!

PS. Опираясь на реплику Андре, оптимальная длина аудиобуфера должна быть 3072. Попробуйте на своем компьютере!

2 голосов
/ 28 марта 2011

Если я правильно понимаю ваш вопрос, вам нужно прочитать данные с плавающей запятой для каждого семпла, суммировать их и записать полученное значение в ваш новый аудиопоток. Это дало бы правильное сочетание 50/50.

У меня сейчас нет доступа к машине с компилятором, но должно быть что-то вроде этого (предполагается, что bytes1 и bytes2 - два объекта ByteArray одинаковой длины):

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

Конечно, вы, вероятно, захотите выполнить какую-то проверку переполнения, но этого должно быть достаточно, чтобы вы встали на правильный путь.

0 голосов
/ 28 марта 2011

если у вас несжатый звук, вы можете просто сложить значения отдельных элементов массива в ваших ByteArray. Но вы также должны обрабатывать ограничение для максимальных / минимальных значений (без переполнения). Уверен, что нет ничего равносильного микшированию MP3 - так что вам, возможно, придется декодировать, микшировать и кодировать в MP3 снова.

...