## A basic two-operator frequency modulation implementation

The FM suite (fmActor, fmHand, fmAlg) provides an implementation of the frequency modulation synthesis algorithm, along with its associated vss handler and actor. The FM suite also provides a model for implementing other synthesis algorithms in the vss3.0 framework, by virtue of its completeness as a generator actor and by its relative simplicity.

The synthesis algorithm is based upon two sinusoidal operators, the output of one modulating the phase of the other. A so-called "fm operator" is considered as a two-input black box sinewave generator. One input controls the frequency of the output sinusoid, the other, the instantaneous phase offset. This second input is called the "modulation input". This algorithm employs two operators, one as a modulator and one as a carrier. The output of the modulator ties to the modulation input of the carrier. The carrier output becomes the generated sound.

The spectrum of the generated sound consists of a spike at the carrier frequency and an infinite, decaying train of spikes (e.g. "harmonics") on either side of the carrier frequency. The harmonics are spaced in frequency according to integer multiples of the sum and difference of the carrier and modulator frequencies. The amount of modulation, i.e. the amplitude of the modulation applied to the carrier, is called the "modulation index" and controls the resulting spectral width or "brightness" of the output. Larger modulation indices result in a "richer" or "brighter" sound.

In addition, this algorithm implements "operator self-feedback". A controllable amount of the operator output is fed back to the operator's own modulation input. Spectrally, this also results in a train of harmonics spaced at even multiples of the operator's frequency. Depending upon the amount of feedback, this can lend a generally "warm", "brassy", or "buzzy" quality to the resulting tone, a quality which is otherwise difficult or computationally expensive to achieve. The operator feedback is implemented on both operators. Placing it on the modulator allows for a controllable degree of non-sinusoidal modulation of the carrier, greatly extending the degree of tonal richness achievable with only two operators.

Internally, the operators are a nice excercise in fast, linearly-interpolated sinusoidal wave-table lookup. The FM algorithm obeys the standard FM equations found in most introductory communications texts. For further investigation one may refer to the coverage of "Angle Modulation" in Modern Communications and Spread Spectrum by Cooper and McGillem, published by McGraw-Hill.

To use the FM implementation, load fm.so and create an actor of type FmActor.

### FmActor messages

In addition to the messages understood by all generator actors, the FmActor understands the following messages. If the optional parameter `time` is specified in any of the following messages, then the corresponding parameter is linearly modulated from the old value to the specified value over the duration of `time` seconds after receipt of the command. In the case of the commands SetAll[Param], the default [Param] is always set immediately on receipt of the command, regardless of `time`.

SetRatioMode `hActor bool`
  Set the default frequency ratio mode for new instances created by this actor to `bool`. Ratio Mode is active if `bool`=1, and is the default if `bool` is unspecified. In Ratio Mode the modulator frequency tracks changes in the carrier frequency according to the carrier/modulator frequency ratio parameter set by CMratio or MCratio. Ratio Mode is useful for changing the perceived "pitch" of the sound, without altering the perceived "timbre" of the sound, by issuing a single SetCarFreq-style command. If `bool`=0 then Ratio Mode is inactive and the carrier and modulator frequencies are independent.
SetAllRatioMode `hActor bool`
  Set the current frequency ratio mode of all children to `bool`, and set the default frequency ratio mode for new instances created by this actor to `bool`. Ratio mode is active when `bool`=1 and is the default if `bool` is unspecified. Refer to actor command SetRatioMode for behavioral details of Ratio Mode.
SetCarFreq `hActor x`
SetModFreq `hActor x`
  Set the default carrier (modulator) frequency for new instances created by this actor to `x`. (SetFreq is a synonym for SetCarFreq.)
SetAllCarFreq `hActor x time`
SetAllModFreq `hActor x time`
  Set the current carrier (modulator) frequency of all children to `x`, and set the default carrier (modulator) frequency for all future children to `x`.
SetCMratio `hActor x`
SetMCratio `hActor x`
  Set the default carrier-to-modulator frequency ratio (modulator-to-carrier frequency ratio) for new instances created by this actor to `x`.
SetAllCMratio `hActor x time`
SetAllMCratio `hActor x time`
  Set the current carrier-to-modulator frequency ratio (modulator-to-carrier frequency ratio) of all children to `x`, and set the default CM ratio (MC ratio) for all future children to `x`.
SetModIndex `hActor x`
  Set the default modulation index for new instances created by this actor to `x`.
SetAllModIndex `hActor x time`
  Set the current modulation index of all children to `x`, and set the default modulation index for all future children to `x`.
SetCarFeedback `hActor x`
SetModFeedback `hActor x`
  Set the default carrier (modulator) feedback amount for new instances created by this actor to `x`.
SetAllCarFeedback `hActor x time`
SetAllModFeedback `hActor x time`
  Set the current carrier (modulator) feedback amount of all children to `x`, and set the default carrier (modulator) feedback amount for all future children to `x`.

### FM handler messages

In addition to the messages understood by all handlers, the handler for the FM algorithm understands the following messages. If the optional parameter `time` is specified in any of the following messages, then the corresponding parameter is linearly modulated from the old value to the specified value over the duration of `time` seconds after receipt of the command.

SetRatioMode `hSound bool`
  Set to the frequency ratio mode to `bool`. Ratio mode is active when `bool`=1, and is the default if `bool` is unspecified. Refer to actor command SetRatioMode for the behavioral details of Ratio Mode.
SetCarFreq `hSound x time`
SetModFreq `hSound x time`
  Set the carrier (modulator) frequency to `x`. (SetFreq is a synonym for SetCarFreq.)
SetCMratio `hSound x time`
SetMCratio `hSound x time`
  Set the carrier-to-modulator (modulator-to-carrier) frequency ratio for this handler to `x`.
SetModIndex `hSound x time`
  Set the modulation index to `x`.
SetCarFeedback `hSound x time`
SetModFeedback `hSound x time`
  Set the carrier (modulator) feedback amount to `x`.