日本語English

FM Voice Parameters

How to write the YAML file that defines a 4-operator FM voice (音色). One file may define multiple voices.

File format

YAML format. Comment lines start with #; blank lines and whitespace-only lines are ignored. Load with one of fileio.LoadFMVoiceFile / LoadFMVoiceFileFS / SetFMVoiceData.

fmVoice:
  - voiceID: 0
    algorithm: 2
    feedback: 20
    lfo: true
    lfoDelay: 0.3
    lfoFade: 0.4
    lfoDepth: 30
    lfoHz: 7
    operators:
      - multiple: 1
        totallevel: 127
        detuneCents: 0
        wave: W1
        envelope: "11, 10, 0.6, 4, 12"
      - multiple: 2
        totallevel: 40
        detuneCents: 0
        wave: W1
        envelope: "31, 12, 0.3, 4, 12"
      - multiple: 1
        totallevel: 30
        detuneCents: 0
        wave: W2
        envelope: "31, 10, 0.5, 4, 12"
      - multiple: 1
        totallevel: 0
        detuneCents: 0
        wave: W2
        envelope: "31, 8, 0.7, 2, 12"

Voice parameters

KeyRange / formatDescription
voiceIDintegerUniquely identifies this voice. Referenced by [partSetting]'s voiceID or by RegisterVoice.
algorithminteger 0-7How the 4 operators are connected (see "Algorithm list" below).
feedback0-7Self-feedback amount applied to operator 1 (OP1). Values above 7 are treated as 7.
lfotrue / falseEnables/disables the vibrato LFO. Defaults to false if omitted (Phase 8).
lfoDelayseconds (0.1s steps)Delay from note-on until the LFO starts. Default when omitted: 0.4.
lfoFadeseconds (0.1s steps)Time from LFO start until it reaches full depth. Default when omitted: 0.5.
lfoDepthcents (100 = one semitone)LFO swing depth. Default when omitted: 30.
lfoHzHzLFO oscillation rate. Default when omitted: 6.

operators (fixed 4 entries, same fields for each)

KeyRange / formatDescription
multiplepositive floatFrequency ratio applied to the note's base frequency. A larger value produces a higher, more harmonic-sounding component. Not clamped.
totallevel0 (loudest) - 127 (silent)This operator's output attenuation. On a carrier (an operator whose output is audible) this controls volume; on a modulator it controls modulation depth. Attenuates at roughly 0.75dB per step.
detuneCentscents (100 = one semitone)Fine detune applied on top of multiple. Positive or negative.
waveW1-W8The basic waveform (see "Basic waveforms" below). Omitted or invalid defaults to W1 (sine).
envelope"attackRate, decay1Rate, sustainLevel, decay2Rate, releaseRate" comma-separated stringSee "Envelope" below.

envelope (5 fields)

Field (in order)RangeDescription
attackRate0-31Speed of the rise from silence to full level. 0 never rises; 31 is fastest.
decay1Rate0-31Speed of decay from full level down to sustainLevel. 0 holds at full level indefinitely.
sustainLevel0.0-1.0The level decay1 settles to.
decay2Rate0-31Speed of the slow secondary decay from sustainLevel toward 0. 0 sustains indefinitely without decaying.
releaseRate0-31Speed of the fall to silence after note-off. 0 never falls (be careful on a carrier - the note would never stop sounding).
Rate values sit on a logarithmic 0-31 scale mapped to real time (roughly 8 seconds down to a few milliseconds). A smaller value is slower, a larger value is faster.

Basic waveforms (W1-W8)

The 8 basic waveforms selectable via wave. phase represents a 0-2π phase angle.

SelectorNameWaveform character
W1Sine waveThe full-cycle basic waveform. The backward- compatible default matching pre-Phase-5 voices.
W2Half-rectified sineOnly the positive (upper) half-cycle is kept; the negative (lower) half is clamped to 0.
W3Full-wave rectified sineThe negative (lower) half-cycle is mirrored into the positive (upper) side.
W4Half-rectified sine (half period)A positive half-cycle in the first half of the period only; the second half is 0.
W5Sawtooth-like sineA positive half-wave repeated twice at double frequency (half width).
W6Full-wave rectified (half period)W3's humps packed twice as densely.
W7Positive full-wave rectified (polar)A scaled-down, positively shifted version of W3.
W8Asymmetric sawtooth-like sineW5's alternating-inversion counterpart.

Algorithm list (0-7)

Choose how the 4 operators (labeled OP1-OP4 in the diagrams, indices 0-3 internally) are connected. Arrows show the modulator→carrier direction; the orange-outlined boxes are that algorithm's "carriers" - the operators whose output is actually heard. Operator 1 (OP1) can always additionally receive self-feedback via feedback, regardless of algorithm.

algorithm: 0 — Full serial chain
OP1 OP2 OP3 OP4
A straight chain: OP1→OP2→OP3→OP4. Output = OP4. The strongest, most harmonically complex FM character of the eight.
algorithm: 1
OP1 OP2 OP3 OP4
OP1→OP4, OP2→OP3→OP4. Output = OP4. Two modulator chains converge onto one carrier.
algorithm: 2
OP1 OP2 OP3 OP4
OP1→OP4, OP2→OP3→OP4. Output = OP4. Similar to algorithm 1, but OP1 modulates OP4 directly (used by the sample voiceID:0).
algorithm: 3
OP1 OP2 OP3 OP4
OP1→OP2→OP4, OP3→OP4. Output = OP4. Two modulator paths converge onto one carrier.
algorithm: 4 — Two parallel FM pairs
OP1 OP2 OP3 OP4
(OP1→OP2) and (OP3→OP4) run independently in parallel. Output = OP2 + OP4. Sounds like two layered voices, adding thickness.
algorithm: 5 — One-to-many modulator
OP1 OP2 OP3 OP4
OP1 modulates OP2, OP3, and OP4 simultaneously. Output = OP2 + OP3 + OP4. A single modulator wobbling several carriers at once.
algorithm: 6
OP1 OP2 OP3 OP4
Only OP1→OP2 has a modulation link; OP3 and OP4 are fully independent carriers. Output = OP2 + OP3 + OP4.
algorithm: 7 — Fully independent (additive)
OP1 OP2 OP3 OP4
No modulation connections. All 4 operators are independent carriers. Output = OP1 + OP2 + OP3 + OP4. Suits organ-like additive sounds.

Example

A bass/lead-leaning voice (a mostly-serial algorithm 4, with the carrier-side operators set to W2):

fmVoice:
  - voiceID: 0
    algorithm: 4
    feedback: 20
    operators:
      - multiple: 20
        totallevel: 20
        detuneCents: 0
        wave: W1
        envelope: "28, 10, 0.6, 4, 20"
      - multiple: 2
        totallevel: 40
        detuneCents: 0
        wave: W1
        envelope: "31, 12, 0.3, 4, 20"
      - multiple: 1
        totallevel: 30
        detuneCents: 0
        wave: W2
        envelope: "31, 10, 0.5, 4, 20"
      - multiple: 1
        totallevel: 0
        detuneCents: 0
        wave: W2
        envelope: "31, 8, 0.7, 2, 20"
An undefined or invalid value (a minor YAML parse issue) is logged as a warning and treated as 0, and parsing continues. Loading is aborted with a fatal error only if the YAML itself is invalid.