SGDK icon indicating copy to clipboard operation
SGDK copied to clipboard

Garbled PCM track when using XGM ROM builder

Open meyertime opened this issue 2 years ago • 4 comments

Thanks for putting this together. I'm trying to use the included XGM ROM builder to build a ROM to use on a real Genesis model 1 to do some recording. I finally got it working and tried out the ROM in an emulator, but the drum track played on the PCM channel of the YM2612 is garbled. That's the best way I can describe it. Here's a recording of Green Hill Zone from Sonic 1 to illustrate:

ghz-garbled-drums.zip

I've seen reference to this problem on the interwebs, but it's from several years ago, so I'm hoping this is a known issue with a known fix and you can just let me know what to do. (Like maybe the player ROM is out of date or something.)

Sorry if I'm posting to the wrong place. I really can't find any other source of the XGM player ROM or ROM builder. I know there's a magic rom.bin file that contains the player, but I don't know where the source code for that actually resides. Of course, this could also be an issue with xgmtool and how it converts the .vgm to the XGM format. But the .vgm source file I used plays correctly using libvgm and DeadFish's VGM player ROM (other than being about 98% speed on a the real Genesis, which is why I'm trying out this one instead).

In other news, I'm on Linux. I could use some instructions for building xgmtool, as xgmRomBuilder.txt says you need to build it if you're on Linux, but I couldn't find instructions on how. Instead, I pulled it out of the Docker image referenced in this project's README. I also had to make a few fixes to the XGM ROM builder project, and that's probably also due to the fact that the release history mentions Java 6, but I didn't want to install that, so I used Java 8 to run it. The fixes are around reading the rom.bin resource and executing the xgmtool process, but should not have any effect on the actual XGM conversion or playback.

meyertime avatar Apr 04 '22 21:04 meyertime

Hi @meyertime

There are several thing to know about the XGM driver. First, the PCM output rate is fixed to 14 Khz so it's generally better to use 14 Khz PCM too to avoid distortion due to the (poor) resampling algorithm used by rescomp tool. The other thing to know is that XGM ROM Builder is outdated and do not use the last version of the XGM driver nor the last version of XGM Player and rescomp tool, so definitely you may have better results just by directly using the XGM Player sample sources so you can customize it to your needs (at least modify the track list).

Edit: Listening your FLAC, i wouldn't say the PCM are garbled but that they are not properly synched, as if they were a bit of latency between the music play and PCM play. This is generally an issue with the VGM --> XGM conversion process. That happens when original VGM file isn't really clean. Did you tried different VGM sources to see if the problem happen everytime ? Also did you used the XGM ROM Builder tool included with SGDK ? It's possible you're using an even older one.

Stephane-D avatar Apr 12 '22 07:04 Stephane-D

Thanks, @Stephane-D. I built the latest XGM Player in the sample folder. It works, except I noticed a similar issue with the included Ice Cap Zone music. I built it with Green Hill Zone, and it has the same issue, unfortunately. However, I stripped all the channels out of the .vgm except for the PCM to get a better listen at what's going on. Here's a recording of just the strange drum track by itself, along with a recording through libvgm of the way it's supposed to sound:

ghz-garbled-drums2.zip

Here are my observations:

  • The kick sound is played at a higher rate than it should be.
  • The snare sound is played at the correct rate when it is played at the correct time.
  • There are additional snare hits between when the kick and snare are supposed to be. These snare hits are played at a lower rate than they should be.
  • Sometimes the snare doesn't hit when it's supposed to, and instead, the additional snare hit that happened right after the kick continues playing. Other times, the snare does hit when it's supposed to, interrupting the previous note.

So, a theory:

  • The kick sound may have been sampled at a lower rate in the original game in order to save space in the ROM. That would make sense, since kicks don't have as much treble anyway.
  • When played at the correct rate, the kick sample takes up all the time until the snare hits. But since it's played at too high a rate, playback continues into the next sample in memory, which happens to be the snare sample, thus why there's an extra snare hit that shouldn't be there.
  • This still doesn't explain the difference in pitch between the correct snare hit and the additional incorrect ones...

And some questions:

  • You said PCM is fixed at 14kHz. Does that mean that the samples are resampled to 14kHz ahead of time? (Like during the VGM -> XGM conversion?) Or are they resampled on-the-fly?
  • I want to be as authentic as possible to the way the music sounded in the original game. The reason I'm using a ROM to play VGM files is so that I can isolate individual channels and still play them through the real hardware. So if the samples are resampled to 14kHz, would that affect the way they sound when played through the YM2612 chip? Or is it something like nearest neighbor, and the extra writes to the DAC won't matter since the value stays the same for the extra samples and the DAC will produce the same output?

meyertime avatar Apr 12 '22 20:04 meyertime

Afaik the Ice Cap Zone music is an example i'm using as it's quite difficult to recover PCM properly. VGM has different formats and older versions didn't had efficient / correct way of encoding PCM so the XGMTool converter has to recover it from simple DAC register write. The problem is that sound drivers weren't really good for PCM playback so it has many interruptions because of BUS contention or tasks delay so it's very difficult to properly reconstruct samples from that. What you can try is to play with the extended flag options DI/DR in the XGM ROM Builder tool : image

They affect the way PCM data are recovered but honestly it's almost impossible to recover them perfectly from so broken VGM dumps. XGM driver is meant to play 14 Khz samples defined from a directory (sample are resampled during conversion of course) so it can't play them the same play as the (huge) VGM dumps . The change in sample rate shouldn't affect too much the output as soon we are at higher sampling rate, at lower rate of course that would make a difference.

Stephane-D avatar Apr 13 '22 10:04 Stephane-D

@meyertime Oh i forgot to mention, latest SGDK do disable Z80 on DMA tasks and that will definitely affect PCM playback quality. If you aim for best PCM quality then just set HALT_Z80_ON_DMA and HALT_Z80_ON_IO to 0 in the config.h file and rebuild the library, that should make a difference.

Stephane-D avatar May 09 '22 13:05 Stephane-D

@meyertime Did you tested the last proposed solution ? Should definitely fix your issue.

Stephane-D avatar Aug 22 '22 08:08 Stephane-D