It seems that the path through the AudioThread::InputCallBack code is different when being served from a shoutcast stream vs. from the Rio HTTP server.

This is basically correct. The path chosen actually depends on whether or not the music stream contains metadata (which contains the current song title).

There are these weird for loops to read in stuff related to metadata. Could you explain what you are doing there. I just couldn't understand why you can't simply do a single fread(). Though, I am sure you have a reason for this.

The reason for this filthy mess of code is because the Shoutcast metadata is embedded in the stream every n bytes. Because of this you have to keep track of how many bytes you've read so you can know when to expect the metadata to occur. It gets even worse because in the InputCallback, MAD passes in data which it did not yet process which must be accounted for. I'm open to suggestions on how to clean this up

Shouldn't you grab the ClassMutex before calling Display.Update for the metadata? You seem to do that in the OutputCallback code. Or is that lock used to protect something else?

The way I did the mutexes is that each Thread class protects itself with it's own mutex. So, if you look in Display.Update() you'll find that the Display locks itself inside that function. Looking at the lock in the OutputCallback that you're talking about, I'm not sure if it's needed. I'll have to look more closely at that.