我在AS3中有一个工作的麦克风录音脚本,我已经成功地通过AMF将.wav文件保存到服务器。这些文件在任何音频播放器中都能正常播放,没有任何奇怪的效果。
作为参考,我正在做的是捕捉麦克风的ByteArray :(在名为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);
}
这没有问题。录制完成后,我可以使用_rawData变量并通过WavWriter类等运行它。
但是,如果我使用以下代码运行同样的ByteArray作为声音,我从adobe cookbook改编:(在一个名为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);
}
}
音频文件以双倍速度播放!我检查了记录比特率等等,我很确定这些都是正确的,我尝试改变缓冲区大小和我能想到的任何其他数字。它可能是单声道与立体声的东西吗?
希望我在这里很清楚,谢谢!
答案 0 :(得分:8)
问题是ByteArray必须包含两个通道(左和右)的数据,一个值紧接着另一个。因此,如果您的录音是单声道,您的代码应为:
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);
}
如果是立体声,则需要相应调整。
答案 1 :(得分:3)
我已经测试过了。
您需要确保麦克风的速率为44kHz:
_microphone.rate = 44;
这听起来应该是正确的
我用过:
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);
}
}