Malvineous / libgamemusic

Library providing a standard mechanism for playing and converting music used in DOS games.
http://www.shikadi.net/camoto/
GNU General Public License v3.0
24 stars 4 forks source link

incorrect .wlf playback speed? #10

Closed wothke closed 1 year ago

wothke commented 1 year ago

when uploading some .wlf file on your https://camoto.shikadi.net/libgamemusic/ page the console message reports:

"File is definitely: id Software Music Format (type-0, 560Hz) [imf-idsoftware-type0]"

I presume it is also using the incorrect 560 Hz rate for playback - when it should be using 700 Hz (see http://www.vgmpf.com/Wiki/index.php/IMF ).

Malvineous commented 1 year ago

On the page you linked to, look at the section "specifying the file type". It explains this problem. It's because there's no way to tell whether a file should be 560 or 700 Hz, so you have to specify it manually.

wothke commented 1 year ago

As far as I know the " .wlf" extension MEANS that 700 Hz should always be used, it's the whole point why ".wlf" was even introduced and there is no reason to ever play .wlf with 560 Hz! (BTW that's also how AdPlug does it).

Malvineous commented 1 year ago

Yes I know, I was the one who came up with the idea of using .wlf to set the tempo and I pushed to get it implemented in AdPlug many years ago, before I took over maintenance of AdPlug as well. But the architecture of libgamemusic doesn't allow filenames to be passed to the file format identification function, so there's no way for it to look at a block of unnamed IMF data and tell whether it came from an .imf or .wlf as it doesn't know what the filename is. That's why there is example code on that web page to show you how to set the tempo yourself, which you could easily do by checking the filename you're passing in, and if it ends in .wlf set it to 700 Hz.

libgamemusic is a much more regimented library than AdPlug, and it had to be in order to support writing songs as well as reading them. So I'm not disagreeing with you at all, it's just a limitation of the way it was designed - working on unnamed blocks of data instead of named files. It means the library user (you) have to be responsible for any logic that involves the filename.

To illustrate the point, you will find that you can rename an .imf or .wlf to anything you want, and it will happily load your .abc file and play it, because it never looks at the filename. The idea behind this is to make it easier to identify unknown music formats when you're reverse engineering games.

wothke commented 1 year ago

At the time it was obviously quite braindead by whoever came up with idea to save the "id Music Format" rips without adding a header that could have stored all the needed extra information. And given the minuscule grand total of 201 files in that format (according to modland) I find it quite surprising that this lacking rip format has not been replaced with some "extended" file format (that fixes this flaw) a long time ago..

I've had my own web player based on AdPlug for almost 10 years now (see http://www.wothke.ch/AdLibido/ ) so I would probably not switch to any other player to play .wlf files on the web. But I wanted to give you my feedback regarding what I as a user would consider a flaw (i.e. having to redundantly configure format information that is already there as the file's extension).

I am all in favor of file content based format detections since I've had my share of grief with the garbage Eagleplayer based detection logic in my web version of UADE (see http://www.wothke.ch/webuade+/ ). However this only works when the formats actually do contain all the necessary information - which obviously isn't the case in the IMF scenario. When a filename coveys the extra information that is missing in the file's content then a player should still have the capability to use it.

My usecase (see http://www.wothke.ch/playmod/ ) is maybe somewhat different from what your example page has in mind: I am not hardcoding/preloading what is played. I want to be able to handle music files correctly and automatically - that I have barely any information about (in this case the 400k files in the modland collection) - without having to rely on any manual add-on crutches. The player can use whatever it finds in the files/filenames but should then be able to correctly play the music.

In any case, good luck with your player (I see it handles a few formats that none of "my" existing web ports handle: 670, bsa, mus/tim, klm). I'll be back in case I ever need those :-)

Malvineous commented 1 year ago

There are other container formats that store this extra information (like the .vgm format), and you can also convert the .imf into something else like .dro, and then both ways will result in the file always playing at the correct speed. But then it's not really the original rip any more, it's a conversion.

I suppose when Andy Durdin first ripped the files from the games he could've added some sort of flag for the speed, but back then nobody knew the format would appear unchanged in other games, and again, they'd be inventing a new file format that isn't IMF. You can take a .wlf and import it directly into a game that uses .imf and it will play it (albeit at the wrong speed) so any changes to this would sort of defeat the point of working with the original unmodified game files.

Your PlayMOD is interesting. I notice that if you play Modland/Apogee/Bobby Prince/Duke Nukem 2/ files then it doesn't handle those properly either, which are 280 Hz. There is no standard filename scheme for detecting the correct playback speed there, so even if you handled .wlf, you'd still have problems with Duke Nukem 2.

You probably know that AdPlug contains a library with CRC codes and playback speeds for many of the known files, so using that is another way that you can get the correct playback speed.

But unfortunately IMF is just not designed as a music distribution format. It is a raw, internal format used by the games that is designed to take minimal resources during playback.

As for the 670 etc file formats, there are links to those file formats on the VGMPF page for Camoto (under "Song formats that can be read") which in turn shows a list of games using those formats, and offer them for download, if you want sample files in those formats.

wothke commented 1 year ago

don't mention modland ;-) unfortunately they are not (yet) using the .wlf naming convention for those files where it would actually help the players.. (I still hope that they'll eventually rename those - eventhough that will not solve the issue with the DukeNukem files and maybe they'll add another useful naming convention for those). But the separate CRC library is really a badly designed crutch: each time somebody "discovers" an additional song (or patches something up using an existing song) the player has to be recompiled/redeployed to map the new CRCs - or you need an additional server to remotely supply the information (adding complexity for no good reason).

Malvineous commented 1 year ago

Oh I looked in Modland because you mentioned it in your example :)

Yes I was never keen on the CRC database, which is why I advocated for the .wlf filename extension instead, even though it only solved two timing problems. I discovered years ago that if you double the delay bytes in the Duke 2 IMFs you can turn a 280 Hz file into a 560 Hz file, so I just did that for all my Duke 2 IMFs so they are now standard 560 Hz files and work with the .imf extension. I just added these to the VGMPF Duke 2 game rip if you are interested in them.

That's why for libgamemusic, I left it up to the user to specify the timing as there just isn't enough information otherwise. libgamemusic isn't really designed to work universally like you would expect for a player, it was designed foremost for game modding where you already know all about the game you're editing, so I made a conscious decision that the person calling the library would know a lot about the file format. I only added the autodetection code for convenience and to help with reverse engineering new games. So this design works well for the intended use case, but it does have some limitations when working with players as you've discovered.

I did however write an XMMS2 plugin for libgamemusic, and I didn't run into any problems there with song tempo. I just added an extra check to set it to 700 Hz if it was .wlf, otherwise default to 560 Hz, and all the files play at the correct speed through XMMS2 so it's definitely doable. In this case XMMS2 doesn't supply songs as filenames but rather URLs, so not having the library require the filename worked in my favour here anyway. I could examine the URL to extract the file extension and not be tied to whatever requirement the library may have imposed for the filename.

wothke commented 1 year ago

thanks for the link.. I'll try to convince the modland chaps to host the 560Hz versions by default.. (what is the difference between the nicely named files in the root folder and the ones in the "Original Rip" folder? wouldn't it make sense to also use the 560Hz approach for those user friendly versions in the root folder? )

Malvineous commented 1 year ago

No idea what the difference is between those files, I didn't create that part of the archive. I can only guess that it serves as a record of what the original filename was, as the data appears to be unchanged.

The site focuses on original unmodified game rips so they prefer the main files to be relatively untouched, with any adjustments or conversions in separate folders.