Audio Recording in WP7

Because it is possible to use the XNA libraries within a Silverlight project you can add audio recording in your application using the Microphone class found in the Microsoft.Xna.Framework.Audio namespace. You can test this on the Emulator as it will work with a microphone attached to the host PC.

First add a reference to Microsoft.Xna.Framework.dll to your project.

Next to make life easier add “using Microsoft.Xna.Framework.Audio;” to the top of your code file. You can access the Microphone through the static Microphone.Default property but for ease I created a local variable called m.

Next you need to decide what you are going to do with recorded audio. I built a simple audio memo application which stores the audio data in memory for instant playback. For simplicity I added MemoryStream to my app. I will write audio data to this and then I can easily get a byte array of the entire buffer to pass to the SoundEffect class to playback later. You could also write to a file in Isolated Storage or send to a web service…

In the constructor of my page I added an event handler for the BufferReady event of the Microphone. This is called each time the buffer is full and in the handler I copy the contents to the memory stream.

I created a Record button. I then set the BufferDuration on the Microphone object to 1 second (the maximum value), this is not strictly necessary as you’ll be copying data from the Microphone when it notifies you. Then I call Start to open the Microphone and start recording. Each time the buffer fills it is copied to the memorystream. When a Stop button is pressed I called Stop() on the Microphone to stop recording. Afterwards the MemoryStream is closed and we can now access the underlying buffer for playback.

A third button, you guess it “Play”, uses the SoundEffect class to play back the contents of the buffer. Into the constructor I pass the .ToArray() method of the MemoryStream, the SampleRate from the Microphone and AudioChannels.Mono since we know this is a mono source. You can then either call Play() or if you want to muck about with the sound you can use the overload which accepts volume, pitch and pan values. For example se.Play(0.7f, 0.5f, -1.0f) plays the sound at 70% volume, with pitch raised half an octave and through the left channel. Unless the user is wearing a stereo headset the panning will probably be lost on them. By playing with the pitch property (-1 – one octave lower through to +1 – one octave higher) you can probably find your perfect balance between Brian Blessed and Joe Pasquale…

As Rob Miles noted in his blog there seems to be an issue with pitch values > 0.6 in the current release.

By Peter Foot

Microsoft Windows Development MVP