Optimizing VGMs

From vgmrips

Optimization is different from compression; an unoptimized VGM can still be compressed into a VGZ. You must optimize before you submit your pack, but submitting uncompressed VGMs is perfectly okay. The VGMs will be properly GZipped during the finishing process, after pack acceptance and before pack posting.

The question remains, though: How do you optimize? Each different system requires its own method. And sometimes, there aren't any optimizations (yet or at all), such as for the Game Boy DMG.

First, make sure all tracks have been trimmed by this point. If, as you proceed, you want more details on a tool such as options not shown, the links will take you to the according wiki page.

Everything you could possibly need to optimize, you already have; after all, vgm_trim comes with the other VGM Tools. But you might also find Useful Batch Files a helpful resource.

As you'll see, each tool can take a second filename after the first. If the tool modifies a file in-place, you can thus make it make a new file instead. If the tool always creates a new file, you can thus control what filename is created.

Multi-System tools

...can be used on all or multiple systems. I'll introduce them here, and refer to them as needed.

Unless the instructions for your target system or the tool itself say otherwise, these tools can be used at any time safely.

vgm_cmp

When this tool runs, it always makes a new VGM and leaves the original/source file untouched. If the source was a VGZ, the new file will be decompressed, regardless of the file extension.

vgm_cmp "your.vgm"

In this form, vgm_cmp creates a new VGM with _optimized added to the end of the source filename. So, this call will make "your_optimized.vgm" in the same folder as your.vgm.

As stated, to make the new VGM have the name you want, just add it to the end like so:

vgm_cmp "oh, it's a.vgz" "let's rename it since it becomes a.vgm"

vgm_sro

For sound chips with sample ROM (e.g. SegaPCM, sometimes RF5C68/164, YM2608/10, Namco and Konami PCM chips, etc.).

It's quickest to just look at vgm_sro's page for fuller details. It has a list of supported chips.

Currently, this tool will incorrectly strip K053260 PCM roms.

vgm_ptch

Lets you strip unused chips. This cuts down the files a bit more.

Order of usage if multiple apply

  1. optvgm (YM2612 only)
  2. vgm_sro
  3. optvgmrf (for streamed samples on the RF5C68 and RF5C164 (Sega MegaCD) only. use it when vgm_sro complains about streamed data on RF chips)
  4. vgm_cmp

vgm_ptch can be used at any time, though after trimming is suggested.

Sega Master System

These albums are handled by SMS Power, and don't need optimization in any case.

Sega Mega Drive

The relevant tools:

  • optvgm
  • vgm_cnt
  • vgm_ptch

optvgm and vgm_cmp

optvgm "soon to become a vgz, it was once a.vgm"
optvgm "your.vgm" "optimized.vgz"

A few points about optvgm:

  • If you use it without an output filename as above (like drag and dropping), it changes the file in-place.
  • It always makes a VGZ, even if the filename doesn't say that afterward. You can tell by how the size reduces.
  • It may report "No compression achieved." This typically means the PCM (which is different from PSG) was not used in the original file, so optvgm just had nothing to optimize.
    • But if that happens, it still creates a VGZ, in-place or no.

Once you've used optvgm, then you can use vgm_cmp on that same file. optvgm must be used first, or you risk it throwing a "verification failed" error at you.

The name optvgm is a legacy of sorts. This tool only has meaning to Mega Drive/Genesis games. If you only rip other systems, it's useless. Fortunately, because you're in this section, you're likely ripping a MD/G game.


To use these tools together easily, create this opt.bat:

for %%f in (*_trimmed.vgm) do optvgm "%%f" "%%~nf.vgz" & vgm_cmp "%%~nf.vgz" "%%~nf_optimized.vgm" & gzip.exe "%%~nf_optimized.vgm" & ren "%%~nf_optimized.vgm.gz" "%%~nf_optimized.vgz"

If you'd like to know brief details:

  1. For each VGM file with "_trimmed" at the end of the filename,
  2. run optvgm on it (with output file set to "[filename].vgz")
  3. then (&) run vgm_cmp on that (with output file set to "[filename_optimized.vgm")
  4. then run gzip on that (producing "[filename]_optimized.vgm.gz")
  5. and finally, ren(ame) that to "[filename]_optimized.vgz".

gzip's for making a VGZ, as you see, which is compression. Thus, you can ignore for now anything about gzip here if it's too confusing at this time. Your final results here will always end with "_trimmed_optimized", whether VGM or VGZ. And when you're ready to create the playlist, you should refer back to Filling Out the Tags and Text File for how to get rid of that extra easily.

