FMINST


Frequency modulation: a type of distortion synthesis where one waveform (the carrier) of frequency fc is modulated by another waveform (the modulator) with frequency fm and modulation index I (defined by the maximum amplitude deviation of the modulator oscillator divided by its frequency). The resultant sound consists of the carrier frequency as well as a number of sidebands of frequencies fc ± kfm, where k is an integer series increasing from 0 (the carrier frequency). The amplitude of the sidebands over time is determined by a Bessel function of the first kind Jk(I). Negative frequencies are possible, resulting in a 180° out-of-phase sideband at the absolute value of that frequency. Negative amplitudes are also possible, resulting in a reversal of phase at that sideband (paraphrased from Dodge and Jerse, 1985).

FM has traditionally been considered a computationally efficient method to create complex, time-varying spectra using just two oscillators. rAa very low modulation index and/or frequency will result in vibrato on the carrier signal. As the modulation increases, the spectrum will become increasingly richer. FMINST provides for a time-varying index of modulation based on gen3 and p4 and p5 of the instrument (which define the index curve, its low point, and its high point, respectively).

Syntax:


makegen(1, 24, 1000, t0, a0, t1, a1...) /* amplitude envelope of the output signal, in time/amplitude pairs */
makegen(2, 10, 1000, p0, p1...) /* spectrum of the carrier oscillator */
makegen(3, 24, 1000, t0, a0, t1, a1...) /* envelope of the modulation index, in time/amplitude pairs */

FMINST(outskip, duration, amplitude, fc, fm, indexlow, indexhi, spread)
in comment form:

/* p0 = start; p1 = dur; p2 = amplitude; p3 = pitch of carrier (hz or oct.pc); 
   p4 = pitch of modulator (hz or oct.pc); p5 = fm index low point;
   p6 = fm index high point;  p7 = stereo spread (0-1) 
   function slot 1 is the amp, slot 2 is oscillator waveform;
   slot 3 is index guide /*

An example score:

rtsetparams(44100, 2)
load("FMINST")
makegen(1, 24, 1000, 0, 0, 3.5,1, 7,0)
makegen(2, 10, 1000, 1)
makegen(3, 24, 1000, 0,1, 7,0)
FMINST(0, 7, 20000, 8.00, 179, 0, 10)

Another score, showing different index envelopes:

rtsetparams(44100, 2)
load("FMINST")
makegen(1, 24, 1000, 0, 0, 3.5,1, 7,0)
makegen(2, 10, 1000, 1)
makegen(3, 24, 1000, 0, 0, 5,1, 7, 0)
FMINST(0, 7, 10000, 8.00, 179, 0, 10, 0.1)
makegen(3, 24, 1000, 0,1, 7,0)
FMINST(3.5, 7, 10000, 8.07, 179, 0, 10, 0.9)

A third score, featuring a looping structure:

rtsetparams(44100, 2)
load("FMINST")
print_off()
makegen(1, 7, 1000, 0, 500, 1, 500, 0)
makegen(2, 10, 1000, 1)
makegen(3, 24, 1000, 0,1, 2,0)

nfms = 1
for (start = 0; start < 60; start = start + 1.5) {
	freq = 8.00
	for (n = 0; n < nfms; n = n + 1) {
		FMINST(start, 1.5, 1000, freq, 179, 0, 10)
		freq = freq + 0.02
		}
	nfms = nfms + 1
}