surgeosc-fm 0.2.12-alpha.0

surge synthesizer -- fm oscillator
# FM Oscillator for the Surge synthesizer system

The `surgeosc-fm` crate provides an implementation
of a Frequency Modulation (FM) Oscillator for the
Surge synthesizer system. This oscillator allows
the creation of complex and rich sounds by
modulating the frequency of one waveform (carrier)
with the amplitude of another waveform
(modulator). This FM synthesis technique is widely
used in electronic music production, offering
a vast range of sonic possibilities.

In the context of FM synthesis, the core
mathematical concept is frequency modulation,
represented by the following equation:

`output(t) = A * sin(2 * π * (f_c + (B * f_m) * sin(2 * π * f_m * t)) * t)`

where:
- `output(t)` is the oscillator output at time `t`
- `A` is the amplitude
- `f_c` is the carrier frequency
- `B` is the modulation index
- `f_m` is the modulator frequency

This crate provides the following tokens:

- `control_group`, `control_type`,
  `default_value`, `max_value`, `min_value`,
  `modulateable`, `moverate`, and `value_type`:
  These tokens are used to define and manage
  oscillator parameters, such as carrier
  frequency, modulation index, and waveform types.

- `FMOscillator`: The struct representing the FM
  oscillator, which holds the oscillator state and
  configuration.

- `do_fm_block`: A helper function to perform the
  core FM synthesis algorithm on a block of
  samples.

- `init`: A method to initialize the FM oscillator
  with the appropriate settings and parameter
  values.

- `process_block`: A method that processes a block
  of samples by applying the FM synthesis
  algorithm, using the `do_fm_block` function.

To use this crate, you'll need to integrate it
into your Surge synthesizer system or a compatible
application, ensuring proper initialization and
parameter management. By leveraging the power of
FM synthesis, you'll be able to create an
extensive range of sounds, from classic FM
electric pianos and bells to evolving textures and
complex harmonic structures.

9> /file surge-rs/surgeosc-fm/src/process.rs

The `FMOscillator` implementation provided here is
a frequency modulation (FM) oscillator that
processes audio in blocks. The algorithm uses
three modulators with different amounts and
frequency ratios or absolute frequencies, as well
as feedback to create a wide variety of
sounds. The implementation is optimized for the
Surge synthesizer system and processes audio
samples in chunks defined by `BLOCK_SIZE_OS`.

Let's break down the `process_block` function:

1. The method starts by retrieving the current
   parameter values for modulator amounts,
   frequency ratios, and absolute frequencies, as
   well as the feedback amount.

2. The oscillator pitch is updated with drift,
   which introduces small random variations to the
   pitch over time to simulate analog oscillator
   behavior.

3. The rates for each modulator are calculated
   based on the drifted pitch, frequency ratios,
   and absolute frequencies.

4. The modulation depths for each modulator are updated.

5. The FM depth is updated if FM is enabled.

6. The feedback depth is updated.

7. The `do_fm_block` function is called for each
   sample in the block to apply the FM algorithm.

8. If stereo processing is enabled, the left
   channel is duplicated to the right channel.

10> /file surge-rs/surgeosc-fm/src/block.rs

The `do_fm_block` function performs the core FM
synthesis operation on a single audio sample. It
takes the current sample index `k`, the carrier
waveform frequency `omega`, and a boolean flag
`fm` that indicates whether FM synthesis is
enabled or not.

Let's walk through the function step by step:

1. The function starts by retrieving the master
   oscillator's value at the current sample index
   `k`.

2. The three modulator oscillators (`rm1`, `rm2`,
   and `am`) are processed.

3. The output for the left channel is calculated
   by adding the current phase, the contributions
   of the three modulators, and the last output
   scaled by the feedback depth.

4. If FM synthesis is enabled, the contribution
   from the master oscillator is added, scaled by
   the FM depth.

5. The sine function is applied to the output
   sample to generate the final waveform.

6. The last output value is updated with the
   current output value, scaled by the feedback
   depth.

7. The phase of the oscillator is incremented by
   `omega`.

8. The modulation depths and feedback depth are
   updated by processing their respective
   envelopes.

This `do_fm_block` function is called for each
sample in a block by the `process_block`
method. By combining multiple modulators,
feedback, and optional FM synthesis, this
implementation of `FMOscillator` generates a wide
variety of complex and rich sounds.

11> cool thanks! could you teach me even more
about FM synthesis? what are its mathematical
properties?

Frequency Modulation (FM) synthesis is a technique
for generating complex sounds by modulating the
frequency of one waveform, called the carrier,
with another waveform, called the modulator. The
carrier waveform is usually a simple waveform like
a sine wave, and the modulator is often another
sine wave or a more complex waveform. The
resulting sound can have a rich harmonic content,
making FM synthesis suitable for creating a wide
variety of timbres.

The basic mathematical equation for FM synthesis
is as follows:

y(t) = A * sin(2 * π * (f_c + I * f_m * sin(2 * π * f_m * t)) * t)

Where:

- y(t) is the output signal at time t

- A is the amplitude

- f_c is the carrier frequency

- f_m is the modulator frequency

- I is the modulation index, determining the
  amplitude of the sidebands in the output signal

The modulation index (I) is crucial in determining
the harmonic content of the resulting
sound. A higher modulation index results in a more
complex sound with a richer harmonic structure,
while a lower modulation index produces a simpler
sound closer to the original carrier waveform.

One of the key features of FM synthesis is the
ability to create a wide range of harmonic
structures by varying the modulation index and the
ratio between the carrier and modulator
frequencies. When the frequency ratio is an
integer or a simple fraction, the resulting sound
tends to have a harmonic structure, making it
suitable for musical applications. In contrast,
when the frequency ratio is an irrational number,
the sound becomes more inharmonic and noisy.

In practice, FM synthesis can involve multiple
modulators, each with its own frequency and
modulation index. This allows for even more
complex and evolving sounds, as demonstrated in
the `FMOscillator` implementation you've provided
earlier. Furthermore, feedback can be introduced
by feeding the output of the carrier waveform back
into the modulator, resulting in even richer
harmonic structures.

Overall, FM synthesis is a powerful technique for
sound synthesis, offering a wide range of
possibilities for creating diverse and intricate
sounds with relatively simple mathematical
principles.