Flash 10.1 AS3 - 将实时效果应用于麦克风 - 口吃问题

时间:2011-02-09 11:40:01

标签: flash actionscript-3 microphone

我正在尝试编写一个Flash应用程序,该应用程序接收麦克风流并应用实时效果并将其输出回扬声器。

我发现从麦克风输出时出现口吃问题,将其复制到ByteArray amd然后使用单独的

  

sound = new Sound();

     

sound.addEventListener(SampleDataEvent.SAMPLE_DATA,processSound);

     

sound.play();

从此ByteArray中读取并播放声音。

我注意到来自mic的bytesAvailable的输入发生了变化,并且两个事件(mic的SAMPLE_DATA和声音的SAMPLE_DATA)没有发射A B A B A B A B就像是需要但是更随机。

我是否正确地认为mic.SAMPLE_DATA事件以不同的间隔以不同的数据量触发,并且工作实现需要读取可用数据并缓冲输入,以便Sound SampleDataEvent始终可以播放回来避免填充?

1 个答案:

答案 0 :(得分:4)

我找到了一个解决方案,所以我认为我会把它发布在这里,因为其他人都有类似的问题(许多谷歌搜索对我来说没有任何意义)。

似乎来自麦克风的输入通过不一致的方式馈送,并且需要通过所有发送的字节来正确处理声音。让它工作的关键是使用数组来缓冲输入。

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