梦想成真 XNA (6) - 声音和音效
梦想成真 XNA (6) - 声音和音效
作者:webabcd
介绍
XNA: 声音和音效
- XACT - Cross-platform Audio Creation Tool,跨平台音效制作工具
- SoundEffect - 音效对象
- MediaPlayer - 媒体播放器对象; Song - 音乐对象
示例
1、通过 XACT 处理和播放音效(按键盘 K 键加载此 Demo)
Component/Audio/XACT.cs
/* * XACT(Cross-platform Audio Creation Tool) - 跨平台音效制作工具,用于汇集并编辑音频文件,XNA 则提供了 API 来播放 XACT 项目。Reach 标准不支持 XACT * 1、XACT 只能处理 .wav 格式的音频文件 * 2、Microsoft XNA Game Studio 4.0 -> Tools -> Microsoft Cross-Platform Audio Creation Tool 3 (XACT3) 用于启动 XACT 编辑工具 * 3、XACT 编辑的项目类型为 .xap 格式的文本文件(可以用记事本打开),将 .xap 文件及其引用的 .wav 文件保存到 Content 项目里后,Content Pipeline 会对其进行处理 * 4、新建一个 Wave Banks(波形库),将 .wav 文件添加至此库 * 5、新建一个 Sound Banks(声音库),Sound Banks 分为两个窗口,一个是 Sound Name,一个是 Cue Name * a) 在 Wave Banks 中将某 Item 拖拽到 Cue Name 后,将会在 Sound Name 和 Cue Name 中分别建一个 Item * b) 在 Sound Name 中可以修改声音的重复次数,音量,高低音等 * c) XNA 是通过 Cue 名称来播放音效的,Cue 的一个关键作用是:一个 SoundBank 对象可以同时播放多个 Cue * 6、想在 XACT 编辑器中播放声音的话,需要启动 Microsoft XNA Game Studio 4.0 -> Tools -> XACT Auditioning Utility 控制台 */ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; namespace XNA.Component.Audio { public class XACT : Microsoft.Xna.Framework.DrawableGameComponent { // 声音引擎 AudioEngine _audioEngine; public XACT(Game game) : base(game) { } public override void Initialize() { base.Initialize(); } protected override void LoadContent() { // Wave Banks(波形库)对象 WaveBank waveBank; // Sound Banks(声音库)对象 SoundBank soundBank; /* * 编译后,Content Pipeline 会将 .xap 文件分解为多个文件,分别如下: * 1、每个 .xap 文件会产生一个同名的 .xgs 文件,实例化 AudioEngine 时,需要使用此文件 * 2、.xap 中的每个波形库会产生一个对应的 .xwb 文件,文件名为对应的波形库名称,实例化 WaveBank 时,需要使用此文件 * 3、.xap 中的每个声音库会产生一个对应的 .xsb 文件,文件名为对应的声音库名称,实例化 SoundBank 时,需要使用此文件 */ _audioEngine = new AudioEngine(Game.Content.RootDirectory + "/Audio/XACT.xgs"); waveBank = new WaveBank(_audioEngine, Game.Content.RootDirectory + "/Audio/Wave Bank.xwb"); soundBank = new SoundBank(_audioEngine, Game.Content.RootDirectory + "/Audio/Sound Bank.xsb"); /* * SoundBank.PlayCue(string cueName) - 播放指定的 cue,支持一个 SoundBank 对象同时播放多个 cue * SoundBank.GetCue(string cueName) - 获取指定的 cue 信息,返回 Microsoft.Xna.Framework.Audio.Cue 对象 */ soundBank.PlayCue("Thunder"); soundBank.PlayCue("Rain"); /* * Cue - cue 信息 * Cue.Play() - 播放 * Cue.Pause() - 暂停 * Cue.Resume() - 继续 * Cue.Stop(AudioStopOptions options) - 停止,重新播放的话需要重新实例化 Cue 对象 * AudioStopOptions.AsAuthored - 完成 XACT 指定的效果后停止(比如本例中 Rain 被标记为 Infinite 和 Play Release,前者表示 Rain 会循环播放,后者表示在调用 Stop(AudioStopOptions.AsAuthored) 后,等待 Rain 音频播放完后停止) * AudioStopOptions.Immediate - 立即停止 */ Cue cueThunder = soundBank.GetCue("Thunder"); System.Diagnostics.Debug.Write(cueThunder.Name); } public override void Update(GameTime gameTime) { // AudioEngine.Update() - 就当做每帧时 AudioEngine 都要为自己管辖的声音做一些调整吧,为了使声音在任何时候都播放正常,必须每帧调用此方法 _audioEngine.Update(); base.Update(gameTime); } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.CornflowerBlue); base.Update(gameTime); } } }
2、通过 SoundEffect 播放音效(按键盘 L 键加载此 Demo)
Component/Audio/SoundEffectDemo.cs
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using System.Diagnostics; namespace XNA.Component.Audio { public class SoundEffectDemo : Microsoft.Xna.Framework.DrawableGameComponent { public SoundEffectDemo(Game game) : base(game) { } public override void Initialize() { base.Initialize(); } protected override void LoadContent() { /* * SoundEffect - 音效对象 * SoundEffect.Play(float volume, float pitch, float pan) - 播放音效 * volume - 音量值,0 到 1 之间 * pitch - 高音值, -1 到 1 之间,-1 是纯低音,1 是纯高音 * pan - 左右声道平衡值,-1 到 1 之间,-1 是仅左声道有声,1 是仅右声道有声 * SoundEffect.Duration - 音效的时长 * SoundEffect.Name - 音效对象的名称 */ SoundEffect soundEffect; soundEffect = Game.Content.Load<SoundEffect>("Audio/Thunder"); soundEffect.Play(0.5f, -1f, 0f); Debug.WriteLine(soundEffect.Duration.TotalSeconds.ToString(), "Duration"); /* * SoundEffectInstance - SoundEffect 的对象实例 * SoundEffect.CreateInstance() - 返回 SoundEffect 对象 * SoundEffectInstance.Volume - 音量值,0 到 1 之间 * SoundEffectInstance.Pitch - 高音值, -1 到 1 之间,-1 是纯低音,1 是纯高音 * SoundEffectInstance.Pan - 左右声道平衡值,-1 到 1 之间,-1 是仅左声道有声,1 是仅右声道有声 * SoundEffectInstance.IsLooped - 是否循环播放 * SoundEffectInstance.Play() - 播放 * SoundEffectInstance.Pause() - 暂停 * SoundEffectInstance.Resume() - 继续播放 * SoundEffectInstance.Stop() - 停止 * SoundEffectInstance.State - 返回音效对象的当前状态 [Microsoft.Xna.Framework.Audio.SoundState 枚举] * SoundState.Playing - 正在播放状态 * SoundState.Paused - 暂停状态 * SoundState.Stopped - 停止状态 */ /* SoundEffectInstance soundEffectInstance = soundEffect.CreateInstance(); soundEffectInstance.Volume = 0.5f; soundEffectInstance.Pitch = -1f; soundEffectInstance.Pan = 0f; soundEffectInstance.IsLooped = true; soundEffectInstance.Play(); soundEffectInstance.Pause(); soundEffectInstance.Resume(); soundEffectInstance.Stop(); SoundState soundState = soundEffectInstance.State; */ } public override void Update(GameTime gameTime) { base.Update(gameTime); } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.CornflowerBlue); base.Update(gameTime); } } }
3、通过 MediaPlayer 和 Song 播放音乐(按键盘 M 键加载此 Demo)
Component/Audio/MediaPlayerDemo.cs
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using System.Diagnostics; namespace XNA.Component.Audio { public class MediaPlayerDemo : Microsoft.Xna.Framework.DrawableGameComponent { public MediaPlayerDemo(Game game) : base(game) { } public override void Initialize() { base.Initialize(); } protected override void LoadContent() { /* * Song - 音乐对象 * Song.FromUri() - 从指定的网络地址加载音乐文件 */ /* * MediaPlayer - 媒体播放器对象 * MediaPlayer.IsRepeating - 是否重复播放 * MediaPlayer.IsMuted - 是否静音 * MediaPlayer.PlayPosition - 当前的播放位置 * MediaPlayer.Volume - 音量 * MediaPlayer.State - 播放状态,返回 Microsoft.Xna.Framework.Media.MediaState 枚举 * MediaState.Playing - 播放中 * MediaState.Paused - 暂停状态 * MediaState.Stopped - 停止状态 * MediaPlayer.MediaStateChanged- 播放状态改变后所触发的事件 * MediaPlayer.Queue - 获取播放列表对象,类型 Microsoft.Xna.Framework.Media.MediaQueue * MediaQueue.ActiveSong - 当前正在播放的 Song 对象 * MediaQueue.ActiveSongIndex - 当前正在播放的 Song 对象在播放列表中的索引 * MediaQueue.Count - 播放列表中 Song 对象的总数 * MediaPlayer.Play() - 播放指定的 Song 对象;或播放指定的 Song 对象集合(即播放列表),且可指定从播放列表中的第几首音乐开始播 * MediaPlayer.Pause() - 暂停 * MediaPlayer.Resume() - 继续播放 * MediaPlayer.Stop() - 停止 */ // Song song = Song.FromUri("Demo", new Uri("http://www.abc.com/demo.mp3")); Song song = Game.Content.Load<Song>("Audio/Demo"); MediaPlayer.IsRepeating = true; MediaPlayer.IsMuted = false; MediaPlayer.Volume = 0.5f; MediaPlayer.Play(song); } public override void Update(GameTime gameTime) { base.Update(gameTime); } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.CornflowerBlue); base.Update(gameTime); } } }
OK
[源码下载]