Creating Voice Recorder in Windows Store Apps

In this article we are creating a Media Recorder app in Windows Store apps.

Introduction

Today we are going to create a Media Recorder app in Windows Store apps. Using this app we can record voice in multiple formats and multiple qualities and after recording you can save it. To use this app you may need a Microphone to capture the voice.

Step 1

Open Visual Studio 2012 and start new Windows Store apps project.

Step 2

Go to Solution Explorer and double-click on "Package.appxmanifest" to open it. In the capabilities tab check "Microphone" and "Music Library".

Capibilities-Windows-Store-Apps.png

Step 3

In this step add the AudioEncodingFormat enum used by the application to allow the selection of an audio encoding format. Add a class named "AudioEncodingFormat" and replace all the code with the following code.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace MediaRecorder

{

    public enum AudioEncodingFormat

    {

        Mp3,

        Mp4,

        Avi,

        Wma

    };

    public static class AudioEncodingFormatExtensions

    {

        public static string ToFileExtension(this AudioEncodingFormat encodingFormat)

        {

            switch (encodingFormat)

            {

                case AudioEncodingFormat.Mp3:

                    return ".mp3";

                case AudioEncodingFormat.Mp4:

                    return ".mp4";

                case AudioEncodingFormat.Avi:

                    return ".avi";

                case AudioEncodingFormat.Wma:

                    return ".wma";             

                default:

                    throw new ArgumentOutOfRangeException("encodingFormat");

            }

        }

    }

}

Step 4

Now go to "MainPage.xaml" and add the following code.

<Page

    x:Class="MediaRecorder.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:MediaRecorder"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">

 

    <Grid Background="SteelBlue">

        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">

            <StackPanel Orientation="Horizontal" Margin="0,10,10,10">

                <TextBlock>Select Audio Format</TextBlock>

                <ComboBox Name="AudioFormat" ItemsSource="{Binding}" MinWidth="230" Margin="10,0,0,0"

                          SelectionChanged="AudioFormat_SelectionChanged"></ComboBox>

            </StackPanel>

            <StackPanel Orientation="Horizontal" Margin="0,10,10,10">

                <TextBlock>Select Audio Quality</TextBlock>

                <ComboBox Name="AudioQuality" ItemsSource="{Binding}" MinWidth="230" Margin="10,0,0,0"

                          SelectionChanged="AudioQuality_SelectionChanged"></ComboBox>

            </StackPanel>

            <StackPanel Orientation="Horizontal">

                <Button Name="RecordBtn" Click="RecordBtn_Click" >Record</Button>

                <Button Name="StopBtn" Click="StopBtn_Click" >Stop</Button>

                <Button Name="SaveBtn" Click="SaveBtn_Click" >Save</Button>

            </StackPanel>

            <StackPanel  Orientation="Horizontal" Margin="0,10,0,0">

                <TextBlock>Duration</TextBlock>

                <TextBlock Name="Duration" Text="{Binding}" Margin="10,0,0,0"></TextBlock>

            </StackPanel>

        </StackPanel>

    </Grid>

</Page>

Step 5

Go to the "MainPage.xaml.cs" page and add the following namespaces.

using Windows.Media.MediaProperties;

using Windows.Storage;

using Windows.Storage.Pickers;

using Windows.Storage.Streams;

using Windows.UI.Popups;

using Windows.Media.Capture;

using System.Threading.Tasks;

Step 6

Here is the complete "MainPage.xaml.cs" page code.

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using Windows.Foundation;

using Windows.Foundation.Collections;

using Windows.UI.Xaml;

using Windows.UI.Xaml.Controls;

using Windows.UI.Xaml.Controls.Primitives;

using Windows.UI.Xaml.Data;

using Windows.UI.Xaml.Input;

using Windows.UI.Xaml.Media;

using Windows.UI.Xaml.Navigation;

using Windows.Media.MediaProperties;

using Windows.Storage;

using Windows.Storage.Pickers;

using Windows.Storage.Streams;

using Windows.UI.Popups;

using Windows.Media.Capture;

using System.Threading.Tasks;

 

