XNA 4.0在聲音的部分新增加了麥克風的功能,現在可以使用麥克風來錄製聲音。
這個功能支援WP7、Xbox 360和PC等具有麥克風的產品。
我們可以藉由這項功能,來豐富話我們的遊戲。
這邊就提供簡單的範例程式。用麥克風這項功能主要是會用到Microphone這個物件。
如果在標頭的地方沒有using Microsoft.Xna.Framework.Audio請手動加入。
然後我們還需要一個DynamicSoundEffectInstance用來播放我們所錄製的聲音。
然後在Initialize的函數中,我們需要取得實體麥克風的介面,經由Microphone.Default這個方式取得。
如果回傳數值為null則代表沒有辦法找到麥克風的裝置。
if (Microphone.Default == null)
{
throw new Exception("Can't found MicroPhone.");
}
else
{
microPhone = Microphone.Default;
}
取得到裝置的介面以後,還需要準備一個緩衝器(buffer)用來儲存錄製的音效。
buffer = new byte[microPhone.GetSampleSizeInBytes(TimeSpan.FromSeconds(5.0f))];
GetSampleSizeInBytes這個方法是將內部所指定的TimeSpan的時間轉換成Btyes的數值,以上述來說會轉換五秒時間的btye會使用的buffer大小。
經過上述那行程式碼以後,現在我們擁有麥克風的介面和緩衝器的儲存空間。
接下來我們需要在Update的函數中,設定一些操作,讓使用者可以按下鍵盤來錄製聲音。
keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.R))
{
microPhone.Start();
microPhone.GetData(buffer);
}
if (keyboard.IsKeyDown(Keys.S))
{
microPhone.Stop();
}
當按下R以後會開始錄製聲音。
Start開始接收麥克風所接收到的聲音,然後在用GetData的函數將這些資訊儲存在buffer當中。
如果你想要結束錄製則按下S就會停止錄製。
錄製完畢以後,可能會想要播放聲音。
這時我們就會需要DynamicSoundEffectInstance的物件來幫我們做這個事情。
在initialize的函數中,我們需要配置一塊記憶體給它
soundEffect = new DynamicSoundEffectInstance(microPhone.SampleRate, AudioChannels.Mono);
第一個參數是說現在麥克風的取樣速率(使用者可以調整,不過記得麥克風的部分也需要調整)
第二個參數是指輸出的聲道(這邊提供單聲道和立體音)
完成操作以後,還需要指定現在要播放的buffer是哪一個,我們需要使用SubmitBuffer函數來設定buffer。
soundEffect.SubmitBuffer(buffer);
設定完成以後在呼叫play()來播放音效
相關程式碼:
Microphone microPhone;
byte[] buffer;
DynamicSoundEffectInstance soundEffect;
KeyboardState keyboard;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
if (Microphone.Default == null)
{
throw new Exception("Can't found MicroPhone.");
}
else
{
microPhone = Microphone.Default;
}
buffer = new byte[microPhone.GetSampleSizeInBytes(TimeSpan.FromSeconds(5.0f))];
soundEffect = new DynamicSoundEffectInstance(microPhone.SampleRate, AudioChannels.Mono);
keyboard = Keyboard.GetState();
base.Initialize();
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || keyboard.IsKeyDown(Keys.Escape))
this.Exit();
// TODO: Add your update logic here
keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.R))
{
microPhone.Start();
microPhone.GetData(buffer);
}
if (keyboard.IsKeyDown(Keys.S))
{
microPhone.Stop();
}
if (keyboard.IsKeyDown(Keys.P))
{
soundEffect.SubmitBuffer(buffer);
soundEffect.Play();
}
base.Update(gameTime);
}