Ok, exchanging some sleep for some comments…
Firstly, there is a bunch of things I like, such as the new track command with the chip index in it, I won’t touch on these too much. Also, please take the below as constructive criticism, because that is how it is intended
.
1. Please put GD3 data at the start, currently I have to load and decompress the entire file before I can display the song data, rather than just having a quick load when the user selects a file or views the directory index or playlist. Also I would like meta-information like total length in front.
2. Please put the ROM/PCM block before the track data. I don’t want to decompress the entire VGM first before starting playback. Background (on the fly) decompression is high on my wishlist for VGMPlay-MSX, this will drastically reduce load times and memory requirement.
(So this order: metadata, chips, rom data, tracks.)
3. Multiple tracks, are they supposed to play back one by one or simultaneously? In the former case, why not have different VGMs then. In the latter case, this will be difficult to combine with background loading but that could be OK if it’s not used often, but I don’t understand the exact purpose of this? If there is any way it could be interleaved, it would have my preference.
4. Specifying the frequency as numerator / denumerator is nice in theory, however I think it unnecessarily complicates things. By their nature all clock chips have deviations (even over time), and thus none will hit the exact number. The only practical application I can imagine is to encode low frequencies like 59.94 Hz.
5. As mentioned before please encode SCC commands as “aa dd”.
6. Why are wavetable chip command addresses not encoded in intel byte order (ll mm)?
7. For me the point for a type / subtype would be that if a new subtype is added, there is a likelihood that it will be recognised by older players which have not added support for it and will still play back at least to some degree.
7a. In that vein, it is strange to me that within a type there are different command lengths.
7b. Also the OPLL does not belong in the OPL group since it is not register compatible with the others.
8. I feel for parsing simplicity, rather than FF it would be better to use $7F for special commands, then the 16th chip can be used with data length 8. Not a big fan of the MIDI style variable length, a length byte or encoded length byte would be easier to process, and not restrict the following values to 7 bits and the (slow on Z80) bit-shifting encoding schemes for >127 values that will undoubtedly follow.
9. Additionally, maybe leave a few numbers free for future extension? $70-7A? Could define some fixed lengths for some / all of them for downwards-compatibility.
9a. Instead of 7C-7F and the “special command”, maybe introduce a special “VGM control chip” and reuse the chip command? Seems like it would add a lot of flexibility. 00-7F could be all waits and 80-FF all commands.
9b. Channel remaps could be specified as channel swaps to fit within the 8 data bytes and reduce the amount of state.
9c. Another idea, the wait commands could use an UTF-8 like encoding where the two most significant bits indicate the length (0-1 byte, 1-2 bytes, 2-3 bytes, 3-4 bytes, big endian order.)
10. Currently my timing code is 16-bit, changing to 32-bit and a much higher resolution would be a bit more annoying to process, not a huge fan but I guess I’ll manage.
11. Please put the command data byte count in bits 0-2 for easy parsing by masking.
12. Channel remap will be
very annoying to implement, and not all chips even define a channel that clearly, e.g. think of the AY3 tone channels shared with the single the noise. Also not all channels are equal, e.g. consider the YM2612 6th channel with DAC, or the YM2151’s 8th channel with drums. I think it would be way better if this could somehow be handled on the VGM encoder’s side (no concrete suggestions right now, maybe something with chips / tracks?). Or at least fail relatively gracefully (e.g. as much as it does now) if it is not implemented.
13. For future extensibility (upwards compatibility), I think it might be good to use a chunks-like architecture of sorts. Currently I think if a chip attribute is ever added, the file can’t be parsed by older players. E.g. in the chips table, prefixing each chip by a length byte would be a good start.
14. Combine the chip type and subtype into one 16-bit value.
15. A common structure for all chip types would be easier to parse than the current ID-value based approach. At least the current attributes seem common to all.
16. Stream commands are just another generic DMA chip as far as I’m concerned. Could be the same as the earlier mentioned VGM control chip.
17. It would be good if there was support for multiple data blocks, because some I would upload to a chip’s sample memory and could discard after, while others I would want to keep in memory (e.g. CPU-controlled DAC PCM data), but as it is proposed I think I can’t know this in advance, whereas I can with VGM 1.0.
18. Alternatively / additionally it would be really handy for me if there was some index of start / end / loop positions of blocks are used by stream commands and PCM chips which do not have these as preset instrument data in the ROM. Maybe this could replace the multiple data blocks thing. Saves me from having to pre-scan the entire VGM trying to determine these when emulating PCM on OPL4. It could also allow to shorten special command $03 and the stream commands…
19. Finally, although I do see the flaws in the current VGM format, I already do not have that much free memory in VGMPlay-MSX, so it’ll be a bit of a challenge to put the code for two formats in one executable. In more general terms, there’s currently quite a huge library of VGM players and hardware, all of which will not support the new format, and may not for the coming years or at all. The benefit needs to be great enough.