namespace MediaRecorder

    public sealed partial class MainPage : Page

    {

        public enum RecordingMode

        {

            Initializing,

            Recording,

            Stopped,

        };

 

        private MediaCapture CaptureMedia;

        private IRandomAccessStream AudioStream;

        private FileSavePicker FileSave;

        private DispatcherTimer DishTimer;

        private TimeSpan SpanTime;

        private AudioEncodingFormat SelectedFormat;

        private AudioEncodingQuality SelectedQuality;

 

        public MainPage()

        {

            this.InitializeComponent();

        }

        protected async override void OnNavigatedTo(NavigationEventArgs e)

        {

            await InitMediaCapture();

            LoadAudioEncodings();

            LoadAudioQualities();

            UpdateRecordingControls(RecordingMode.Initializing);

            InitTimer();

        }

        private async Task InitMediaCapture()

        {

            CaptureMedia = new MediaCapture();

            var captureInitSettings = new MediaCaptureInitializationSettings();

            captureInitSettings.StreamingCaptureMode = StreamingCaptureMode.Audio;

            await CaptureMedia.InitializeAsync(captureInitSettings);

            CaptureMedia.Failed += MediaCaptureOnFailed;

            CaptureMedia.RecordLimitationExceeded += MediaCaptureOnRecordLimitationExceeded;

        }

        private void LoadAudioEncodings()

        {

            var audioEncodingFormats = Enum.GetValues(typeof(AudioEncodingFormat)).Cast<AudioEncodingFormat>();

            AudioFormat.ItemsSource = audioEncodingFormats;

            AudioFormat.SelectedItem = AudioEncodingFormat.Mp3;

        }

        private void LoadAudioQualities()

        {

            var audioQualities = Enum.GetValues(typeof(AudioEncodingQuality)).Cast<AudioEncodingQuality>();

            AudioQuality.ItemsSource = audioQualities;

            AudioQuality.SelectedItem = AudioEncodingQuality.Auto;

        } 

        private void UpdateRecordingControls(RecordingMode recordingMode)

        {

            switch (recordingMode)

            {

                case RecordingMode.Initializing:

                    RecordBtn.IsEnabled = true;

                    StopBtn.IsEnabled = false;

                    SaveBtn.IsEnabled = false;

                    break;

                case RecordingMode.Recording:

                    RecordBtn.IsEnabled = false;

                    StopBtn.IsEnabled = true;

                    SaveBtn.IsEnabled = false;

                    break;

                case RecordingMode.Stopped:

                    RecordBtn.IsEnabled = true;

                    StopBtn.IsEnabled = false;

                    SaveBtn.IsEnabled = true;

                    break;

                default:

                    throw new ArgumentOutOfRangeException("recordingMode");

            }

        } 

        private void InitTimer()

        {

            DishTimer = new DispatcherTimer();

            DishTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);

            DishTimer.Tick += TimerOnTick;

        }

        private void TimerOnTick(object sender, object o)

        {

            SpanTime = SpanTime.Add(DishTimer.Interval);

            Duration.DataContext = SpanTime;

        }

        private async void MediaCaptureOnRecordLimitationExceeded(MediaCapture sender)

        {

            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>

            {

                await sender.StopRecordAsync();

                var warningMessage = new MessageDialog("The media recording has been stopped because you exceeded the maximum recording length.", "Recording Stoppped");

                await warningMessage.ShowAsync();

            });

        }

 

        private async void MediaCaptureOnFailed(MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs)

        {

            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>

            {

                var warningMessage = new MessageDialog(String.Format("The media capture failed: {0}", errorEventArgs.Message), "Capture Failed");

                await warningMessage.ShowAsync();

            });

        }

        private async void RecordBtn_Click(object sender, RoutedEventArgs e)

        {

            MediaEncodingProfile encodingProfile = null;

            switch (SelectedFormat)

            {

                case AudioEncodingFormat.Mp3:

                    encodingProfile = MediaEncodingProfile.CreateMp3(SelectedQuality);

                    break;

                case AudioEncodingFormat.Mp4:

                    encodingProfile = MediaEncodingProfile.CreateM4a(SelectedQuality);

                    break;

                case AudioEncodingFormat.Wma:

                    encodingProfile = MediaEncodingProfile.CreateWma(SelectedQuality);

                    break;

                default:

                    throw new ArgumentOutOfRangeException();

            } 

            AudioStream = new InMemoryRandomAccessStream();

            await CaptureMedia.StartRecordToStreamAsync(encodingProfile, AudioStream);

            UpdateRecordingControls(RecordingMode.Recording);

            DishTimer.Start();

        } 

        private async void StopBtn_Click(object sender, RoutedEventArgs e)

        {

            await CaptureMedia.StopRecordAsync();

            UpdateRecordingControls(RecordingMode.Stopped);

            DishTimer.Stop();

        }

        private async void SaveBtn_Click(object sender, RoutedEventArgs e)

        {

            var mediaFile = await FileSave.PickSaveFileAsync();

 

            if (mediaFile != null)

            {

                using (var dataReader = new DataReader(AudioStream.GetInputStreamAt(0)))

                {

                    await dataReader.LoadAsync((uint)AudioStream.Size);

                    byte[] buffer = new byte[(int)AudioStream.Size];

                    dataReader.ReadBytes(buffer);

                    await FileIO.WriteBytesAsync(mediaFile, buffer);

                    UpdateRecordingControls(RecordingMode.Initializing);

                }

            }

        } 

        private void AudioFormat_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            SelectedFormat = (AudioEncodingFormat)AudioFormat.SelectedItem;

            InitFileSavePicker();

        } 

        private void InitFileSavePicker()

        {

            FileSave = new FileSavePicker();

            FileSave.FileTypeChoices.Add("Encoding", new List<string>() { SelectedFormat.ToFileExtension() });

            FileSave.SuggestedStartLocation = PickerLocationId.MusicLibrary;

        }

        private void AudioQuality_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            SelectedQuality = (AudioEncodingQuality)AudioQuality.SelectedItem;

        }

    }

}

Step 7

Now run you application. The first time it will ask for permission to access the microphone. Click on "Allow".

Allow-Permision-Windows-Store-Apps.png

Step 8

Select the media format and quality and click on "Record" voice. After recording voice you can save it on your system by clicking on "Save".

Result-Windows-Store-Apps.png