Working Around the Missing Real Time Clock in Windows IoT

I’ve got a project planned involving Windows IoT for which I need the system to have the correct time. The Raspberry Pi with Windows IoT has no real time clock. It initializes the time over NTP when connected to a network. But when not connected to a network the time will be wrong.   It has no support for a real time clock at this point in time. That’s no good. I searched for how people have worked around this. A frequent solution was to add a real time IC and have ones solution communicate directly with the real time chip and ignore the native APIs built around time. I don’t like this solution. I’d like to maintain compatibility with other systems and not make something that is dependent on a specific implementation of a clock. I wanted a way to get the Raspberry Pi to initialize from the RTC instead of NTP. 

It took a while to create a solution for this because the APIs needed to manipulate the system time are not available to UWP applications. I managed to create a solution with a power shell script, a program that I made, and a real time clock. The complete solution is available at CodeProject.com. Here is a summary of the solution. The stand alone application I made only does two things. It can read the time from the real time clock chip that I used and print it out as a string. It can also look at the system time and set the time in the real time clock to match. I use the latter of these two capabilities to set the time on the real time clock. When ever the system boots up the first of those capabilities is used to expose the current time in the RTC  to the Power Shell environment. From there I can use the Set-Date command to update the system time. I’ve saved a Power Shell script to run every time the system turns on to do just this. Now when I turn on my Raspberry Pi off network within a few seconds of turning it on it now has the right time. 😊

ViewModelBase and DelegateCommands in Sample Code

I’m working on some sample code for some upcoming blog post. There are two classes that are used throughout the examples and will probably be used in future samples. I wanted to mention them here for future blog post. This is applicable to both UWP and WPF projects. The first is the base class that I use for all of my ViewModel classes. 

using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Threading;


namespace Common
{
    public class ViewModelBase
    {

        public static System.Threading.SynchronizationContext SyncContext;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                SendOrPostCallback  a = (o) => { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); };
                if (SyncContext == null)
                    a(null);
                else
                    SyncContext.Send(a, null);
                
            }
        }

        protected void OnPropertyChanged(Expression> expression)
        {
            OnPropertyChanged(((MemberExpression)expression.Body).Member.Name);
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

The field SyncContext is needed for code that runs asynchronously on another thread (for WPF projects this is a Dispatcher instead). If the code attached to PropertyChanged interacts with the UI an exception will occur if this interaction happens on a different thread than the one on which the UI controls were created. When the OnPropertyChanged method is called the SyncContext is used to marshal control back to the UI thread.  One of the OnPropertyChanged methods takes as an argument an expression. I prefer to use this when passing the name of the field being updated to the OnPropertyChange handler because it provides the advantage of compile checking for typos in the name and will be updated if the Rename command is used on a property.  The other frequently used class(es) is the DelegateCommand

using System;
using System.Windows.Input;

namespace Common
{
    public class DelegateCommand : ICommand
    {
        public DelegateCommand(Action execute)
            : this(execute, null)
        {
        }

        public DelegateCommand(Action execute, Func canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute != null)
                return _canExecute();

            return true;
        }

        public void Execute(object parameter)
        {
            _execute();
        }

        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }

        public event EventHandler CanExecuteChanged;

        private Action _execute;
        private Func _canExecute;
    }

    public class DelegateCommand<T> : ICommand
    {
        public DelegateCommand(Action<T> execute)
            : this(execute, null)
        {
        }

        public DelegateCommand(Action<T> execute, Func<T, bool> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute != null)
            {

                return _canExecute((T)parameter);
            }

            return true;
        }

        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }

        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }

        public event EventHandler CanExecuteChanged;

        private Action<T> _execute;
        private Func<T, bool> _canExecute;
    }
}

The DelegateCommand class is used to make commands that can be bound to a button. This allows us to use DataBinding to associate code with a button through data binding. 

XNA Animated Sprite code uploaded to CodeProject.com

I’ve uploaded some code I was working on to animate sprites in XNA.

