我正在尝试编写一个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始终可以播放回来避免填充?
答案 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] );
}
}