Skip to content

Multithreading vgm rendering

Technical discussion about the VGM format, and all the software you need to handle VGM files.

Moderator: Staff

Multithreading vgm rendering

Post by vampirefrog »

Hello, besides assigning each chip instance to its own thread, is there a way to multithread vgm rendering? I'm thinking we split the song into N chunks, divided by samples, then render each chunk in parallel, but in order to do that, there needs to be preprocessing of the command stream for that chip, to determine its state at the beginning of each chunk. The preprocessing might not be multi-threadable, but we can probably have some decently fast(?) mode for the chip, where it just takes commands and updates its internal state, and then we can somehow get the state from it at a given sample, so we can instantiate it once for each thread, and for each instance, make it load the internal state at sample N. This preprocessing would also be useful for really fast seeking, which would be useful for an interactive VGM file editor. But it would require that each chip core have the ability to take commands and update its internal state without rendering, and be able to save and load state. I know some of the chips simply have registers that can be updated, but there might also be a phase issue, when putting the chunks back together, so there probably needs to be some phase information, ie, some processing of wait samples. hmmmm
  • ctr Offline
  • Posts: 492
  • Joined: 2013-07-17, 23:32:39

Post by ctr »

Currently, vgmplay doesn't support multithreading at all, and libvgm could do it (the emulation and player components only) but each thread will require its own instance. I think that splitting the file in chunks could cause accuracy issues depending on how well the chip handles seeking

Many chips don't really handle seeking that well (quick example would be the Nuked cores) and so the end result could be pretty bad. It's possible that register writes will be dropped, and I have noticed this in several chips, including the Nuked ones as well as the current HLE QSound.

As you mentioned, seeking will indeed affect the timing of key on/offs so the phase will be affected. Also keep in mind that the phase shift will affect not only the oscillator (sample position / waveform phase) but also envelopes. Songs with very long PCM samples (like the late 90s arcade games) will probably sound completely broken since the sample position is usually reset by seeking.

I believe that using threading to render multiple files is easiest and less likely to cause any problems.

For the interactive VGM file editor, I think it is possible to render the song once and construct a tree of "savestates" (containing the entire VGM player state as necessary) at a certain interval in the file. This will allow for faster seeking to random positions and perhaps even reduce the likelihood for seeking issues as I mentioned above. Of course, after each edit, all savestates at and after the edit must be re-generated. This could probably be done in a background thread though.

Post by vampirefrog »

Actually the initial seeking for splitting into chunks can be done on separate threads, even though they'd be doing roughly the same thing until they hit their desired sample point. So basically, in every thread, the process is: seek (send register writes but do not render samples) to desired sample (sample is calculated from the number of samples in the VGM header, divided by the number of threads), render until desired end sample (one sample less than the next chunk). Keep wave data in memory or in temporary files, and when all threads finish, rebuild the data either from memory chunks of temporary files. I would use the memory version for when outputting to stdout. There's a bit of waste, but it should still be faster than single thread.
Post Reply