Skip to content

Emulator != Real device

May 15, 2011

While working on Picture of the Day i spent about 30min’s pulling my hair out trying to get light/dark theming working with the app bar buttons switching. This is when you switch between light and dark theming the buttons should switch between black and white to make them stand out. It appeared to work in blend but not on the emulator and unfortantely i didnt have access to my phone at that time, but later on plugging it in and running it own a real device i was able to see that it works.

This is not the first time i have come across issues, in earlier versions of the emulators the on screen keyboard did not work when you where in landscape mode.

So i have learnt my lesson twice now, whenever it doesnt work on the emulator and you think it should plug in the real phone and give it a go!

Advertisements

Using the microphone

May 3, 2011

Their are 4 main things you need to do to use the microsoft phone coming from a silverlight project

– Reference “Microsoft.Xna.Framework”

– Add “ID_CAP_MICROPHONE” as a capabiltiy in the WMAppManifest.xml

– Add a  XNA framework DispatcherTimer

– Get the Audio from the Microphone

Coming from building other silverlight apps on the phone the only two new things should be the last two things on that list, XNA dispatcher timer and reading data from the phone.

For the XNA dispatcher you need to implement a IApplicationService and an entry point. The entry point will be added to your App.xaml.cs in its constructor and look something like ”

ApplicationLifetimeObjects.Add(new XnaAsyncDispatcher(TimeSpan.FromMilliseconds(50)));

The rest of your xna dispatcher is just running off a dispatcher timer and updating the framework dispatcher as such below

    public class XnaAsyncDispatcher : IApplicationService
    {
        private readonly DispatcherTimer _frameworkDispatcherTimer;

        public XnaAsyncDispatcher(TimeSpan dispatchInterval)
        {
            try
            {
                _frameworkDispatcherTimer = new DispatcherTimer();
                _frameworkDispatcherTimer.Tick += FrameworkDispatcherUpdate;
                _frameworkDispatcherTimer.Interval = dispatchInterval;
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }

        public void StartService(ApplicationServiceContext context)
        {
            try
            {
                _frameworkDispatcherTimer.Start();
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }
        public void StopService()
        {
            try
            {
                _frameworkDispatcherTimer.Stop();
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }

        private static void FrameworkDispatcherUpdate(object sender, EventArgs e)
        {
            try
            {
                FrameworkDispatcher.Update();
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }

    }

As you can see i am over cautious with exceptions and want to log every one so it can be resolved.

The main part of the code to be in the viewmodel below will record the audio then play it back when your finished

public class AudioRecorderViewModel
    {
        public RelayCommand StartRecording { get; private set; }
        public RelayCommand StopRecording { get; private set; }

        private readonly Microphone _microphone = Microphone.Default;
        private readonly TimeSpan _fromMilliseconds = TimeSpan.FromMilliseconds(1000);
        private MemoryStream _memoryStream;
        private byte[] _buffer;
        private DynamicSoundEffectInstance _dynamicSound;

        public AudioRecorderViewModel()
        {
            try
            {
                StartRecording = new RelayCommand(RunStartRecording);
                StopRecording = new RelayCommand(RunStopRecording);
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }

        private void RunStopRecording(object obj)
        {
            try
            {
                _microphone.BufferReady -= MicrophoneBufferReady;
                _microphone.Stop();
                _dynamicSound.SubmitBuffer(_memoryStream.GetBuffer());
                _dynamicSound.Play();
                _memoryStream.Dispose();
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }

        private void RunStartRecording(object obj)
        {
            try
            {
                _memoryStream = new MemoryStream();
                _microphone.BufferReady += MicrophoneBufferReady;
                _microphone.BufferDuration = _fromMilliseconds;
                _buffer = new byte[_microphone.GetSampleSizeInBytes(_microphone.BufferDuration)];
                _dynamicSound = new DynamicSoundEffectInstance(_microphone.SampleRate, AudioChannels.Mono);

                _microphone.Start();
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }

        private void MicrophoneBufferReady(object sender, EventArgs e)
        {
            try
            {
                PhoneLogger.Info("Buffer Ready at {0}", DateTime.Now);
                _microphone.GetData(_buffer);
                PhoneLogger.Info("Buffer Length {0}", _buffer.Length);

                _memoryStream.Write(_buffer, 0, _buffer.Length);
            }
            catch (Exception exception)
            {
                PhoneLogger.Exception(exception);
            }
        }
    }