Animating a sprite isn’t difficult, but I wanted some way to animate them but reduce the coupling between code and the animation. The Content Pipeline is perfect for this. So I created a component that will handle the animation scenarios that I need along with a content extension so that I could load these animations as content. Right now the animation information is in an XML file. This is a stepping point towards having a graphical tool for handling this.

You can read about the code here or see a brief description of it in the video below

Welcome to the Site Mirror!

It seems that my hosting provider has gone through some changes for the worst; once a week for the past three weeks this site has gone offline because of some failure or data loss at my provider’s location. Because of the decrease in reliability I’ll be looking for a new provider. In the mean time I’ve started mirroring my content at here. Any new content I write will also be published here(I may just use WordPress as the primary host for this site, still undecided). If the main site ever goes down remember you can see the content heretoo.

Mango Beta 2 Available for Phones Today!

The Beta 2 Mango Windows Phone Tools are available to developers today! Included with the beta is the ability for developers registered with the AppHub to flash their retail devices.

I know there are some non-developers out there that want to also flash their phones and they may wonder how they get get their phones reflashed with the Mango beta. For the time being they cannot. There is an inherent risk in reflashing the phone; you could end up with a bricked phone if something goes bad. If this happens Microsoft has budgeted to take care of repairing up to one phone per developer. But Microsoft doesn’t see this risk as being appropriate for user audiences. [Some] developers on the other hand are willing to risk their device’s life and limb to have early access to something new. If you brick your device today Microsoft won’t be prepared to act on it for another couple of weeks. That’s not the best case scenario. But the alternative was to wait another couple of weeks before releasing the Mango tools. If you don’t feel safe walking the tight rope without a safety net then don’t re-flash your device yet.

According to the Windows Phone Developer site if you are a registered developer you will receive an e-mail inviting you to participate in early access to Mango.

Changing the Pitch of a Sound

I got a tweet earlier today from some one asking me how to change the pitch of a wave file. The person asking was aware that SoundEffectInstance has a setting to alter pitch but it wasn’t sufficient for his needs. He needed to be able to save the modified WAV to a file. It’s something that is easy to do. So I made a quick example

Video Example

I used a technique that comes close to matching linear interpolation. It get’s the job done but isn’t the best technique because of the opportunity for certain types of distortion to introduced. Methods with less distortion are available at the cost of potentially more CPU cycles. For the example I made no matter what the original sample rate was I am playing back at 44KHz and adjusting my interpolation accordingly so that no unintentional changes in pitch are introduced.

To do the work I’ve created a class named AdjustedSoundEffect. It has a Play() method that takes as it’s argument the factor by which the pitch should be adjusted where 1 plays the sound at the original pitch, 2 plays it at twice its pitch, and 0.5 plays it at half its pitch.

If you are interested the code I used is below.

using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Xna.Framework.Audio;

namespace J2i.Net.VoiceRecorder.Utility
{
    public class AdjustedSoundEffect
    {
        //I will always playback at 44KHz regardless of the original sample rate. 
        //I'm making appropriate adjustments to prevent this from resulting in the
        //pitch being shifted. 
        private const int PlaybackSampleRate = 16000;
        private const int BufferSize = PlaybackSampleRate*2;

        private int _channelCount = 1;
        private int _sampleRate;
        private int _bytesPerSample = 16;
        private int _byteCount = 0;
        private float _baseStepRate = 1;
        private float _adjustedStepRate;
        private float _index = 0;
        private int playbackBufferIndex = 0;
        private int _sampleStep = 2;

        private bool _timeToStop = false;

        private byte[][] _playbackBuffers;

        public bool IsPlaying { get; set;  }

        public object SyncRoot = new object();


        private DynamicSoundEffectInstance _dse;

        public static AdjustedSoundEffect FromStream(Stream source)
        {
            var retVal = new AdjustedSoundEffect(source);
            return retVal;
        }

