AS3 microphone recording/saving works, in-flash PC

2020-07-17 06:42发布

问题:

I have a working mic recording script in AS3 which I have been able to successfully use to save .wav files to a server through AMF. These files playback fine in any audio player with no weird effects.

For reference, here is what I am doing to capture the mic's ByteArray: (within a class called AudioRecorder)

public function startRecording():void {
_rawData = new ByteArray();
_microphone
 .addEventListener(SampleDataEvent.SAMPLE_DATA,_samplesCaptured, false, 0, true);
}

private function _samplesCaptured(e:SampleDataEvent):void {
  _rawData.writeBytes(e.data);
}

This works with no problems. After the recording is complete I can take the _rawData variable and run it through a WavWriter class, etc.

However, if I run this same ByteArray as a sound using the following code which I adapted from the adobe cookbook: (within a class called WavPlayer)

public function playSound(data:ByteArray):void {
  _wavData = data;
  _wavData.position = 0;
  _sound.addEventListener(SampleDataEvent.SAMPLE_DATA, _playSoundHandler);
  _channel = _sound.play();
  _channel
    .addEventListener(Event.SOUND_COMPLETE, _onPlaybackComplete, false, 0, true);
}

private function _playSoundHandler(e:SampleDataEvent):void {
  if(_wavData.bytesAvailable <= 0) return;
  for(var i:int = 0; i < 8192; i++) {
    var sample:Number = 0;
    if(_wavData.bytesAvailable > 0) sample = _wavData.readFloat();
    e.data.writeFloat(sample);
  }
}

The audio file plays at double speed! I checked recording bitrates and such and am pretty sure those are all correct, and I tried changing the buffer size and whatever other numbers I could think of. Could it be a mono vs stereo thing?

Hope I was clear enough here, thanks!

回答1:

The problem is that the ByteArray has to contain data for both channels (left and right), one value immediately after the other. Thus, if your recording is mono, your code should be this:

for(var i:int = 0; i < 8192; i++) {
    var sample:Number = 0;
    if(_wavData.bytesAvailable > 0) sample = _wavData.readFloat();
        e.data.writeFloat(sample);
        e.data.writeFloat(sample);
}

If it is stereo, you will need to adjust accordingly.



回答2:

I've tested it.
You need to make sure the Microphone's rate is at 44kHz:
_microphone.rate = 44;
This should sound right.

I used:

    private function playSound(data:ByteArray):void
    {
        rawData = data;
        rawData.position = 0;
        var sound:Sound = new Sound();
        sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playSoundHandler);
        var channel:SoundChannel = sound.play();
        channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete, false, 0, true);
    }

    private function playSoundHandler(e:SampleDataEvent):void
    {
        if(rawData.bytesAvailable <= 0)
        {
            return;
        }
        for(var i:int = 0; i < 8192; i++)
        {
            var sample:Number = 0;
            if(rawData.bytesAvailable > 0)
            {
                sample = rawData.readFloat();
            }
            e.data.writeFloat(sample);
            e.data.writeFloat(sample);
        }
    }