VGM file format - Kyuchumimo/Micro-Joy-Home-Video-Computer GitHub Wiki

⚠️ Music libraries only read uncompressed VGM files. That is, it does not support .vgz files or .gz files.
Change the .vgz file extension to .gz, then use a file decompressor of your choice and extract the .vgm file.

VGM is the file format that Micro Joy Home Video Computer uses to play music. This format contains instructions for talking to audio chips. It is an almost universal format.

These files are only a fraction of the size of, for example, an .mp3 audio file.

Beware that the VGM file compatible does not comply with a standard version, as concessions have been made to reduce the size of these as much as possible, in particular with the commands that call the Konami SCC sound chip.

The command for Konami SCC has the following format:
0xD2 pp aa dd : SCC1 port pp, write value dd to register aa

This command occupies 4 bytes in total, but we can make it occupy only 3 bytes by removing the port parameter.

The port parameter can have 6 possible values, which correspond to a function of the Konami SCC sound chip.

Value Function
0x00 waveform
0x01 frequency
0x02 volume
0x03 mixer
0x04 waveform (0x00 used to do SCC access, 0x04 SCC+)
0x05 test register

Knowing this, we can map the ports to the corresponding memory address.

We can also remove the GD3 tag. This contains information about the name, author, album, system and the software used to export the file. This can be left out, it doesn't affect anything if we remove it.

Another important change that I see necessary is to replace the mixer commands by volume commands, since the only thing they do is to complicate everything more.

A tool that optimizes VGM files to make them compatible with the system can be found in this same repository.
See: tools/VGM-OPTI.py

Header

Depending on the version of VGM and the program where you export the file, the size of the header may be different.
Furnace will always export a 256 byte header regardless of the version of the VGM specification.
This is what the header of the latest version of VGM looks like (v1.72)

      00  01  02  03   04  05  06  07   08  09  0A  0B  0C  0D  0E  0F
0x00 ["Vgm " ident   ][EoF offset     ][Version        ][SN76489 clock  ]
0x10 [YM2413 clock   ][GD3 offset     ][Total # samples][Loop offset    ]
0x20 [Loop # samples ][Rate           ][SN FB ][SNW][SF][YM2612 clock   ]
0x30 [YM2151 clock   ][VGM data offset][Sega PCM clock ][SPCM Interface ]
0x40 [RF5C68 clock   ][YM2203 clock   ][YM2608 clock   ][YM2610/B clock ]
0x50 [YM3812 clock   ][YM3526 clock   ][Y8950 clock    ][YMF262 clock   ]
0x60 [YMF278B clock  ][YMF271 clock   ][YMZ280B clock  ][RF5C164 clock  ]
0x70 [PWM clock      ][AY8910 clock   ][AYT][AY Flags  ][VM] *** [LB][LM]
0x80 [GB DMG clock   ][NES APU clock  ][MultiPCM clock ][uPD7759 clock  ]
0x90 [OKIM6258 clock ][OF][KF][CF] *** [OKIM6295 clock ][K051649 clock  ]
0xA0 [K054539 clock  ][HuC6280 clock  ][C140 clock     ][K053260 clock  ]
0xB0 [Pokey clock    ][QSound clock   ][SCSP clock     ][Extra Hdr ofs  ]
0xC0 [WSwan clock    ][VSU clock      ][SAA1099 clock  ][ES5503 clock   ]
0xD0 [ES5506 clock   ][EC][EC][CD] *** [X1-010 clock   ][C352 clock     ]
0xE0 [GA20 clock     ][Mikey clock    ] *** *** *** ***  *** *** *** ***
0xF0  *** *** *** ***  *** *** *** ***  *** *** *** ***  *** *** *** ***
  • Unused space (marked with *) is reserved for future expansion, and must be zero.
  • All integer values are unsigned and written in "Intel" byte order (Little Endian), so for example "0x12345678" is written as 0x78 0x56 0x34 0x12.
  • All pointer offsets are written as relative to the current position in the file, so for example the GD3 offset at 0x14 in the header is the file position of the GD3 tag minus 0x14.
  • All header sizes are valid for all versions from 1.50 on, as long as header has at least 64 bytes. If the VGM data starts at an offset that is lower than 0x100, all overlapping header bytes have to be handled as they were zero.
  • VGMs run with a rate of 44100 samples per second. All sample values use this unit.

The following is a list of the fields in which music libraries are interested in:

  • 0x00: "Vgm " ident
    This field is an identifier. This field indicates that the file is indeed a VGM type file. Music libraries check this field. If the check fails, the library will throw an error.
  • 0x08: Version
    This field indicates the version of the VGM file specification. Music libraries check if the version is equal to v1.71. If the check fails, the library will throw an error.
  • 0x1C: Loop offset
    The value of this field is relative to the field address.
    If your music contains a loop, this field will contain data, otherwise 0 if no loop.
    This field is used to indicate where the music loop is located.
  • 0x74: AY8910 clock
    This field indicates the clock frequency in hertz of the AY-3-8910 audio chip. If the value is different from 1789772, the check will fail and the library will throw an error.
  • 0x9C: K051649 clock
    This field indicates the clock frequency in hertz of the K051649 (Konami SCC) audio chip. If bit 31 is set it is a K052539 (Konami SCC+). If the value is different from 1789772 or 2149273420 or 0 (if there is no Konami SCC/SCC+ chip used), the check will fail and the library will throw an error.