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);
        }

 

arrow
arrow
    全站熱搜

    teexit1224 發表在 痞客邦 留言(0) 人氣()