If you're still here, nevertheless you may not already have gzip.exe. In that case, you can

  1. just remove everything after and including & gzip.exe, and send the results. That's the simplest choice, but if you really want to do it yourself, then
  2. get a copy of GZip, or
  3. change the gzip.exe part to use 7z gzipping instead (which should be 7z a -tgzip if 7z is installed/pathed properly), or
  4. do option 1, but then use VGMToolbox's gzip compressor, under "Compression Tools". Beware!: VGMToolbox won't rename the files to use .vgz for you, so you must rename them yourself.

Identifying and Stripping Unused PSG (starring vgm_ptch)

Unlike optvgm and vgm_cmp, vgm_ptch can be used at any time, before and after other optimizations and on VGZs as well.

First, use any of the methods I'll soon describe to check if none of the songs in the pack use the PSG. If even just one of them does use the PSG, then the chip should be left untouched in all the packs. You can now proceed to Final Touches and Pack Posting.

But if none of the VGMs use the PSG at all, then use vgm_ptch on each track like so:

vgm_ptch -Strip:PSG "insert your.vgm" "and place more in if you need to strip more.vgm"

This further reduces the size, without affecting playback. Stripping the chip can cause some Waits to be split up, but they still take up the same amount of time roughly.

If you want more convenience, you can create this batch file:

@ECHO OFF
echo Make sure you didn't hit this by mistake, as stripping can't be undone.  Have you backed up?
pause
for %%v in (*.vg?) do vgm_ptch -Strip:PSG "%%v"

Or, using Kaijuu with a pattern of *.vg?:

cmd.exe /k echo StripPSG && pause && vgm_ptch -Strip:PSG {files}

Those Pauses are important: last thing you want is to run it on things by accident.

Now, if you're making a pack update and the text file says "SEGA VDP PSG" in the Music Hardware line, remove it. You may then proceed to 3 Final Touches and Pack Posting.

The Specific Commands not Used

Or, The worst way to check for disuse: Ctrl + F in vgm2txt files. You probably don't want to actually do this since there are better and quicker ways, but it's informative to see what SN76496 calls don't actually do anything, and why.

Matt Furniss particularly never used the PSG in his compositions, so we'll use him as an example. Songs by him, at least some of them, issue a single PSG command, uselessly setting the noise type once at the start of the songs and that's it (a possible holdover from SFX playback).

0x00000040: 50 E0       SN76496:	Noise Type: 0 - Periodic, High (6927Hz)

Sometimes the PSG non-usage is more complex, as in this image:

(The first numbers are just line numbers.)

If you don't know what you're looking for, lines like these look important. In fact, they tell you for sure the SN76489/Sega VDP PSG is not being used.

  • The lines without 0x numbers are just initialization. That's like preparing the band to play.
  • 50 means a command to the PSG. The number after it tells what command to the player.
  • All Latch/Data and just Data commands have nothing but zero for inputs. With the volume always set at 0, no sound is played.
  • Ex, as in E0, refers to a Frequency register. The other three for the PSG are 8x, Ax, and code>Cx. If only these four are "used", the PSG is not doing anything for the song.

This is all awesome, but there are often many useless PSG calls. Throughout the VGM. Even if you have a great way to search in many text files and show you all matching lines, this is way too much. And even in the best case, like the Furniss example? You have to open each txt and Ctrl+F for "SN76496" at least five times.

That's why there's other, better ways to check.

VGM Command Counter

Enter vgm_cnt.

Consider Zero Wing's Stage 1 music:

SN76496 #0: 34238 Commands, 8 Notes
YM2612 #0: 1679085 Commands, 2997 Notes

The PSG is used, most likely.

Consider Ondo of Puyopuyo:

SN76496 #0: 59061 Commands, 0 Notes
YM2612 #0: 154335 Commands, 2180 Notes

Most likely not used. All of these commands could be and probably are the useless sort, as mentioned above.

The Power of WAV

By creating a .wav file of only the PSG contents, you can see at a glance if it's unused in a VGM.

For a single VGM, a quick way to do so is:

VGMPlay.exe -c YM2612.Disabled=True -c General.MaxLoops=1 -w your.vgm

You can also change those options in the .ini file of VGMPlay.

You can also put all tracks you want to check into a playlist.m3u file and give it to VGMPlay in place of a vgm, with the changes/settings above made. This is usually more convenient than listing them one by one at once.

This is also possible with in_vgm and players that can create .wavs/.flacs with it. See Finding Trim Points in WAV Files for more details on conversion. The YM2612 muting can be done in the in_vgm options.