19 releases
0.2.12-alpha.0 | Apr 7, 2023 |
---|---|
0.2.11-alpha.0 | Dec 19, 2022 |
0.2.5-alpha.0 | Jun 21, 2022 |
0.2.4-alpha.0 | Mar 14, 2022 |
0.1.42-alpha.0 | Oct 27, 2021 |
#11 in #modulation
Used in 3 crates
510KB
10K
SLoC
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 timet
A
is the amplitudef_c
is the carrier frequencyB
is the modulation indexf_m
is the modulator frequency
This crate provides the following tokens:
-
control_group
,control_type
,default_value
,max_value
,min_value
,modulateable
,moverate
, andvalue_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 thedo_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:
-
The method starts by retrieving the current parameter values for modulator amounts, frequency ratios, and absolute frequencies, as well as the feedback amount.
-
The oscillator pitch is updated with drift, which introduces small random variations to the pitch over time to simulate analog oscillator behavior.
-
The rates for each modulator are calculated based on the drifted pitch, frequency ratios, and absolute frequencies.
-
The modulation depths for each modulator are updated.
-
The FM depth is updated if FM is enabled.
-
The feedback depth is updated.
-
The
do_fm_block
function is called for each sample in the block to apply the FM algorithm. -
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:
-
The function starts by retrieving the master oscillator's value at the current sample index
k
. -
The three modulator oscillators (
rm1
,rm2
, andam
) are processed. -
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.
-
If FM synthesis is enabled, the contribution from the master oscillator is added, scaled by the FM depth.
-
The sine function is applied to the output sample to generate the final waveform.
-
The last output value is updated with the current output value, scaled by the feedback depth.
-
The phase of the oscillator is incremented by
omega
. -
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.
Dependencies
~11–20MB
~299K SLoC