游戏会话声音播放/录音
Posted
技术标签:
【中文标题】游戏会话声音播放/录音【英文标题】:Game session Sound Playback / Recording 【发布时间】:2012-05-04 21:16:18 【问题描述】:所以我正在制作一个简单的 Flash 游戏。基本上,我有一个转盘,可以播放 30 秒,其中包含几首样本音乐,这些样本音乐在多层声音中叠加在一起,形成一首最终歌曲。
现在我希望能够在游戏结束时录制和播放声音。
我创建了一个 SoundFx 类,它接收 mp3 音频并将其转换为 byteArrays,希望将音频混合到同一个声道中。
现在我已经达到了一定的僵局,因为我无法正确混合字节数组。我开始认为在将通道添加到混合中时不可能对字节数组进行编码。
我很想被引导到正确的方向。我不确定从这里开始是否是最好的方法,即使只是播放也会很好。创建按钮日志可能会修复播放并在第二次运行中混合音频以直接进入文件。但要实现这一目标似乎还有很长的路要走。
提前对我蹩脚的英语表示感谢和道歉
大卫·R.
关于此事的一些代码:
private var srcSound:Sound;
private var sound1:Sound;
private var sound2:Sound;
private var soundChannel:SoundChannel;
private var bytes:ByteArray;
private var incbytes:ByteArray;
private var mixedBytes:ByteArray;
public var pitchShiftFactor:Number;
public var position:Number;
public var AddSound:Boolean = false;
public var incremental:Number;
public var left1:Number;
public var left2:Number;
public var right1:Number;
public var right2:Number;
public var mixedBytes1:Number;
public var mixedBytes2:Number;
public function SoundFx()
public function playFx(srcSound:Sound):void
this.srcSound = srcSound;
position = 0;
var morphedSound:Sound = new Sound();
morphedSound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler);
soundChannel = morphedSound.play();
public function addSound(sound1:Sound , sound2:Sound):void
this.sound1 = sound1;
this.sound2 = sound2;
sound1.addEventListener(SampleDataEvent.SAMPLE_DATA, addSampleData);
position = 0;
soundChannel = sound1.play();
soundChannel = sound2.play();
AddSound = true;
private function addSampleData(event:SampleDataEvent):void
position = 0;
var incbytes:ByteArray = new ByteArray();
position += sound1.extract(incbytes, 4096, position);
var bytes:ByteArray = new ByteArray();
position += sound2.extract(bytes, 4096, position);
event.data.writeBytes(mixBytes(bytes, incbytes));
private function sampleDataHandler(event:SampleDataEvent):void
var bytes:ByteArray = new ByteArray();
position += srcSound.extract(bytes, 4096, position);
event.data.writeBytes(editBytes(bytes));
private function mixBytes(bytes1:ByteArray , bytes2:ByteArray ):ByteArray
bytes.position = 0;
incbytes.position = 0;
var returnBytes:ByteArray = new ByteArray();
while(bytes1.bytesAvailable > 0)
left1 = bytes1.readFloat();
left2 = bytes2.readFloat();
right1 = bytes1.readFloat();
right2 = bytes2.readFloat();
mixedBytes1 = left1 + left2;
mixedBytes2 = right1 + right1;
mixedBytes.writeFloat(mixedBytes1);
mixedBytes.writeFloat(mixedBytes2);
return mixedBytes;
private function editBytes(bytes:ByteArray):ByteArray
//var skipCount:Number = 0;
var returnBytes:ByteArray = new ByteArray();
bytes.position = 0;
while(bytes.bytesAvailable > 0)
//skipCount++;
returnBytes.writeFloat(bytes.readFloat());
returnBytes.writeFloat(bytes.readFloat());
return returnBytes;
【问题讨论】:
【参考方案1】:我想我明白你的想法,希望我明白了。
您应该尝试将所有 SoundChannel 类(正在添加的声音层)传递给 SoundMixer 类(在 adobe 站点中有大量关于此的信息),例如漏斗,然后将 SAMPLEDATA 事件侦听器添加到该混音器,并捕获该混音器的字节数组,就像获取最终混音的字节数组......然后将这些字节编码为wav or mp3
。
对不起,我不能为你写下那个代码,我对代码还不是很好,但我很擅长混合声音。
这是一个示例表单 adobe 网站本身:
function loaded(event:Event):void
outputSnd.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound);
outputSnd.play();
有用的链接: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html
混音器类链接: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundMixer.html
【讨论】:
【参考方案2】:我在服务器端使用了SoundMixer.computeSpectrum()
使用 Stratus (cirrus) 网络收音机进行实验,并使用 NetStream.send()
将该数据传递到客户端进行绘图和播放。
它可以工作,但是在一台计算机上的客户端和服务器非常需要内存(并且加载了几首歌曲并转换为原始音频数据:)
所以,试试computeSpectrum()
,它似乎非常适合创建“音频日志”
【讨论】:
谢谢!完成后我会检查并发布结果:)以上是关于游戏会话声音播放/录音的主要内容,如果未能解决你的问题,请参考以下文章