Ok, had a quick look and spotted a big problem right away.
You're using SoundFillBuffer as the callback function for your voices, which means it will get executed by an interrupt handler. That means it can't use mutexes (because mutexes only function properly inside threads and the context isn't in a thread) and it can't use floating point (not supported in interrupt handlers) which will be used by the libMAD decoder in the GetPCM call.
What I suggest is creating a high priority thread and message queue (either roll your own or see libogc's message.h - but beware, the function definitions are slightly wrong). The thread waits for messages to arrive, each message can either specify a voice that needs filling or an exit signal. Then make a new voice callback that simply pushes the appropriate messages to signal the thread.
Tip: Unlike mutexes, you can release semaphores inside a callback (because they're not "owned" by a thread). So a cheap message queue could be implemented by:
- a static u32 array (to hold the messages)
- a semaphore that gets released/incremented when a new message is "pushed" (by the callback) and waited/decremented by the thread when it "pops" a message.