Again, you need the Hive Tech Preview thread and ist downloads a pre-requisites:
http://www.kvraudio.com/forum/viewtopic ... 1&t=511390
Bypassing further ado, let's dive right in:
Chapter 1: FM Fundamentals
The fundamental idea of FM is to take a sine wave oscillator (modulator) to modulate the *phase* of another sine wave oscillator (carrier). What you hear is the carrier, which has a richer spectrum than two sine waves would suggest. The spectrum (or resulting waveform) depends on the frequency relation of those two oscillators as well as on the depth/amplitude of the phase modulation. Sonic movement similar to filter sweeps in classic subtractive synthesis is achieved by scaling the volume of the modulator signal with envelopes. Disharmonic sounds (bells etc.) can be achieved by altering pitch, or simple by having a non-integer frequency relation of modulator and carrier.
While Wavetables can of course only ever have harmonic content, there's still a whole lot of FM goodness available.
Here's a simple sine wave oscillator:
Code: Select all
Wave "sin(2*pi*phase)"
Now, let's create another sine, but of any harmonic of choice:
Code: Select all
Wave "sin(2*pi*phase * 16)"
Now, let's see how to move phase, since that's what we want to modulate:
Code: Select all
Wave "sin(2*pi*phase + table*2*pi)"
Lesson: *Multiply* 2*pi*phase by n to change harmonic. *Add* 2*pi*n to change phase.
The general FM operator
So, in general our FM operators consist of the following formula:
sin( 2*pi*phase*harmonic + 2*pi*delta*depth )
optionally shortened to
sin( 2*pi* (phase*harmonic + delta*depth) )
Where harmonic is a whole number (1,2,3,4...16 or so) and delta is the output of another operator, optionally scaled by a depth parameter (Typically between 0 and, maybe, 5 or so, but that's up to anyone).
Note: I wrote harmonic, delta and depth in italics because we need to replace them with variables or functions available in the scripting language.
Examples!
Here's the simple most FM wavetable .uhm script:
Code: Select all
Wave "sin(2*pi*phase + sin(2*pi*phase*4))"
Code: Select all
Wave "sin(2*pi*phase*4)"
Wave "sin(2*pi*phase + x)"
Now, let's modulate the depth.
Code: Select all
Wave "sin(2*pi*phase*4)"
Wave "sin(2*pi*phase + x*(1-table))"
It is still a bit boring though. If you look at patch sheets from FM synths, they usually have Time/Level envelopes, shaping a nice short initial Decay to some low value, followed by a slow long decay towards zero. FM is renowned for its percussive sounds.
Hence:
Envelopes!
Of course you can do envelopes any way you like. You can create your wavetables bit by bit using the start/end frame positions. But that's tedious. Hence there is a 8-segment Time/Level envelope built into the engine. It nicely lends itself to FM Synthesis.
Code: Select all
Info "Simple FM patch"
NumFrames=101
/*
Introducing: The Envelope Feature!
No. | Time | Level
0 | --- | 1.0
1 | 0.2 | 0.3
2 | 0.8 | 0.0
...
8 | |
*/
Envelope L0=1 T1=0.2 L1=0.3 T2=0.8 L2=0.0
Wave "sin( 2*pi*phase * 5 )" // Modulator on 5th harmonic
Wave "sin( 2*pi*(phase + x * env(table)) )"
Code: Select all
Envelope L0=1 T1=0.2 L1=0.3 T2=0.8 L2=0.0
Before you ask: This envelope only exists in the script. It does not magically appear in Hive somewhere.
The way you use it, is in the last line. The envelope is accessed by the env(...) function in the formula parser:
Code: Select all
Wave "sin( 2*pi*(phase + x * env(table)) )"
(and yes, you can use "phase" as time base as well, in case of which the envelope evolves over the course of the cycle... see "Tut03 Classic Waves Part 3.uhm" for creating waveforms using the envelope.)
Now. Let that sink in. I'll think of something for the next chapters. More operators? Layering? Feedback modulation?