1m2m: mod->midi file converter for TiMidity++ 2 3 4 5 6BRIEF SYNOPSIS: 7 8This adds the new -OM output mode to TiMidity++, which will read in a mod file 9and output a midi file. All parameters needed for the conversion are 10contained in a .m2m file of the same base name as the mod. If this file can 11not be found, it will generate one for you. Chord assignment and 12transposition values can be very difficult and tedious to assign by hand. It 13is STRONGLY recommended that you let the program generate the initial .m2m 14file, so that it can do most (if not all) of this for you. You will still 15need to assign drums, correct banks/programs, and tweak volume amps by hand. 16 17 18 19 20EXAMPLE USAGE: 21 22timidity -c c:\timidity\timidity.cfg -OM -V 2 -idt foo.mod 23 24This will try to read in foo.m2m as the config file for the conversion, and 25will output a file called foo.mid. -V 2 tells it to generate midi for use 26on a device that uses an X^2 volume curve (all GM/GS/XG hardware). You can 27use the -o flag to specify any other output name you wish. 28 29If you don't have timidity installed, so that you don't have a valid 30timidity.cfg file, just create a 0 byte file and use it instead of the real 31thing. Since you're playing mod files, timidity doesn't need to load any 32midi instruments, so you don't need to have a set of patches or a real 33timidity.cfg file :) 34 35 36 37 38BACKGROUND: 39 40MOD files are a lot like MIDI files. Both formats are basicly a series of 41events that control how notes get played with which instruments. MODs 42package the instruments along with the events into a single file, while MIDI 43relies on external sources of instruments. It is this fundamental 44difference that creates the most difficulty in performing a mod->midi file 45conversion. The mod file does not need to know what pitch each sample is 46tuned to, if it is a drum, or if it is a chord. MOD players simply play the 47packaged sample at the requested pitch, assuming all samples are tuned to 48the same fixed frequency, whether they actually are or not. Thus, if you 49were to do a direct mod->midi event conversion, you would wind up with midi 50instruments playing in the wrong keys, snare drums being treated as normal 51melodic instruments, and single notes where there should be chords. 52Transposition, drum related channel movements, and chord emissions are the 53most noticable obstacles to overcome when performing an accurace mod->midi 54conversoin. 55 56Paolo Bonzini has already done half of my job for me. He contributed a good 57amount of code that turns TiMidity++ into a first rate mod player. This, 58alone, would not have helped me very much; it was how he implemented it. 59Rather than handle the events like every other mod player known to man, 60TiMidity++ converts them into standard midi events, loads the mod instruments 61in as special patches, and then renders them just like it would any normal 62midi file. The mod event parsing, instrument parsing, and direct event 63conversion was already done! All I had to do was handle the problems I 64mentioned above, along with many more minor ones I haven't mentioned, before 65writing the internal TiMidity++ events out to a midi file. See the comments 66at the top of m2m.c if you are interested in some of the other issues that 67needed to be addressed during the conversion process. Although some of 68these other issues were non-trivial to deal with, and pitch bends beyond 4 69octaves may still sound a bit odd, they are nothing that the average user 70needs to know about or keep in mind when trying to succesfully convert a mod 71file. The only thing you need to know is that, in order to address the 72conversion problems disscussed above, some information about each sample in 73the mod must be specified in a config file (.m2m) associated with each mod 74file. The format of this file is given below. 75 76 77 78 79M2M CONFIG FILE FORMAT: 80 81Comment lines must begin with a #. Blank lines (no spaces or any other 82character besides a newline or carriage return) are allowed. All other lines 83must specify ALL FIVE of the fields described below. Each field is separated 84by white space. 85 86 87 88FIELD 1: Sample Number 89 90This is the number of the sample that you are defining information for. 91The first sample in the mod file is 1 (not zero). 92 93 94 95FIELD 2: Bank/Program, drum flag, chord, silent flag 96 97This field specifies several different properties of the sample. Optional 98paramaters are given surrounded by parentheses. The format for this field 99is: 100 101(!)(bank/)program(chord)(*) 102 103If the field begins with an exclaimation mark, ! , then no notes will be 104issued for this sample. This can be used to silence samples that you can 105not assign to a general midi instrument, such as speech, complicated drum 106tracks, or any sound effect that you can not create a close approximation to 107using GS sfx banks. 108 109The bank portion of the field specifies an optional bank selection. This is 110the number of the bank to use, followed by a / to separate it from the 111program number. 112 113The program number is the midi instrument you are assigning to the sample. 114If the sample is a drum, this is the note that the drum is mapped to in the 115drum set. 116 117The optional chord field specifies what type of chord the sample is composed 118of. There are 4 types of chords, each of which has 3 subtypes. The 119supported chord types are (M)ajor, (m)inor, (d)iminished minor, and (f)ifth. 120Each chord is specified by the letter surrounded by parantheses in the 121previous line. The subtype of the chord describes how much the chord is 122"rotated" from a standard chord, which can be 0, 1, or 2. As an example of 123what I mean by "rotated", a major chord is composed of the following note 124semitone offsets: 0,4,7. If you were to rotate the chord one to the left, it 125would be: -5,0,4. Two to the left is: -8,-5,0. If no subtype is given, 126zero rotation is assumed. 127 128The final part specifies if the sample is a drum. Put a * at the end of the 129field to indicate this. Chord assignments will be ignored if the drum flag 130is set. 131 132Examples: 1338/48M bank 8, program 48 (Orchestra Strings), with a normal major chord 134!8/48M silence this sample 1358/48M2 same as the first example, only the chord is rotated down twice 13648 normal Marcato Strings in tone bank 0 13716/38* Power drum set, Snare1 13838* Snare1 on the regular drum set 0 139 140 141 142FIELD 3: Transposition 143 144This is how much to transpose the original note specified in the mod file. 145If the sample is tuned at middle C (pitch 60), it will need to be transposed 146+24 semitones for the midi instrument to play on the correct pitch. Samples 147marked as drums will not be transposed, since they are fixed to a single 148note on the drum channel. You must still enter a value for the 149transposition field, even if it is ignored by the drums, so that the config 150file parser will not crash. 151 152 153 154FIELD 4: Fine Tuning 155 156All pitch bend events for this sample will be adjusted by the given fraction 157of a pitch. This is sometimes necessary for highly out of tune samples. 158Some MOD composers, instead of tuning their samples correctly, use pitch 159bends to tune the samples. When you play this music with correctly tuned 160samples, these pitch bends detune the note and it sounds out of tune. So the 161fine tuning value is used to compensate for these detuning pitchbends. 162 163It is also common to find out of tune samples that were NOT tuned with 164pitchbends, so adding in a pitch bend adjustment would only make them sound 165worse in a midi file. To disable fine tuning, an optional ! can be placed 166before the fine tuning value. This is the DEFAULT SETTING in the automatic 167config file generator. If you find that a mod requires fine tuning for a 168sample, simply delete the ! and redo the conversion. 169 170This feature is not yet fully implemented. Only existing pitch bend events 171are affected, so no new pitch bend events are issued. This is not usually a 172problem, however, since most cases where this feature needs to be applied 173involve mods that issue pitch bends before the affected notes, since they 174were intended to tune the samples to begin with. I plan to eventually 175implement insertion of new pitch bend events, so that this will be a true 176fine tuning feature. 177 178 179 180FIELD 5: %Volume 181 182Each sample can be amplified by scaling the expression events. 100 is the 183default amount, which is 100% of the original volume. 50 would decrease it 184to half of the original volume, while 150 would be 1.5 times the original 185volume. Don't forget that the maximum expression value is 127, so any 186expression events that get scaled higher than this will cap off at 127 and 187you won't hear any difference. It is mainly used for quieting instruments 188that are too loud in the midi file, or for amplifying instruments whoose 189expression values are too low to begin with. 190 191Any fields beyond the first 5 will not be parsed. You can type anything 192here that you want. You do not have to place a # before comment text, but 193it is conventional to do so. 194 195 196 197 198FREQUENCY ANALYSIS: 199 200So, how do you figure out how much to transpose each sample and what chord 201it is? Load it up in a program that can perform an FFT on the sample and 202display the frequency peaks. The first peak is usually, but not always, the 203fundamental pitch of the sample. If the sample is a chord, take the first 3 204major peaks and assign the chord from these. Then enter the appropriate 205chord and transposition values in the .m2m file and see if it sounds correct. 206It is VERY time consuming to do all of this by hand.... So, I wrote routines 207to do all of the assignments for you :) It is not 100% accurate, but it's 208pretty darn close. And when it does miss a pitch or a chord, it always 209assigns it the correct LOOKING answer. That is, if I were to visually 210inspect the FFT data, I would pick the same pitch the algorithm does. I'm 211no expert at this, but after spending so many hours testing this on many 212different difficult to assign pitches, I think I'm pretty good at it now :) 213The only way I can see to improve it is to build in some sort of 214psychoacoustical model that takes into account how the human ear percieves 215the sound. And I don't think I want to do that at the moment.... It does an 216above average job at dealing with samples that have more than one pitch or 217chord in them, but don't be surprised if a noisy or multi-tonal sample 218doesn't get assigned correctly. Garbage in, garbage out :) The automatic 219assignment is very good for the vast majority of samples and should DEFINATELY 220be tried first before you start changing things by hand. When it does mess 221up, it's usually only off by a single semitone or an octave multiple, so it's 222easy to tweak from there. 223 224Before I wrote the automatic frequency analysis routines, I knew very little 225about the field. Pitch detection is a very old problem in the audio signal 226processing literature. I looked up references in the library dating from 227the 1960's. The stuff from back then is just as relevant as the later 228literature, since the methods really haven't improved much since then. The 229two major camps on how to do this are "autocorrelation" and "cepstrum" 230analysis. It turns out that autocorrelation was not the answer to my 231problems. While it works well on "well behaved" samples, it breaks down 232very quickly on synth instruments, noisy instruments, and instruments with 233multiple fundamental frequencies. A large number of samples encountered in 234mod files exhibit these properties. No matter what I did to try to tweak it, 235and I tried a lot of good things, I just could not make it robust enough to 236handle real world samples. It's a good theory, but it falls apart in 237practice. 238 239Cepstrum analysis proved to be much more robust. But even so, I had to do a 240good deal of pitch filtering and peak weighting before I could get it to work 241well. The 2nd FFT analysis kept giving me frequency peaks that didn't exist 242in the 1st FFT spectrum. They were, however, very close to real peaks. So I 243throw away all frequencies that fall below a pitch peak area and maximum 244magnitude filter, then force the cepstrum analysis to only choose pitches that 245have made it through the filter in the 1st FFT spectrum. I set a maximum 246frequency based on zero point crossing analysis, going out two zero crossings 247from the largest amplitude in the sample. This was necessary to prevent 248octave jumping errors. I found that it is also important to weight the 249cepstrum peak areas by the maximum magnitude within the corresponding pitch 250peak in the 1st FFT. This was a desperate attempt to get some especially 251troublesome bass samples to assign correctly. Surprisingly enough, it works 252great, giving me a higher success rate on all my samples without inducing any 253new misassignments! The only catch is that the weighting only works well for 254< 2 seconds of audio analysis. Any larger than that and the FFT size gets 255so big that the pitch peaks are too diffused, so the maximum magnitudes for 256the pitches are too small, and the weighting starts to give wrong answers. 257If anyone wants to analyze >= 2 seconds of data, which isn't neccessary for 258assigning pitches to mod/midi instruments, it would be easy to implement a 259sliding window average that calls the existing frequency assignment 260function. 261 262It appears to work better than any of the other sample analysis software I 263have. If you are interested in more details of how I did the cepstrum 264analysis, try looking over the code in freq.c and/or email me for a more 265complete description of the algorithm I wound up with. The new FFT routines 266are not mine, but are public domain. From all the benchmarks I could find, 267this is the best FFT implementation for doing what I need to do (and for 268future effects processing, should they ever be added to TiMidity++). See 269fft4g.c for info on where to get the original FFT package. 270 271 272 273 274SUGGESTIONS ?: 275 276Feel free to email me with any suggestions you may have on how I can do a 277better job of converting the mods, or how I can implement things on the TODO 278or WISH lists in m2m.c. I am considering turning this into a stand alone 279program, but until I get more free time and energy, it's going to stay as 280just an addon for TiMidity++. 281 282 283 284 285LEGAL STUFF: 286 287TiMidity++ is distributed under the GPL, and since my code is derived from 288and makes use of it, I guess it's under the GPL too. So blah blah blah, 289legal stuff, blah blah blah, etc.. You know the drill. 290 291 292 293 294Eric A. Welsh <ewelsh@ccb.wustl.edu> 295Center for Molecular Design 296Center for Computational Biology 297Washington University 298St. Louis, MO 299