One very common task for many mobile applications is the ability to capture the audio from your microphone and use it inside your application. Doing this on your WP7 device could not be easier. To do this you really need like 20 lines of code and a good speaking voice (ok the second part is mostly optional).
How do I capture audio on my device?
1) Add reference to Microsoft.Xna.Framework (the microphone library is here) in your application.
2) Create a dispatcher class which updates the Framework Dispatcher (information from this post) as below:
public class XNAAsyncDispatcher : IApplicationService
{
private DispatcherTimer frameworkDispatcherTimer;
public XNAAsyncDispatcher( TimeSpan dispatchInterval )
{
this.frameworkDispatcherTimer = new DispatcherTimer();
this.frameworkDispatcherTimer.Tick += new EventHandler( frameworkDispatcherTimer_Tick );
this.frameworkDispatcherTimer.Interval = dispatchInterval;
}
void IApplicationService.StartService( ApplicationServiceContext context ) { this.frameworkDispatcherTimer.Start(); }
void IApplicationService.StopService() { this.frameworkDispatcherTimer.Stop(); }
void frameworkDispatcherTimer_Tick( object sender, EventArgs e ) { FrameworkDispatcher.Update(); }
}
3) Invoke the dispatcher class (above) in your App.xaml.cs class
ApplicationLifetimeObjects.Add( new XNAAsyncDispatcher( TimeSpan.FromMilliseconds( 50 ) ) );
3a) If you forget to do the items in step 2 & 3 you will receive the following error:

4) Create the code to actually perform the recording and playback;
private Microphone _microphone = Microphone.Default;
private TimeSpan _fromMilliseconds = TimeSpan.FromMilliseconds( 1000 );
private byte[] _buffer;
private DynamicSoundEffectInstance _dynamicSound;
private MemoryStream _memoryStream = new MemoryStream();
private void Start_Click( object sender, RoutedEventArgs e )
{
_microphone.BufferReady += new EventHandler( _microphone_BufferReady );
_microphone.BufferDuration = _fromMilliseconds;
_buffer = new byte[_microphone.GetSampleSizeInBytes( _microphone.BufferDuration )];
_dynamicSound = new DynamicSoundEffectInstance( _microphone.SampleRate, AudioChannels.Mono );
_microphone.Start();
}
void _microphone_BufferReady( object sender, EventArgs e )
{
Debug.WriteLine( "Buffer Ready at {0}", DateTime.Now );
_microphone.GetData( _buffer );
Debug.WriteLine( "Buffer Length {0}", _buffer.Length );
_memoryStream.Write( _buffer, 0, _buffer.Length );
}
private void Stop_Click( object sender, RoutedEventArgs e )
{
_microphone.BufferReady -= new EventHandler( _microphone_BufferReady );
_microphone.Stop();
}
private void Play_Click( object sender, RoutedEventArgs e )
{
_dynamicSound.SubmitBuffer( _memoryStream.GetBuffer() );
_dynamicSound.Play();
}
In the code above we are doing 3 things;
- Starting the recording:
To start the recording what we want to do is wire up an event handler to capture the buffered information from the stream, this is the BufferReady event. We will also want to set the buffer duration (how much is recorded per cycle. I have mine set to 1 second which I believe is the max but you can set yours to any value. Finally I am creating a new instance of the dynamic sound class (this allows you to play back the audio).
- Stopping the recording;
Once we are done recording you can simply call .Stop and it will stop buffering the data, this is needed to avoid dead air
- Playing the recording;
Once I am done recording the data i submit the memory stream to the DynamicSoundEffectInstance instance and call play. Now you have audio playing back.
As you can see capturing and playing audio is pretty easy and can be done with very little effort.
Till next time,
Posted
10-22-2010 6:51 AM
by
Derik Whittaker