Click here to Skip to main content
15,895,142 members
Articles / Mobile Apps / Windows Phone 7

Making a Voice Recorder on Windows Phone

Rate me:
Please Sign up or sign in to vote.
4.92/5 (23 votes)
30 Mar 2011CPOL14 min read 110K   5.3K   43  
Demonstration of what needs to be done to make a voice recorder on Windows Phone 7 including converting the raw bytes from the recording into a WAVE file.
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using J2i.Net.VoiceRecorder.Utility;
using Microsoft.Phone.Shell;
using Microsoft.Xna.Framework.Audio;


namespace J2i.Net.VoiceRecorder.ViewModels
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            this.Items = new ObservableCollection<RecordingDetails>();

            var isoStore = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();

            if (!isoStore.DirectoryExists("settings"))
                isoStore.CreateDirectory("settings");
            if (!isoStore.DirectoryExists("data"))
                isoStore.CreateDirectory("data");
            if (!isoStore.DirectoryExists("recordings"))
                isoStore.CreateDirectory("recordings");

        }

        //public bool IsRecording { get; private set; }
        private Microphone _currentMicrophone;
        private MemoryStream _currentRecordingStream;
        private byte[] _audioBuffer;
        private bool _stopRequested;
        private int _sampleRate = 0;
        private string _baseFileName;

        private SoundEffectInstance _currentSound = null;
                
        // MyConfiguration - generated from ObservableField snippet - Joel Ivory Johnson
        private ConfigurationViewModel _myConfiguration;
        public ConfigurationViewModel MyConfiguration
        {
        get { return _myConfiguration ?? (_myConfiguration = ConfigurationViewModel.GetConfiguration()); }
            set
            {
                if (_myConfiguration != value)
                {
                    _myConfiguration = value;
                    NotifyPropertyChanged("MyConfiguration");
                }
            }
        }
        //-----


                
        // IsRecording - generated from ObservableField snippet - Joel Ivory Johnson

        private bool _isRecording;
        public bool IsRecording
        {
        get { return _isRecording; }
            set
            {
                if (_isRecording != value)
                {
                    _isRecording = value;
                    NotifyPropertyChanged("IsRecording");
                }
            }
        }
        //-----

        /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public ObservableCollection<RecordingDetails> Items { get; private set; }

        private RecordingDetails _selectedRecording;
        public RecordingDetails SelectedRecording
        {
            get { return _selectedRecording;  }
            set
            {
                if(value!=_selectedRecording)
                {
                    _selectedRecording = value;
                    NotifyPropertyChanged("SelectedRecording");
                    if (value != null)
                        LastSelectedRecording = value;
                }
            }
        }

                
        // LastSelectedRecording - generated from ObservableField snippet - Joel Ivory Johnson

        private RecordingDetails _lastSelectedRecording;
        public RecordingDetails LastSelectedRecording
        {
        get { return _lastSelectedRecording; }
            set
            {
                if (_lastSelectedRecording != value)
                {
                    _lastSelectedRecording = value;
                    NotifyPropertyChanged("LastSelectedRecording");
                }
            }
        }
        //-----


        public void ApplySettings()
        {
            PhoneApplicationService.Current.ApplicationIdleDetectionMode = (MyConfiguration.AllowRunUnderLockScreen)
                                                                               ? IdleDetectionMode.Disabled
                                                                               : IdleDetectionMode.Enabled;
        }

        public void CreateNewRecording()
        {
            SelectedRecording = new RecordingDetails() {Title = DateTime.Now.ToLongDateString(), IsNew = true};
        }

        public void StartRecording()
        {
            if (_currentMicrophone == null)
            {
                _currentMicrophone = Microphone.Default;
                _currentMicrophone.BufferReady += new EventHandler<EventArgs>(_currentMicrophone_BufferReady);
                _audioBuffer = new byte[_currentMicrophone.GetSampleSizeInBytes(_currentMicrophone.BufferDuration)];
                _sampleRate = _currentMicrophone.SampleRate;
            }

            //SelectedRecording = new RecordingDetails(){Title = DateTime.Now.ToString(), TimeStamp = DateTime.Now};
            _baseFileName = (DateTime.Now.Ticks/10000).ToString();            
            _stopRequested = false;
            _currentRecordingStream = new MemoryStream(1048576);
            IsRecording = true;
            _currentMicrophone.Start();
        }


        public void RequestStopRecording()
        {
            _stopRequested = true;
        }

        void _currentMicrophone_BufferReady(object sender, EventArgs e)
        {
            _currentMicrophone.GetData(_audioBuffer);
            _currentRecordingStream.Write(_audioBuffer,0,_audioBuffer.Length);
            if (!_stopRequested) return;
            _currentMicrophone.Stop();
            var isoStore = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();

            using (var targetFile = isoStore.CreateFile(SelectedRecording.FilePath = String.Format("recordings/{0}.wav", _baseFileName)))
            {
                WaveHeaderWriter.WriteHeader(targetFile, (int)_currentRecordingStream.Length, 1, _sampleRate);
                var dataBuffer = _currentRecordingStream.GetBuffer();
                targetFile.Write(dataBuffer,0,(int)_currentRecordingStream.Length);                    
                targetFile.Flush();
                targetFile.Close();
            }
            IsRecording = false;
            CommitRecording();
            LoadData();
        }

        public void CommitRecording()
        {                
            var myDataSaver = new DataSaver<RecordingDetails>() {};
            myDataSaver.SaveMyData(LastSelectedRecording,String.Format("data/{0}.dat",_baseFileName) );
            
        }

        public void SaveUpdate()
        {
            var myDataSaver = new DataSaver<RecordingDetails>() {};
            myDataSaver.SaveMyData(LastSelectedRecording, LastSelectedRecording.SourceFileName);
        }

        public void ReloadUpdate()
        {
            var myDataSaver = new DataSaver<RecordingDetails>();
            var item = myDataSaver.LoadMyData(LastSelectedRecording.SourceFileName);
            item.SourceFileName = LastSelectedRecording.SourceFileName;
            LastSelectedRecording.Copy(item);
        }

        public void Delete(RecordingDetails target)
        {
            var isoStore = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();

            //delete the wave file
            isoStore.DeleteFile(target.FilePath);
            //delete the file description
            isoStore.DeleteFile(target.SourceFileName);

            this.LoadData();
            
        }

        public void PlayRecording(RecordingDetails source)
        {
            SoundEffect se;
            if(_currentSound!=null)
            {
                _currentSound.Stop();
                _currentSound = null;
            }
            var isoStore = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
            if(isoStore.FileExists(source.FilePath))
            {
                byte[] fileContents;
                using (var fileStream = isoStore.OpenFile(source.FilePath, FileMode.Open))
                {
                    se = SoundEffect.FromStream(fileStream);
                    fileStream.Close();//not really needed, but it makes me feel better. 
                }

                _currentSound = se.CreateInstance();
                _currentSound.Play();
            }
        }



        private string _sampleProperty = "Sample Runtime Property Value";
        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding
        /// </summary>
        /// <returns></returns>
        public string SampleProperty
        {
            get
            {
                return _sampleProperty;
            }
            set
            {
                if (value != _sampleProperty)
                {
                    _sampleProperty = value;
                    NotifyPropertyChanged("SampleProperty");
                }
            }
        }

        public bool IsDataLoaded
        {
            get;
            private set;
        }

        /// <summary>
        /// Creates and adds a few ItemViewModel objects into the Items collection.
        /// </summary>
public void LoadData()
{
    var isoStore = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
    var recordingList = isoStore.GetFileNames("data/*.xml");
    var myDataSaver = new DataSaver<RecordingDetails>();
    Items.Clear();
    foreach (var desc in recordingList.Select(item =>
                                                    {
                                                        var result =myDataSaver.LoadMyData(String.Format("data/{0}", item));
                                                        result.SourceFileName = String.Format("data/{0}", item);
                                                        return result;
                                                    }))
    {
        Items.Add(desc);
    }
    this.IsDataLoaded = true;
}

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer
United States United States
I attended Southern Polytechnic State University and earned a Bachelors of Science in Computer Science and later returned to earn a Masters of Science in Software Engineering. I've largely developed solutions that are based on a mix of Microsoft technologies with open source technologies mixed in. I've got an interest in astronomy and you'll see that interest overflow into some of my code project articles from time to time.



Twitter:@j2inet

Instagram: j2inet


Comments and Discussions