Talk:IMF Format

From ModdingWiki
Jump to navigation Jump to search

As a note, IMFCreator, as far as I have been able to tell, DOES treat the #0 channel correctly, at least in that I have as yet failed to be able to create an IMF file that uses the #0 channel.

It also creates WOLF3D and Duke 2 files (Come on! It's from the Wolf3D site!) IF the speed is specified in the options menu. (It has seperate options for 280 and 560 Hz, with 700 being the default. You can also set the speed to a custom value.) ~Levellass 20/03/2010

Oh ok, well as I haven't used IMFCreator I'm only going by what I've heard of other people's experiences. I'll update the table now but please feel free to just make corrections directly in the future if you notice anything like this. Also do you mean it creates Keen and Duke 2 files? Because I already listed it as creating Wolf3D files... -- Malvineous 03:39, 21 March 2010 (GMT)
I ran some tests on some "complicated" MIDIs and IMFCreator does indeed appear to leave channel #0 free, so I've removed the question mark on that, thanks for prodding me into checking :-) -- Malvineous 04:04, 21 March 2010 (GMT)


Here is the the [music TSR] for Commander Keen Vorticons with source included. I don't know why it lags when playing certain songs like "Make it Tighter." It seems to do this in faster songs where the pitch bend is being used. Lemm 16:41, 17 July 2010 (GMT)


Delay

For the delay, what is meant by the number of cycles? If the delay is 2, does this mean that next two times the interrupt to play the adlib data is called, you don't send any data to the adlib port? (Does that even make sense :p) Lemm 08:10, 5 June 2010 (GMT)

It depends on what your interrupt rate is. For Commander Keen the IMF clock rate is 560Hz, so you will have 560 cycles per second. A delay of two will mean no data is sent for two of these cyles. A delay of 560 would result in one second of silence. -- Malvineous 09:52, 6 June 2010 (GMT)
Another question about delays: If a data chunk has a delay of zero, do you wait until the next cycle to play it, or do you keep sending data until you reach a chunk with a delay? Because that is what the music TSR is doing rigth now and perhaps that could be the reason it lags?
I'm not sure what the games do, but I think a delay of zero means to send the next data byte immediately, don't wait until the next cycle. I think this is correct because (for example) a pitchbend might involve updating two registers to set the new pitch, so any delay between the two register writes will cause the wrong frequency to be played for a short time. Certainly this is how AdPlug and other IMF players are implemented - to keep sending data bytes until a non-zero delay is reached. -- Malvineous 09:30, 25 July 2010 (GMT)
This is how I modify IMF files, and from poking around with them it appears that when something is read from the IMF it is read until a delay is found, that is, all commands seperated by a zero delay are implemented at the same time. This is the basis of chord spacing in IMFCreator I think. --Endian? What are you on about? 06:48, 31 July 2010 (GMT)

Types

I've checked all the IMFs of all the games I have, that is to say every IMF using game except Corridor 7 and Operation Body Count. The type 0s I've seen always skip the first two bytes, and games don't like it when you don't include them. I've been trying to poke around game code to see how it treats the first two bytes, but I've only managed to explore Cosmo and Keen 4-6, for Keen at least as near as I can tell it can't take type 0s at all, simply reading the first two bytes as the length of data to play. (Someone could check this with a Keen engine game like Biomenace or Catacomb 3D)

Also I notice that the Biomenace IMFs have strings in them that seem to give the location of the file, for example xCity.imf has 'c:\bhazard\XCITY.IMF' in its tags. -- Levellass 05:55, 6 July 2010 (GMT)

That's interesting, please post back if you figure out what the two initial zero bytes are for! I always thought that they replaced the length bytes with 00 00 when it was not required, but it seems that chronologically the type-0 format came first, so this wouldn't be the case. It would be interesting to see what happens if you replaced 00 00 with a number that is half the file size - would it be used as the length? (In which case the song should only play to the middle before it loops and starts again.)
It seems that most type-1 files have extra data at the end, Wolf 3D is another (that's one reason why the IMFs floating around from these games have proper filenames, based on those hints.) As yet nobody knows why the data is there or what it is used for, or even what format it is in. But apparently it was important enough that they wrote the length bytes at the front so the data could be kept in the file... -- Malvineous 06:08, 6 July 2010 (GMT)
Ok, first up, I don't have a type-0 playing program, so I can't tell what it would do with the first two bytes of a type-0 file. Do you know of a type-0 playing program?
Second, I've poked Tom Hall about this, apparently there are exactly four tag strings in the 'standard' IMF format ID worked with in this order, a word of unknown use, a 16-byte name string, a 64-byte filename string, and 6 bytes of compiler data. The strings are padded with nuls. (Total 88 bytes) These were put in by the program they used to add IMFs to the sound archive. (Actually copied not from the IMF itself, but taken from some sort of list file and just pasted on to the end of the IMF, some games, especially early ones apparently didn't use this method and so don't have this tag data.)
He doesn't know where you got the composer thing or the $1A signature, I too am curious as to where that information came from. I've checked all the game files I have and I can see no game that uses it, though I was able to confirm Mr Hall's comments. In theory 'your' format could be used harmlessly in files, since games don't read the tag data at all.
Oh, and IMf files of duration 0 (All their timer words are 0) crash games or don't play apparently. Can you confirm this? --Endian? What are you on about? 13:14, 15 July 2010 (GMT)
Cosmo is one game that uses type-0 files and is fairly easy to mod for this sort of test. Interesting response from Tom Hall, I'll have to have another look at it. I think perhaps the fields weren't always padded with NULLs (rather random junk data) which is why both myself and Simon Peter (AdPlug author) couldn't figure it out. The composer tag and $1A signature were purely my own invention as I wanted to tag the files I had with their real names (e.g. for Major Stryker which gives the song titles in-game.) I haven't any files with no durations in them, but I am not surprised that it causes problems. I imagine at each "music tick" in the game code it reads everything up to the next delay, so if there are no delays it could get stuck in an endless loop or reach the end of the file on the first read attempt. Not sure what your endian comment is in reference to, but there's an explanation of why it's important on File format data types#Big endian vs little endian. -- Malvineous 23:08, 15 July 2010 (GMT)
Ok then, who's stupid? I'm stupid. After a lot of confusing and checking and some more talk, I have realized I made a few mistakes. This, as near as I understand it is the difference between the two types:
Type 0 came first. It consists of nothing but song data, thus filesize is always divisible by 4. The first 4 bytes are often (Though not necessarily) $00 $00 $00 $00 (A minor exception is Cosmo 1's MBANJO.IMF) Mr Hall thinks the game just starts reading from byte 0, not skipping anything, but he can't remember, maybe the first word IS skipped.
Type 1 came next, files can be any length because of tags. The first word of the file has a value that divides by 4. Programs that use this type always check the first two bytes THEN go on to play file data. Standard tags added by the compiler add 88 bytes to the file end.
This has put a theoretical kink in one of my programs, since it assumes that type-0\type-1 can always be told apart by the first two bytes, but someone would need to deliberately set up a type-0 to be confusing. *Sigh* --Endian? What are you on about? 05:26, 16 July 2010 (GMT)
As far as I'm aware, checking the first two bytes is enough to tell the format - all the utilities I've written as well as AdPlug use this method and I'm not aware of any files that don't fit. MBANJO.IMF is fine because the first two bytes are still 0x00 0x00. I don't believe the first word is ever skipped, as some of the software synths print errors about register 0x00 being invalid (so AdPlug and others play it.) I have just tested this by setting the first four bytes in MZZTOP.MNI to 0xB0 0xFF 0x00 0x03 which sets the frequency on channel 0 very high when the first note is played, and inserts a ~2 second delay before the song starts. I can hear this as a click (after a short delay) on the Cosmo 1 main menu. This proves that the game does in fact play the first two bytes and treats the following two as a delay. I guess it is just luck that the first two bytes are always writing 0x00 into the non-existent OPL register 0x00! -- Malvineous 13:32, 16 July 2010 (GMT)
I'm not sure, I've had a lot of trouble 'cutting' Cosmo IMFs; if I start playing the data in Winamp from anywhere but the very start of the file I get nothing but silence. I'm wondering if this is something to do with the start of the file. --Endian? What are you on about? 06:34, 19 July 2010 (GMT)
You will need to cut the type-0 file on a four-byte boundary, otherwise it will start playing delay bytes as data and vice versa. To avoid it being detected as a type-1 file you will need to ensure the song starts with 0x00 0x00, e.g. by adding four 0x00 bytes to the start of your output file. Also 'cutting' an IMF will be difficult, because the first hundred or so bytes normally set up the instruments for the song - if they get lost the instruments may well become too quiet to hear. Adlib registers 0xB0 through 0xB8 (inclusive) are where the keyon/off bit is stored, so if you leave all the IMF data up until the first write to one of these registers then you should keep much of the instrument definitions intact. You can then remove as many events as you like, although again only removing events that touch registers 0xB0 through 0xB8 might be best, as removing these events will effectively silence the output up until that point - just remember to set the delay bytes to zero so you don't wait for 20 seconds until the post-cut part of the song starts :-) -- Malvineous 12:11, 27 July 2010 (GMT)
Please give me some credit; I said the problems only occur with COSMOs files, not ones made by IMFCreator. I can switch an IMFs type, alter its speed and paste two songs together. I can cut a segment from a file, but not with the ones ID made. I have narrowed this down to the IMFs in games being very efficiently written, as you said, the start of the file contains vital information that is not repeated in the rest of the file. IMFCreator on the other hand writes as it goes, meaning that I can cut a song where I like with little consequence. (Occasional 'hiss' or 'click' effects occur when a 'note' is cut in half.) You can see this with files created by IMFC, many start 'incorrectly' with a hiss and may 'hang', a strange situation where a song will keep playing, but it silent. (The data after the hang point is fine, as can be seen in winamp-adplug when you move over it.) You can see this in my 0.5 release.
I am currently working on 'Keep first 50 bytes' method, which is ok, but your suggestion may prove to be a better one. I will see about this when I write my 0.6 version of KeenWave. I am also curious about implementing an IMF<->adlib conversion option and would value any information you have on this.
Well you only mentioned Cosmo, for all I knew that was the only IMF file you've ever edited ;-) At any rate, I just wanted to make it clear what was involved, if you're aware of it all already then the issues must have a different cause. I'm not sure what you mean by an IMF to Adlib conversion - IMF files store raw unmodified Adlib data so I'm not sure what could be converted! -- Malvineous 07:21, 31 July 2010 (GMT)
I mean adlib sounds in Keen, you mentioned there is code to convert them to IMF music, I imagine this would involve taking the 16 bytes of data at the start of the sound and making them IMF commands to set up instruments, then converting the pitch data to further IMF commands?
Ah right, I haven't looked at the conversion code in years but yes I imagine it works how you suggest, so in theory it should be possible to convert it back to a sound effect again, subject to any limitations (e.g. maybe only one instrument is allowed.) I might take a quick look now and see what I come up with. -- Malvineous 03:42, 1 August 2010 (GMT)
Ok, I documented the format going off the old code I have, see Adlib sound effect. Since the sound effect files only store notes for a single instrument it would limit what you could bring back in from an IMF file. If you're looking at this with a view to modifying sound effects, I think you would be better off not bothering with the IMF conversion and editing the Adlib effects directly, as they are much simpler to work with than IMF files anyway. With QuickBASIC under DOS you could easily write an editor that would play back the sound effect in real time as you are tweaking the notes and/or instrument settings. -- Malvineous 04:42, 1 August 2010 (GMT)