梦想成真 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
[源码下载]