2

我目前正在编写一个小游戏,其中涉及正在播放动态创建的音乐,并且在特定的音调上,调用一个函数来更新游戏。

我对动态创建音乐没有任何问题,无论是使用SampleDataEvent.SAMPLE_DATA还是美妙的standingwave2 lib,但我不知道如何将声音与代码同步。

我知道“同步”音符每 X 毫秒播放一次(比如说 500 毫秒),所以我尝试启动一个计时器,它在启动声音后每 500 毫秒滴答一次,但它最终会不同步。我不确定计时器是否不足以跟随路径

我知道有一种方法可以将音乐放在 Adob​​e IDE Frames 上,将声音作为“流”播放,然后在每个帧上放置一些代码,这样我就可以知道它在哪里被调用,但我不能以这种方式动态创建音乐。

那么,有谁知道将我的函数调用与我正在创建的声音同步的方法?

4

4 回答 4

3

我认为这取决于音乐产生的时间和方式。如果您在运行游戏之前生成该音乐,那么当特定音调生成到该音乐中时,您可以在该音乐中产生时间偏移列表,然后您从这些值中创建一个排序数组,然后当音乐被主动启动时,您获取 flash.utils.getTimer() 值并将其存储为您的基本时间。在此之后,每帧检查当前 getTimer() 值是否大于当前数组位置,如果是,则调用所需的函数,并在数组中前进一个位置,为下一次预设发生做好准备您想要的音色。

另一方面,如果您动态生成音乐,每帧长度为几帧,那么您必须在游戏开始和(假设)音乐生成时锁定 getTimer() 值,以便您的每一对值放入 sampleData 正好是播放音乐的 1/44100 秒。然后你计算这些对(当然是在运行中),直到将你想要的音调插入到生成的音乐中,然后你就会从声音开始有一个偏移量。将其转换为毫秒,然后检查每一帧当前的 getTimer() 减去存储的滴答计数是否大于或等于发现的偏移量,如果为真,则调用该函数。

于 2012-10-05T16:26:39.623 回答
2

据我所知,即使您动态添加它们,播放的声音也与帧相关。尝试使用 Event.ENTER_FRAME。如果您知道帧率(默认情况下等于 24 fps)和延迟(X ms;当播放“同步”音符时),那么您可以获得“同步”帧的索引:索引 = fps * 延迟。因为对于声音和帧的同步而言,重要的只有标称 fps,而不是真实的。Event.ENTER_FRAME 处理程序中的帧计数。当您实现“同步”框架时,您可以执行您的代码。

于 2012-10-06T00:46:59.820 回答
1

当你渲染音乐处理 SampleDataEvent.SAMPLE_DATA 时,为什么不直接通知你的机制代码关于音乐会发生什么?它应该非常准确,而且你永远不会不同步超过一个声音块(据我所知,这通常是 2048-4096 浮点对,意味着 2048/44100 - 4096/44100 ~= 1/22 - 1/11 秒)。另外,我没有检查过这个,但我相信,SAMPLE_DATA 在现有声音块开始播放后立即触发,所以你可以在它完成后准备下一个,这意味着,如果你写下声音的时间渲染开始,然后实际声音将在稍后的那个时间播放(如果您的系统没有过载),因此您可以非常精确地计算它,精确到毫秒。

于 2012-10-06T08:17:38.077 回答
1

您需要在 FLV 流中封装 WAV 生成的音乐(仅使用音频标签)。在 FLV 音频标签之间插入 FLV 元数据标签,您将在播放该部分时通过 onMetaData 接收这些标签。由于您正在动态生成音乐,因此您可能想要使用 NetStream.appendBytes() 而不仅仅是将 WAV 文件传递​​给 NetStream。

您需要熟悉 FLV 的工作原理、appendBytes 的工作原理以及如何创建包含 WAV 音频的 FLV(您将其写入 appendBytes(),就像您将其写入文件一样)。

于 2012-10-07T19:49:53.513 回答