我正在编写一个小游戏,其中涉及正在播放动态创建的音乐,并且在特定音调上,会调用一个函数来更新游戏。
使用SampleDataEvent.SAMPLE_DATA
或精彩的 standingwave2 lib动态创建音乐没问题,但我无法找到如何将声音与代码同步。
我知道“同步”音符每隔X毫秒播放一次(假设为500),所以我试图在启动声音后立即启动一个每500毫秒滴答一次的计时器,但它最终会失去同步。我不确定计时器是否不足以遵循路径
我知道有一种方法可以将音乐放在Adobe IDE Frames上,播放声音为“stream”,然后在每个帧上放置一些代码,这样我就可以知道它的调用位置,但是我无法以这种方式动态创建音乐。 / p>
那么,有没有人知道一种方法来将我的函数调用与我正在创建的声音同步?
答案 0 :(得分:3)
我认为这取决于音乐生成的时间和方式。如果您在运行游戏之前生成该音乐,那么当特定音调生成到该音乐中时,您可以在该音乐中生成时间偏移列表,然后您可以从这些值中创建排序数组,然后在音乐主动启动时,您获取flash.utils.getTimer()值并将其存储为基准时间。在此之后,检查每个帧是否当前getTimer()值大于当前数组位置,如果是,则调用所需的函数,并在数组中前进一个位置,为下一个预设事件做好准备你想要的语气。
另一方面,如果你动态生成音乐,每个帧长度为几帧,那么你必须在游戏开始和(据说)音乐生成时锁定getTimer()值,以便每对您放入sampleData的值恰好是播放音乐的1/44100秒。然后你计算这些对(当然是动态),直到它有时间将你想要的音调插入到生成的音乐中,然后你就会从声音开始偏移。将其转换为毫秒,然后检查每个帧,如果当前getTimer()减去存储的滴答计数大于或等于已发现的偏移量,如果为true,则调用该函数。
答案 1 :(得分:2)
据我所知,即使您动态添加它们,声音也会与帧相关联。尝试使用Event.ENTER_FRAME。如果您知道帧速率(默认情况下等于24 fps)和延迟(X ms;播放“同步”音符时),则可以获得“同步”帧的索引:index = fps * delay。因为同步声音和帧只重要的是标称fps,而不是真实的。计算Event.ENTER_FRAME处理程序中的帧。当您实现“同步”框架时,您可以执行代码。
答案 2 :(得分:1)
为什么不在渲染音乐处理SampleDataEvent.SAMPLE_DATA时告知您的机械代码有关音乐会发生什么的信息?它应该是非常准确的,并且你永远不会因为多个声音块而失去同步(据我记得,这通常是2048-4096个浮动对,意味着2048/44100 - 4096/44100~ = 1/22 - 1/11秒)。另外,我没有检查过这个,但是我相信,SAMPLE_DATA在现有的声音块开始播放后立即被触发,所以你可以在它完成就绪之后使用下一个,这意味着,如果你记下声音的时间渲染开始,然后实际的声音将在稍后的时间播放(如果你的系统没有超载),所以你可以非常精确地计算它,直到几毫秒。
答案 3 :(得分:1)
您需要在FLV流中封装WAV生成的音乐(仅使用音频标签)。在FLV音频标签之间插入FLV元数据标签,您将receive through onMetaData正在播放该部分。由于您正在动态生成音乐,您可能希望使用NetStream.appendBytes()而不是仅仅将WAV文件传递给NetStream。
您需要熟悉FLV的工作原理,appendBytes的工作原理以及如何创建FLV(您将其写入appendBytes(),就像将其写入文件一样),其中包含WAV音频。