| 10 Comments | No TrackBacks

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

Here is my proof-of-concept ogg vorbis support in Moonlight: sources, or html test page (you'll need either the latest moonlight from trunk, or Silverlight 3 beta)

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.

No TrackBacks

TrackBack URL:


Hi, is there a project page for csvorbis somewhere? I don't know if I would be able to contribute, but I'd like to at least have a look at the todo list.

Hi. There is no project pages yet. We welcome such contributions too ;) or I'll create some wiki page hack later.

And only two years later I did find this great article, too :D

This is really great stuff! Are there plans for a whole WebM decoder? That way SL/Moonlight could be used as a fallback for

So, this is so incredibly awesome!! Have you guys expanded on this at all? I'm writing an app that streams mp3's from my home pc to my work pc. I've converted all my files to ogg vorbis and I've got this working but there is no seek feature : (. Has anyone worked on this at all?

Hi, thanks for your interest. Sadly I haven't been working on it and I have no plan to do either in my job or part of my hobby hacking (I'm only a porter to moonlight anyways). I'd welcome patches and/or forks.

So, I got the seek feature to work.

In the method OpenMediaAsync() make sure the duration and seek feature are set.

mediaSourceAttributes[MediaSourceAttributesKeys.Duration] = this.trackDuration.Ticks.ToString(CultureInfo.InvariantCulture);
mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] = true.ToString();

Change Line:

timePosition += buf.Count * 10000000 / (44100 * 2 * 2);


timePosition += (long) buf.Count * 10000000L / (44100L * 2L * 2L);

Applied your fix. Thanks!


You say you applied the fix, but I see no links to where I can find the svn source for moonvorbis and the tar file does not contain the changes.

Any help would be appreciated,

The sources are now in github (like other mono modules) as part of 'mooncodecs' module:

Leave a comment