使用 SoundEffect 在 XNA 中循环播放带有前奏的音乐

Posted

技术标签:

【中文标题】使用 SoundEffect 在 XNA 中循环播放带有前奏的音乐【英文标题】:Looping music with intro in XNA using SoundEffect 【发布时间】:2010-05-11 16:17:34 【问题描述】:

我有两个声音文件:

声音 A 是一个 18 秒的前奏,旨在播放一次 B 音是 1 分钟的循环曲目

我想播放声音 A 一次,然后一旦声音 A 播放完毕,立即播放声音 B 并继续循环声音 B,直到我告诉它停止。这应该是在 RPG 中循环播放城镇音乐。

我尝试在代码中仅使用 SoundEffect 执行此操作,但声音 A 的结尾和声音 B 的开头之间存在微小但明显的差距。即使我在更新中放置监视代码来观察声音 A 的 SoundEffectInstance.State () 函数,当声音 A 完成时,我无法准确地启动声音 B,因此它是无缝的。

我更喜欢使用 SoundEffect,因为我可以加载 WMA 文件,而不是在 XACT 中被 WAV 卡住。

【问题讨论】:

【参考方案1】:

可能的第二种选择。我想你听到的差距可能是因为第二个声音需要加载到内存中,或者初始化,或者打开流(不确定内部实现)。但如果是这样的话,我想知道你是否可以这样做:

    加载两个音效(a 和 b) 开始播放音效A 立即开始播放音效B 一帧后暂停音效 B 音效A结束后,重新启动音效A

我的假设是,由于音效 B 已经初始化,它可能会更快启动,从而减少感知差距。很想知道你是否有机会尝试这个,以及它是否有效:-)

【讨论】:

试过了,但无济于事。听起来完全一样。作为记录,我在 LoadContent() 中同时加载和创建两个 SoundEffectInstance。不要认为问题与资源加载有关。一开始我确实收到了额外的爆裂声,但我可以通过在我点击 Play() 之前将 SoundEffectInstance 的音量设置为 0 来阻止它。另外,事实证明我的 WMA 正在被 XNA 的 SoundEffect 内容导入器转换为 WAV。啊。我不知道如何解决这个问题。我正在尝试构建一个 RPG,但我无法拥有 1GB 的音乐,因为它都是 WAV 格式的。 哦,那个特殊的问题实际上完全没有问题 :-) 请参阅“Xact 中的音频压缩”blogs.msdn.com/mitchw/archive/2007/04/27/… 我能找到的最佳解决方案:创建一个声音库。将两个 WAV 从 Wave Bank 拖到一个 Sound Bank 中。每一个都应该是一个单独的轨道。循环曲目应该是 Track 2。在 Play Wave 级别选择它,检查 Infinite looping,并(至关重要)将其时间戳设置为前奏部分的确切长度。您可以指定小数点后 3 位。我使用了一个名为 Audacity 的程序来获取介绍歌曲的确切长度。哦,然后按照 Joel 的压缩链接。它会将您的 WAV 文件大小减少 3/4。【参考方案2】:

不幸的是,SoundEffect API 的简单性是以降低灵活性为代价的。这种类型的音频编程是 XACT 擅长的……如果您需要复杂的作曲,那么您可能想要研究转向 XACT。

【讨论】:

我考虑过把这个问题做成一个多部分的问题,但这可能会给我带来麻烦。具体来说:这将如何在 XACT 中工作?该程序使用起来绝对是一场噩梦。我真的很喜欢关于如何在 XACT 中进行这种循环音频的精确的、单击这个然后这个说明,因为我无法仅从推理中弄清楚。 嘿,一个足够公平的声明 :-) 我个人没有这样做,但我想它可以通过过渡功能完成:msdn.microsoft.com/en-us/library/ee415994%28v=VS.85%29.aspx 以前没看过那个文件。看起来很有希望。谢谢,乔尔。

以上是关于使用 SoundEffect 在 XNA 中循环播放带有前奏的音乐的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 Microsoft.Xna.Framework 将 wma 文件加载为 SoundEffect 时发生 InvalidOperationException

XNA“游戏循环”的实际代码在哪里?

在 Windows Phone 8 中播放声音片段

将频率转换为 -1..1 浮点数

停止播放通过 SoundEffect.FromStream 调用的声音

当另一个声音使用 XNA/XACT 结束时,如何立即播放一个声音?