Jul 12 2011

Open Syno : All apologies

Hi there,

First of all, the first two weeks of Open Syno have been very successful. Far more than expected to say the least. in the first week of its public availability, Open Syno has been installed on more than 300 phones, and that is really awesome. What is even more awesome, is that we also have received an amazing number of feedbacks from the community.

Among those feedbacks, some users had troubles decoding the audio properly, reporting glitches in the playback. We’ve found and fixed the problem : the reason was we didn’t bundle the right version of a third party dll : Managed Media Helpers.

So, now that it’s fixed, we are just waiting for Microsoft to finish the certification for the updated version.

We are deeply sorry for what happened, and we are looking forward to hear from you if the fix worked as expected for you. To make your voice heard, don’t hesitate to comment to this blog post !

The applied fix focuses on Wireless connectivity and 3G connection might not work perfectly yet, but we are working on it Winking smile

As usual, just a reminder : you can find us on github and on idea informer to post your issues and your ideas.

Cheers


Mar 19 2011

The age of stream

Allright, on the menu today, we have Streams as a main course.

While working on open syno one of the big challenge was to figure out how I could render an audio file, that is, read a stream, while writing to it.

First, you might try to have a look at the WebClient class, only to be disappointed, since the OpenReadAsync method’s behavior depends on the AllowReadStreamBuffering : if buffering is allowed, then the OpenReadAsync method will notify it got the job done only once the whole file has been downloaded (or “buffered”). And if buffering is not allowed, the notification will be raised right away, without even reading a single byte… and that part of the job will be left to us. That means we might as well use HttpWebRequests and deal with the download ourselves, since we’ll have to face the dreadful “You-Read-While-I-Write” problem anyway.

So, where are we now ?

  1. We cannot leave the hard work of downloading the file to the WebClient
  2. We have to write the routine that saves the buffered data, chunk by chunk, ourselves.
  3. MediaElement uses Streams (or MediaStreamSource, which in turn uses Streams as well)
  4. We need to be thread safe, since the writing and the reading are done in parallel
  5. We need to access the same stream at different positions, one for reading, one for writing… uh-huh…

Okay, while the two first points are not really a  huge technical challenge, we’ll leave it as an exercise for the reader. The real thing here, is that if we are writing to a stream, it will always be at the current Position. Same for reading from a stream : it will always be based to the current Position. Now, one might have the brilliant idea to say something like “Piece of cake : let’s just change the value of the position just before writing, do our thing, and revert the position back to where it was : no harm no foul”… Only it doesn’t work that way. remember the 4th point ? we need to be thread safe, so after writing to the stream, by the time we want to move the position back to where it was so the stream can be read properly, an other read request might have happened in the meantime, changing the position, and there’s a big chance the application will crash just because you just read something you were not supposed to read (remember ? you just cut the grass from under the reader’s feet !)

Now, if someone is a bit experienced with threading and mutual exclusions, he’ll probably the Semaphore / Mutex into the discussion and argue that we just have to restrict to read and write access so only one can do it at the same time. Well, he would be right, only this is not really feasible as-is. Remember point 3 ? We want to use a MediaElement. In other words, we don’t control the way the stream is read. Adding a semaphore or a mutex around the read statement is simply out of the question since we don’t control the way our stream is read… BUT… we do control our stream, right ? it is provided as an argument to the MediaStreamSource.

From there, it is pretty straightforward. We can subclass a Stream class. (in my case, I subclassed MemoryStream because that was the class I was using firsthand) and override the read and write methods. Once we can add our logic within the stream, we can introduce any thread-synchronization mechanism we like. Since all the operations are located in the same class, I went for a lock statement in each overridden method. Note that the locks must all be based on the same object, so I instantiated an Object whose sole purpose is to act like a token for the lock statements of all the protected methods.

 

        private readonly object _lockObject = new object();

        public override int Read(byte[] buffer, int offset, int count)
        {
            lock (_lockObject)
            {
                return base.Read(buffer, offset, count);
            }
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            lock (_lockObject)
            {
                var oldPosition = base.Position;
                base.Position = base.Length;
                base.Write(buffer, offset, count);
                base.Position = oldPosition;
            }
        }