Archive for September, 2010

Fixing the Microphone Audio cut-off issue in Windows Phone 7 Silverlight.

Thanks to some samples online it’s relatively straightforward to access the Microphone from a Silverlight application on Windows Phone 7. However when using these samples I noticed that sometimes the last half second of audio wasn’t

Getting Started

  • First add a reference to Microsoft.Xna.Framework to your Silverlight application. Words cannot describe how much this rubs me the wrong way, why it’s not part of the System namespaces or a separate shared Microsoft assembly is beyond me.
  • Add the dispatcher timer for XNA as described in this blog post.
  • Add two buttons to a page (Start and Stop). Call the StartRecording and StopRecording methods in the appropriate click event handlers.
 private bool isRecording;
 private MemoryStream ms;
 private readonly  Microphone mic = Microphone.Default;
 private byte[] buffer;
 
 private void StartRecording()
 {
     int bufferSize = mic.GetSampleSizeInBytes(mic.BufferDuration);
     this.buffer = new byte[bufferSize];
     mic.BufferReady += this.MicrophoneBufferReady;
     SoundEffect.MasterVolume = 1.0f;
 
     if (ms != null)
     {
         ms.Close();
     }
 
     ms = new MemoryStream();
     mic.Start();
     this.isRecording = true;
 }
 
 private void MicrophoneBufferReady(object sender, EventArgs e)
 {
     int bytesRead = 0;
     while ((bytesRead = mic.GetData(buffer, 0, buffer.Length)) > 0)
     {
         ms.Write(buffer, 0, bytesRead);
     }
 
     if (!this.isRecording)
     {
         ms.Flush();
         mic.Stop();
     }
 }
 
 private void StopRecording()
 {
     if (mic.State != MicrophoneState.Stopped)
     {
         // Calling stop here would stop receiving before  
         // the last buffer was complete. 
         //// mic.Stop(); 
         this.isRecording = false ;
     }
 }
 

Fixing the Audio cut-off issue.

The problem is that as buffers are being pushed to your application, the user pushes the stop button. Calling mic.Stop() immediately causes the buffers to stop being sent to your application and the last buffer that hadn’t completed is lost (leaving the audio chopped off).

The easiest fix for this is to have the Stop button request that the next buffer be the last to be recorded simply by setting a flag this.isRecording = false; and the event handler checks it after processing the last buffer. Viola! Problem solved.

Update: Added a link to blog regarding XNA dispatcher.

Advertisements

2 Comments