Flash 10.1 AS3 - применение эффектов в реальном времени к микрофону - проблемы с заиканием - PullRequest
3 голосов
/ 09 февраля 2011

Я пытаюсь написать флэш-приложение, которое принимает поток микрофона и применяет эффекты в реальном времени и выводит их обратно на динамики.

Я обнаружил, что у меня проблемы с заиканием, когда я беру выходной сигнал с микрофона, копирую его в ByteArray и затем использую отдельный

sound = new Sound ();

sound.addEventListener (SampleDataEvent.SAMPLE_DATA, processSound);

sound.play ();

для чтения из этого ByteArray и воспроизведения звука.

Я заметил, что входные данные из байтов микрофона доступны,а также то, что два события (SAMPLE_DATA микрофона и SAMPLE_DATA звука) не запускают ABABABAB, как было бы необходимо, но является более случайным.

Прав ли я, полагая, что событие mic.SAMPLE_DATA запускается с разными интервалами с разными объемами данных, и рабочая реализация должна будет считывать доступные данные и буферизовать ввод, чтобы Sound SampleDataEvent всегдачто-нибудь, что можно воспроизвести, чтобы избежать набивки?

1 Ответ

4 голосов
/ 10 февраля 2011

Я нашел решение, поэтому подумал, что я опубликую его здесь, если у кого-то еще были подобные проблемы (многие поиски в Google ничего не нашли для меня).

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

private var mic:Microphone;
private var micBuffer:Array;
private var playBackSound:Sound;
//the effect I was applying needed to be applied to 
private var _leftChannel:Vector.<Number> = new Vector.<Number>(8192/2);

private function init() {
    micBuffer = new Array();
    mic = Microphone.getMicrophone();
    mic.rate = 22; 
    mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleData);
}

private function micSampleData(e:SampleDataEvent) {

    //store everything sent from the microphone into the array - this will vary in length
    while  (e.data.bytesAvailable > 0) micBuffer.push(e.data.readFloat());

    //can wait here for the array to reach a certain size if needed
    if (!playBackSound) {
        playBackSound = new Sound();
        playBackSound.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound);
        playBackSound.play();
    }
}

private function playBackSoundSampleData(e:SampleDataEvent) {

    //this number will change depending on the sample rate of microphone
    var numberOfFloats = 8192/8;
    for (var i = 0; i<numberOfFloats && micBuffer.length > 0; i++) 
    {
        _leftChannel[i] = micBuffer.shift();
        count++;
    }

    //apply effect

    //sample rate here is half of 44 so write twice + twice again to make stereo
    for(var i = 0 ; i < count ; ++i )
    {
        e.data.writeFloat( _leftChannel[i] );
        e.data.writeFloat( _leftChannel[i] );
        e.data.writeFloat( _leftChannel[i] );
        e.data.writeFloat( _leftChannel[i] );
    }
}
...