Click here to Skip to main content
Click here to Skip to main content

How to record sound using XNA

By , 2 Feb 2013
Rate this:
Please Sign up or sign in to vote.

Introduction 

Hello friends, I know that all of you are very fond of recording. recording is usual in speech recognition applications, language learning applications and so many other applications. But there is not a clear source code to record sound for windows. All of them are somehow not complete, Winmm.dll has its bugs, direct sound is not supported in .net 4, I mean we are programming we are not waiting for Microsoft to someday get to this point that c# is better than c++ and change the trend of depriving c# coders from having a stable API which can record sound like Direct Sound.

So here i put a simple code that many coders will understand. here i used 3 buttons of mouse for doing our job:

Mouse Left Button: Start recording 

Mouse Right Button: Stop recording 

Mouse Middle Button: Play what is recorded.

Using the code

So pals get started and in the solution Explorer right click on the content, we want to add our font.

Click on Add=> New item

so select select  Spirite Font and add it.

Now let's go coding: 

We should use these refrences:

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.IO;

Add these in the first lines of constructor.

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//
Microphone microphone = Microphone.Default;
byte[] buffer;
MemoryStream stream = new MemoryStream();
SoundEffect sound;
SoundEffectInstance isound;
SpriteFont myfont;
MouseState mystate;
//
string programstate = "none";
string strleftbutton = "none";
string strRightButton = "none";
string strMiddlebutton = "none";

microphone is the device we want to capture sound with, we use the Windows default microphone here. buffer is a container for our current data captured by microphone. stream is something you can save it on the hard disk if you want. Sprite Font provides us a font after initialization. We need mouse state to know which button of mouse is pressed. ProgramState is the state of our program. We provide the information of pressing and releasing the mouse buttons in:

string strleftbutton = "none";
string strRightButton = "none";
string strMiddlebutton = "none";

Below is our Game1 method: 

whenever buffer is full the function microphone_BufferReady will be called.

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
 
    microphone.BufferReady += new EventHandler<EventArgs>(microphone_BufferReady);
}

This is our initialization:

protected override void Initialize()
{
    // TODO: Add your initialization logic here
    IsMouseVisible = true;
    base.Initialize();
}

Well above we made our mouse visible.

This is our  load content, we initialize our font here.

protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);
    myfont = Content.Load<SpriteFont>("SpriteFont1");
    // TODO: use this.Content to load your game content here
}

This is our update :

here we get the mouse state and we call mouseget function that would set our mouse parameters.

If sound is not (null) (recorded before) and the sound is stopped we will set it null and we initialize our state of program.

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();
    mystate = Mouse.GetState();
    mouseGet();
    if (isound != null)
    {
        if (isound.State == SoundState.Stopped)
        {
            isound = null;
            programstate = "none";
        }
    }
    // TODO: Add your update logic here

    base.Update(gameTime);
}

Now let's go for our mouseget function. We here decide on playing, stopping, and recording sound by our mouse buttons clicks.

public void mouseGet()
{
    if (programstate == "none")
    {
        if (mystate.LeftButton == ButtonState.Pressed)
        {
            strleftbutton = "pressed";
        }
        if (mystate.LeftButton == ButtonState.Released)
        {
            if (strleftbutton == "pressed")
            {
           
                    start();
                    strleftbutton = "none";
                    programstate = "started";
            }
       }
   }
    //
    if (programstate == "started")
    {
        if (mystate.RightButton == ButtonState.Pressed)
        {
            strRightButton = "pressed";
        }
        if (mystate.RightButton == ButtonState.Released)
        {
            if (strRightButton == "pressed")
            {

                stop();
                strRightButton = "none";
                programstate = "stoped";

            }
        }
    }
    //
    if (programstate == "stoped")
    {
        if (mystate.MiddleButton == ButtonState.Pressed)
        {
            strMiddlebutton = "pressed";
        }
        if (mystate.MiddleButton == ButtonState.Released)
        {
            if (strMiddlebutton == "pressed")
            {

                play();
                strMiddlebutton = "none";
                programstate = "playing";

            }
        }
    }
}

This is when our buffer is full and ready to give the stream its data. 

void microphone_BufferReady(object sender, EventArgs e)
{
    microphone.GetData(buffer);
    stream.Write(buffer, 0, buffer.Length);
}

Our playing, stopping, and recording functions:

public void start()
{
    microphone.BufferDuration = TimeSpan.FromMilliseconds(100);
    buffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
    stream.SetLength(0);
    microphone.Start();
}
//
public void stop()
{
    if (microphone.State == MicrophoneState.Started)
    {
        microphone.Stop();
    }
}
//
public void play()
{
    if (stream != null)
    {
        sound = new SoundEffect(stream.ToArray(), microphone.SampleRate, AudioChannels.Mono);
        isound = sound.CreateInstance();
        isound.Pitch = 0f;
        isound.Volume = 1f;
        isound.Play();
    }
}
//

Done.

We made it.

But we need to make our app a little user friendly , so we need to tell user the state of program. I made a simple on in the draw method:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    // TODO: Add your drawing code here
    spriteBatch.Begin();
    spriteBatch.DrawString(myfont, programstate, new Vector2(100, 100), Color.Black);
    spriteBatch.End();
    base.Draw(gameTime);
}

So we write the state of program on the screen.

Points of Interest    

Well it was the easiest way of recording sound, you can play with pitch of the sound and have some fun.

History 

Started it on 1/27/2013.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

F.moghaddampoor
Engineer
Iran (Islamic Republic Of) Iran (Islamic Republic Of)
Education:
 
NODET 2003-2007
B.Sc. Electrical Power Engineering 2007–2012
 
Work:
 
T.G.D. Co.(Power,Software) July 2010 -February 2012
Artnous Co.(Power) July 2010 -February 2012
Savay Co.(Software) September 2011- July 2012

Comments and Discussions

 
QuestionHow to download??? PinmemberMember 98070235-Mar-13 1:55 
QuestionDownloads should be hosted on Code Project PinmvpMika Wendelius2-Feb-13 7:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 2 Feb 2013
Article Copyright 2013 by F.moghaddampoor
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid