Oops, I did it again
Happy new year everyone! (this is my first post this year.) I should post some updates since last post at some stage, but briefly,
- I was mostly on summer(!) vacations last December.
- Since the new year week I have switched to join Moonlight development focusing on WCF part (I haven't been involved as my work for three years, and I'm sort of back there).
- I had a Mono session at Microsoft Tech Days Japan 2009
- Due to painful machine breakage, switched to Sony Vaio type P (of course with suse. It's so small; jizz in my pants).
Anyways I'm writing a new post to introduce my toy hack this week.
MoonVorbis: Ogg Vorbis decoder for Silverlight3
Last week Microsoft released their first beta of Silverlight 3, which has a lot of fascinating new features. The most interesting thing to me was support for custom media stream, especially for raw PCM.
It can be achieved by implementing MediaStreamSource API. Actually this class has been there in SL2, but it didn't allow custom media decoder. With Silveright 3 we will be able to write custom audio applications.
However, one major limitation about this new feature is, due to the coreclr security model does not allow us to P/Invoke unmanaged code, which lots of C#-based decoders depend on. To support custom media codec, we will have to write pure managed ones.
However, we indeed had such one in mono repository - managed ogg vorbis decoder (csvorbis), which was written by Marc Crichton in 2002. On Sunday midnight it suddenly came to my mind that we might be able to reuse it. So I got on the time machine and went back 7 years. And yes, it was actually reusable within very limited changes to get compiled with smcs (our Moonlight compiler).
The next step was to write the actual MediaStreamSource for Ogg Vorbis. There was a good example from Microsft: ManagedMediaHelpers, by Larry Olson. It gave me almost everything that I have to understand, and I even borrowed some code (you may notice that the sample page is almost equivalent to the sample in this project. No worries; it is licensed under MS-PL), but the sample didn't work fine when it is recompiled with SL3 sdk (it was due to the dummy value for MediaStreamSample.Timestamp property).
Oh, and I shouldn't forget to introduce another great example by Pete Brown.
The only thing I had to implement was GetSampleAsync(), and I could still reuse csvorbis code - I just changed stream output to yield-return the raw PCM block to return in each call to this method.
Once I got it working under SL3beta, I moved it to moonlight (actually I originally wrote it in MonoDevelop for moonlight, then moved to Windows to get "working" code, and then moved back to our home) but we lacked some code for custom codec support. So I asked Rolf (who rules our media support) about it and I left for lunch. When I came back, it was already working ;-)
It is all how MoonVorbis is made in Moonlight land. I am glad to find that we can has the newest SL3 feature too. You can run it either on Moonlight (you need very latest moon from trunk) or Silverlight 3 beta.
Having said that, this MoonVorbis right now is no more than a proof-of-concept toy. It has to be polished (note that csvorbis itself is written 7 years ago). Some oggs didn't play fine (I haven't improved any existing code, and csvorbis sample originally had limitation). I took a sample ogg from Wikipedia.
I will check in the code somewhere in our svn, so if anyone is interested in improving this custom codec, please join our development. We have some interesting library to boost managed code.