|Home | Downloads | Screenshots | Forums | Source code | RSS|
Jul 23rd 2020, by Arisotura
Sorry for the silence lately -- these times are getting pretty busy. melonDS wise, we're trying to perfect the JIT and the few other things we want for the 0.9 release. Real life wise, on my side, I'm starting the procedure to get my gender marker updated, which is going to be the last big thing for my transition.
Anyway, just yesterday, asie told me that maxmod's interpolated mode was broken in melonDS, which piqued my curiosity.
What's maxmod, you ask? It's a real fancy audio library for the GBA and DS. I don't know much about the GBA side of it, but on the DS, it supports three modes: hardware mode, interpolated mode, and extended mode. Hardware mode is fairly straightforward. Interpolated mode resamples audio on the fly, applying interpolation to make up for the lack of hardware interpolation. Extended mode does its own mixing, adding support for more channels than the hardware can offer.
In our case, interpolated mode was broken, outputting pretty much short high-pitched beeps and nothing else. I was curious to see if maxmod used any of the fancy audio capture/output modes that melonDS doesn't support (because no commercial game uses them, and my policy is to avoid implementing things until I have test cases). melonDS is set to report if any such features are being used, but in this case, it didn't report anything out of the ordinary. So this meant I'd have to dig further.
Quick regression testing showed that interpolated mode worked okay-ish on melonDS versions prior to 0.6. Well, it didn't sound as it should, but it was atleast reasonably close, instead of just being high-pitched beeps.
So apparently it was completely broken when sound FIFOs were implemented. The FIFO logic was fine, but the addition of that feature worsened the consequences of a bug that had always been there.
I logged what was going on during playback, to try and figure out where it failed. It appeared that the data being fed to the audio channels was fine, but, for whatever reason, the channels themselves failed to actually pull the data from memory. More logging revealed some strange things, like how certain things started at zero when they shouldn't. Notably, the channel timers started at zero, when they're supposed to start at the SOUNDxTMR reload value. But also, the FIFO level started at zero, causing it to immediately go negative and break the FIFO filling logic.
For a while, I scratched my head at all that, until it finally clicked.
In interpolated mode, maxmod will first disable the mixer, then sequentially initialize the channel registers, then enable the mixer, letting all channels start in perfect sync.
Thing is, at this point, for each channel, SOUNDxCNT is initialized with the start bit set, and before the other channel registers are set (because SOUNDxCNT comes first). This messed with the way melonDS initialized its channels, because it expected everything to be ready by the time the SOUNDxCNT start bit is set. But, obviously, here, it wasn't the case, and most things being zero fucked everything up.
So I quickly revised melonDS to only perform channel initialization as soon as the channel can actually run. And, hey, that did the trick -- maxmod's interpolated mode sounds fine now.
That being said, I still want to check for any tests that use the unimplemented capture/output modes.
|24 comments have been posted.|