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