MIDI instruments, for convention's sake, specify pitch as an integer from 0 to 127. They tie those values to the pitches used in a standard 12-tone, well-tempered tuning system (the kind you find on almost every standard western keyboard instrument). The pitch value 60 corresponds to middle C and each count up or down moves up or down one half-step in pitch. For example, 61 is a C sharp (or D flat), 62 is a D, 59 is a B, 58 is a B flat (or A sharp), and so on. A jump of 12 is an octave. For example, 69 is an A 440; 81 is an A 880, one octave above A 440.
Portfolio instruments use the standard MIDI tuning system by default, built on pitch values from 0 to 127, playing a 12-tone, equal-tempered tuning system. Not everything sounds its best in this tuning. If you want to reproduce the sounds of a Javanese gamelan or an Indian raga, the out-of-tune splendor of a honky-tonk piano, or the tight-knit harmonies of a barbershop quartet, you have to come up with some alternative tunings that assign different frequencies to the 128 MIDI pitch values.
You can, of course, specify the precise frequency as you play each note to get just the tuning you want. But if you want to play a MIDI score directly on an instrument without setting the precise frequency for each note, that will not work. You can, instead, reset the tuning of the instrument before you play. The score then plays back using the appropriate tuning system. To help you create and use alternative tunings, the Audio folio offers a set of tuning calls.
To create a tuning, you must create a list of frequencies (measured in cycles per second or Hertz) that you want to associate with MIDI pitch values. Each frequency value is stored as a 16.16 value, which allows you to represent fractional frequencies such as 261.63 Hz. The list of frequencies normally goes from lowest to highest, although you can invert that or mix the frequencies to create pitch inversion or true havoc when playing back MIDI scores.
You can, of course, create a list of 128 different frequencies, one for each of the 128 MIDI pitch values. This is useful if your tuning is irregular, and does not repeat itself from one octave to the next. If, however, your tuning uses one set of frequencies within an octave, and that set repeats in higher and lower octaves, then you need only define the frequencies within that one octave. For example, if you want to create a quarter-tone tuning system with 24 pitches per octave, you need only define the 24 pitches within a single octave. The Audio folio extends the tuning to the other octaves. You can also define two or more octaves of pitches if the tuning changes from one octave to the next, but repeats every third, fourth, or fifth octave.
Before you can apply a list of frequencies to an instrument, you must create a tuning based on that frequency list by using this call:
Item CreateTuning( ufrac16 *Frequencies, int32 NumNotes, int32 NotesPerOctave, int32 BaseNote )
*Frequencies
) to the list of frequencies. The second value (NumNotes
) is the number of frequencies found in the list. The third value (NotesPerOctave
) contains the number of pitches that fall within a single octave. And the final value (BaseNote
) is a single MIDI pitch value that corresponds to the first frequency in the frequency list.
When CreateTuning()
executes, it reads the frequencies in the list, starting at the beginning and going the number of frequencies specified by NumNotes
. It is important to set NumNotes
correctly to avoid losing frequencies or reading garbage values. It assigns the first frequency to the value set by BaseNote
and assigns subsequent frequencies to subsequent values. For example, if a five-frequency list is assigned to pitches starting with a base pitch of 60, the five frequencies are assigned in order to 60, 61, 62, 63, and 64. CreateTuning()
returns the item number of the tuning created if successful, or a negative value (an error code) if unsuccessful.
NotesPerOctave
value comes into play. If an instrument plays a note that falls outside the assigned range of pitches, the Audio folio looks at the number of pitches contained in each octave and extends the defined pitches to assign an appropriate frequency to undefined pitches.For example, consider the five-frequency list used above. Assume there are five pitches per octave. If an instrument using the tuning is asked to play pitch value 65 (which is unassigned), the Audio folio looks down five pitches (the span of an octave), finds the frequency assigned to 60, and doubles it to produce an octave-higher frequency for 65. To play pitch value 70, the Audio folio drops down 10 pitches (the span of two octaves) to 65 and quadruples the frequency there to produce a frequency two octaves higher.
If you are working with a sampled sound instrument, it typically has a pitch range that extends no higher than one octave above its recorded pitch. Below its recorded pitch, its pitch range descends into the depths of inaudibility.
To apply a tuning to one instrument, use this call:
Err TuneInstrument( Item Instrument, Item Tuning )
To apply a tuning to an instrument template (thereby applying it to all instruments created using that template), use this call:
Err TuneInsTemplate( Item InsTemplate, Item Tuning )
After tuning an instrument template, all instruments created from the template use the tuned template.
Err DeleteTuning( Item Tuning )
If an instrument is using a tuning and the tuning is deleted, the instrument returns to its default tuning.
The Audio folio provides a similar mechanism for audio instruments. Each instrument stores a bend value (a frac16 value) that multiplies the instrument's output frequency, bending any pitches played up or down by an amount corresponding to the multiplier. For example, if an instrument has a bend value of 2, then all output frequencies are doubled, so the instrument's output pitches bend up by an octave in pitch. If an instrument has a bend value of 0.5, then all output frequencies are halved, so the instrument's pitches bend down by an octave in pitch. And if an instrument has a bend value of 1 (the default value), the output frequencies do not change, and the instrument's output pitches are not bent.
To set an instrument's bend value, use this call:
Err BendInstrumentPitch( Item Instrument, frac16 BendFrac )
Instrument
, the item number of an instrument; and BendFrac
, a bend value to apply to that instrument. When it executes, the call applies the bend value to the instrument. All notes played on that instrument are then bent by the amount specified. The call returns 0 if successful, or a negative value (an error code) if unsuccessful.An instrument's bend value affects all pitches equally, so it does not affect the instrument's relative tuning. For example, if you set an instrument's tuning to a 24-step quarter-tone scale and then you bend the instrument up by a minor third, the instrument still plays a 24-step quarter-tone scale. It simply plays all the pitches in the scale a minor third higher than specified in the tuning.
DSP sampled sound instruments cannot bend up by more than one octave.
Err Convert12TET_F16( int32 Semitones, int32 Cents, frac16 *FractionPtr )
Semitones
, an integer number of half-steps (semitones) to bend up or down; Cents
, an integer number of cents to bend up or down; and *FractionPtr
, a pointer to a frac16 variable where the created bend value is stored. When Convert12TET_F16()
executes, it combines the number of half-steps and the number of cents to determine the final bend interval, creates a bend value that matches that interval, and then writes the bend value to the variable provided. If successful, it returns 0; if unsuccessful, it returns a negative value (an error code).
The Semitones
and Cents
arguments used for Convert12TET_F16()
can be negative or positive. Negative values bend pitch down, positive values bend pitch up. The two arguments need not both be positive or both be negative, one can be positive while the other is negative. For example, -5 semitones and +30 cents specifies a downward pitch interval of 4 semitones and 70 cents (an interval that is a little less than a fourth).