FMKik

# FMKik

A recipe for a simple FM kick drum.

<<fmkik.scm>>=
``<<top>>``

I tried to build this to be highly parametric, so the core function `fmkik` has a lot of variables, all lambdas except for `ft`:

`trig` is the trigger signal.

`freq` is the frequency of the kick (in hz).

`c`, `m`, and `i` are the carrier/modulation/index FM parameters. The index is being enveloped, so `i` is the initial amount.

`dst` is the overdrive distortion level (simple limit distortion). 1 is normal, anything greater will cause some sort of clipping.

`len` is the overall hold time length of the kick.

`tail` controls the decay time of the amp enveloped.

`body` controls the decay time of the modulation index (timbre) envelope.

`ft` is the sine ftable, as a lambda.

<<top>>=
``````(define (fmkik trig freq c m i dst len tail body ft)
(let* ((t (monolith:mkcab trig 0))
(trigf (lambda () (cabget t))))
(begin
(display t)
(newline)
(cabget t)
(tenvx
zz
(param 0.0001)
(len)
(tail))
(fmkik-fm
trigf
freq
c
m
(lambda () (expon (trigf) (i) (body) 0.001))
ft)
(mul zz zz)
(mul zz (dst))
(limit zz -1 1)

(cabclr t))))``````

The core components of the kick are a retriggerable sine oscillator, and from that a retriggerable FM oscillator.

<<top>>=
``````(define (fmkik-sine rt freq ft)
(tphasor (rt) (freq) 0)
(trd zz ft))``````

<<top>>=
``````(define (fmkik-fm rt freq car mod indx ft)
(let* ((o (lambda (f) (fmkik-sine rt f ft)))
(freq-reg (monolith:mkcab freq 0))
(fr (lambda () (cabget freq-reg)))
(car-reg (monolith:mkcab car freq-reg))
(c (lambda () (cabget car-reg)))
(car-osc
(lambda ()
(mul
(mul (indx) (mul (fr) (c)))
(o (lambda () (mul (fr) (c))))))))
(begin
(display "freq-reg: ")
(display freq-reg)
(newline)
(display "car-reg: ")
(display car-reg)
(newline)
(o (lambda () (add (mul (fr) (mod)) (car-osc))))
(cabclr freq-reg)
(cabclr car-reg))))``````

Here's a dead simple version of FMkik, with all the parameters tuned to a sensible defaults.

<<top>>=
``````(define (fmkik-default t ft)
(fmkik
t
(paramf 60)
(paramf 1)
(paramf 1)
(paramf 3)
(paramf 2)
(paramf 0.01)
(paramf 0.1)
(paramf 0.09)
ft))``````

A little demo:

``(monolith:load "ugens.scm")``

``(monolith:start)``

``````(define (run)
(display "FMKik Demo")
(newline)
(regset (gen_sine (ftnew 8192)) 0)
(fmkik-default
(lambda () (metro 1))
(lambda () (regget 0)))
(mul zz 0.5)
(out zz)
(regclr 0))``````