In order to allow a wave to playback over a range of musical notes, (+/- semitones), its playback rate must be raised or lowered by a set amount. From one semitone to the next, this set amount is by a factor of the 12th root of 2 (assuming a western, equal-tempered scale). Here is a table that shows what factor would need to be multiplied by the sampling rate in order to transpose the wave's pitch. Pitch in relation to the Root Multiply Rate by this amount ------------------------------- ------------------------------ DOWN 6 semitones 0.5 DOWN 5 1/2 semitones 0.529731547 DOWN 5 semitones 0.561231024 DOWN 4 1/2 semitones 0.594603557 DOWN 4 semitones 0.629960525 DOWN 3 1/2 semitones 0.667419927 DOWN 3 semitones 0.707106781 DOWN 2 1/2 semitones 0.749153538 DOWN 2 semitones 0.793700526 DOWN 1 1/2 semitones 0.840896415 DOWN 1 semitones 0.890898718 DOWN 1/2 semitone 0.943874312 ORIGINAL_PITCH 1.0 /* rootnote's pitch */ UP 1/2 semitone 1.059463094 UP 1 semitones 1.122562048 UP 1 1/2 semitones 1.189207115 UP 2 semitones 1.259921050 UP 2 1/2 semitones 1.334839854 UP 3 semitones 1.414213562 UP 3 1/2 semitones 1.498307077 UP 4 semitones 1.587401052 UP 4 1/2 semitones 1.681792830 UP 5 semitones 1.781797436 UP 5 1/2 semitones 1.887748625 UP 6 semitones 2 For example, if the wave's Rate is 18000 hz, and you wish to play the wave UP 1 semitone, then the playback rate is: 18000 x 1.122562048 = 20206.11686 hz The sampling period for the Amiga is therefore: (1/20206.11686)/.279365 = .000177151 and to send it to the Audio Device, it is rounded and expressed in micro- seconds: 177 Obviously, this involves floating point math which can be time consuming and impractical for outputing sound in real-time. A better method is to construct a transpose table that contains the actual periods already calculated for every semitone. The drawback of this method is that you need a table for EVERY DIFFERENT Rate in the SAMP file. If all the Rates in the file happened to be the same, then only one table would be needed. Let's assume that this is the case, and that the Rate = 18000 hz. Here is a table containing enough entries to transpose the waves +/- 6 semitones. Pitch in relation to the Root Amiga Period (assuming rate = 18000 hz) ----------------------------- --------------------------------------- Transposition_table[TRANS_TABLE_SIZE]={ /* DOWN 6 semitones */ 398, /* DOWN 5 1/2 semitones */ 375, /* DOWN 5 semitones */ 354, /* DOWN 4 1/2 semitones */ 334, /* DOWN 4 semitones */ 316, /* DOWN 3 1/2 semitones */ 298, /* DOWN 3 semitones */ 281, /* DOWN 2 1/2 semitones */ 265, /* DOWN 2 semitones */ 251, /* DOWN 1 1/2 semitones */ 236, /* DOWN 1 semitones */ 223, /* DOWN 1/2 semitone */ 211, /* ORIGINAL_PITCH */ 199, /* rootnote's pitch */ /* UP 1/2 semitone */ 187, /* UP 1 semitones */ 177, /* UP 1 1/2 semitones */ 167, /* UP 2 semitones */ 157, /* UP 2 1/2 semitones */ 148, /* UP 3 semitones */ 141, /* UP 3 1/2 semitones */ 133, /* Since the minimum Amiga period = 127 the following are actually out of range. */ /* UP 4 semitones */ 125, /* UP 4 1/2 semitones */ 118, /* UP 5 semitones */ 112, /* UP 5 1/2 semitones */ 105, /* UP 6 semitones */ 99 }; Let's assume that (according to the PlayMap) midi note #40 is set to play wave number 3. Upon examining wave 3's structure, we discover that the Rate = 18000, and the RootNote = 38. Here is how the Amiga sampling period is calulated using the above 18000hz "transpose chart" in C: /* MidiNoteNumber is the received midi note's number (here 40) */ #define ORIGINAL_PITCH TRANS_TABLE_SIZE/2 + 1 /* TRANS_TABLE_SIZE is the number of entries in the transposition table (dynamic, ie this can change with the application) */ transposeAmount = (LONG) (MidiNoteNumber - rootNote); /* make it a SIGNED LONG */ amigaPeriod = Transposition_table[ORIGINAL_PITCH + transposeAmount]; In assembly, the 18000hz transpose chart and above example would be: Table dc.w 398 dc.w 375 dc.w 354 dc.w 334 dc.w 316 dc.w 298 dc.w 281 dc.w 265 dc.w 251 dc.w 236 dc.w 223 dc.w 211 ORIGINAL_PITCH dc.w 199 ; rootnote's pitch dc.w 187 dc.w 177 dc.w 167 dc.w 157 dc.w 148 dc.w 141 dc.w 133 ; Since the minimum Amiga period = 127, the following ; are actually out of range. dc.w 125 dc.w 118 dc.w 112 dc.w 105 dc.w 99 lea ORIGINAL_PITCH,a0 move.b MidiNoteNumber,d0 ;the received note number sub.b RootNote,d0 ;subtract the wave's root note ext.w d0 ext.l d0 ;make it a signed LONG add.l d0,d0 ;x 2 in order to fetch a WORD adda.l d0,a0 move.w (a0),d0 ;the Amiga Period (WORD) Note that these examples don't check to see if the transpose amount is beyond the number of entries in the transpose table. Nor do they check if the periods in the table are out of range of the Amiga hardware.