[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

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.