        public AdjustedSoundEffect()
        {
            _playbackBuffers = new byte[3][];
            for (var i = 0; i < _playbackBuffers.Length;++i )
            {
                _playbackBuffers[i] = new byte[BufferSize];
            }
                _dse = new DynamicSoundEffectInstance(PlaybackSampleRate, AudioChannels.Stereo);
            _dse.BufferNeeded += new EventHandler<EventArgs>(_dse_BufferNeeded);
        }

        void SubmitNextBuffer()
        {
            if(_timeToStop)
            {
                Stop();
            }
            lock (SyncRoot)
            {
                byte[] nextBuffer = _playbackBuffers[playbackBufferIndex];
                playbackBufferIndex = (playbackBufferIndex + 1)%_playbackBuffers.Length;
                int i_step = 0;
                int i = 0;

                int endOfBufferMargin = 2*_channelCount;
                for (;
                    i < (nextBuffer.Length / 4) && (_index < (_sourceBuffer.Length - endOfBufferMargin));
                    ++i, i_step += 4)
                {

                    int k = _sampleStep*(int) _index;
                    if (k > _sourceBuffer.Length - endOfBufferMargin)
                        k = _sourceBuffer.Length -endOfBufferMargin ;
                    nextBuffer[i_step + 0] = _sourceBuffer[k + 0];
                    nextBuffer[i_step + 1] = _sourceBuffer[k + 1];
                    if (_channelCount == 2)
                    {
                        nextBuffer[i_step + 2] = _sourceBuffer[k + 2];
                        nextBuffer[i_step + 3] = _sourceBuffer[k + 3];
                    }
                    else
                    {
                        nextBuffer[i_step + 2] = _sourceBuffer[k + 0];
                        nextBuffer[i_step + 3] = _sourceBuffer[k + 1];

                    }
                    _index += _adjustedStepRate;
                }

                if ((_index >= _sourceBuffer.Length - endOfBufferMargin))
                    _timeToStop = true;
                for (; i < (nextBuffer.Length/4); ++i, i_step += 4)
                {
                    nextBuffer[i_step + 0] = 0;
                    nextBuffer[i_step + 1] = 0;
                    if (_channelCount == 2)
                    {
                        nextBuffer[i_step + 2] = 0;
                        nextBuffer[i_step + 3] = 0;
                    }
                }
                _dse.SubmitBuffer(nextBuffer);
            }
        }

        void _dse_BufferNeeded(object sender, EventArgs e)
        {
            SubmitNextBuffer();
        }

        private byte[] _sourceBuffer;
        

        public AdjustedSoundEffect(Stream source): this()
        {
            byte[] header = new byte[44];
            source.Read(header, 0, 44);

            // I'm assuming you passed a proper wave file so I won't bother 
            // verifying  that  the  header  is properly formatted and will 
            // accept it on faith :-)

            _channelCount = header[22] + (header[23] << 8);
            _sampleRate = header[24] | (header[25] << 8) | (header[26] << 16) | (header[27] << 24);
            _bytesPerSample = header[34]/8;
            _byteCount = header[40] | (header[41] << 8) | (header[42] << 16) | (header[43] << 24);
            _sampleStep = _bytesPerSample*_channelCount;
            _sourceBuffer = new byte[_byteCount];
            source.Read(_sourceBuffer, 0, _sourceBuffer.Length);


            _baseStepRate = ((float)_sampleRate) / PlaybackSampleRate;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pitchFactor">Factor by which pitch will be adjusted. 2 doubles the frequency,
        /// // 1 is normal speed, 0.5 halfs the frequency</param>
        public void Play(float pitchFactor)
        {
            _timeToStop = false;

            _index = 0;
            lock (SyncRoot)
            {
                _adjustedStepRate = _baseStepRate * pitchFactor;
                _index = 0;
                playbackBufferIndex = 0;
            }
            if(!IsPlaying)
            {
                SubmitNextBuffer();
                SubmitNextBuffer();
                SubmitNextBuffer();
                _dse.Play();
                IsPlaying = true;
            }
        }

        public void Stop()
        {
            if(IsPlaying)
            {
                _dse.Stop();
            }
        }
    }
}