128 lines
4 KiB
Fennel
128 lines
4 KiB
Fennel
;; ============================================================================
|
|
;; Theme in A minor
|
|
;; Key: Am | Tempo: 95 BPM | Time: 4/4
|
|
;; ============================================================================
|
|
;;
|
|
;; Melody (Triangle, A4 range):
|
|
;; Bar 1: A4~ .C5 | E5 D5 | C5 A4 | G4 A4 |
|
|
;; Bar 2: A4~ .C5 | E5 G5 | F5 E5 | D5~~~~ |
|
|
;; Bar 3: D5~ .E5 | F5 D5 | C5 A4 | G4 A4 |
|
|
;; Bar 4: C5~ .D5 | E5 C5 | A4 G4 | A4~~~~ |
|
|
;;
|
|
;; Bass (Triangle, A2 range, octave jumps):
|
|
;; | A2 A2 A3 A2 | A2 A3 A2 A3 | C3 C3 C4 C3 | C3 C4 C3 C4 |
|
|
;; | D3 D3 D4 D3 | D3 D4 D3 D4 | A2 A2 A3 A2 | A2 A3 E3 A2 |
|
|
;;
|
|
;; Legend: ~ = held note, . = sixteenth rest before
|
|
;; ============================================================================
|
|
|
|
(local pxl8 (require :pxl8))
|
|
|
|
(var time 0)
|
|
(var step 0)
|
|
(var ctx nil)
|
|
(var melody-params nil)
|
|
(var bass-params nil)
|
|
(var playing false)
|
|
|
|
(local bpm 95)
|
|
(local beat (/ 60 bpm))
|
|
(local sixteenth (/ beat 4))
|
|
(local eighth (/ beat 2))
|
|
(local quarter beat)
|
|
(local _whole (* 4 beat))
|
|
|
|
(local melody [[69 eighth] [0 sixteenth] [72 sixteenth]
|
|
[76 eighth] [74 eighth]
|
|
[72 eighth] [69 eighth]
|
|
[67 eighth] [69 eighth]
|
|
|
|
[69 eighth] [0 sixteenth] [72 sixteenth]
|
|
[76 eighth] [79 eighth]
|
|
[77 eighth] [76 eighth]
|
|
[74 quarter]
|
|
|
|
[74 eighth] [0 sixteenth] [76 sixteenth]
|
|
[77 eighth] [74 eighth]
|
|
[72 eighth] [69 eighth]
|
|
[67 eighth] [69 eighth]
|
|
|
|
[72 eighth] [0 sixteenth] [74 sixteenth]
|
|
[76 eighth] [72 eighth]
|
|
[69 eighth] [67 eighth]
|
|
[69 quarter]])
|
|
|
|
(local bass [[45 eighth] [45 eighth] [57 eighth] [45 eighth]
|
|
[45 eighth] [57 eighth] [45 eighth] [57 eighth]
|
|
[48 eighth] [48 eighth] [60 eighth] [48 eighth]
|
|
[48 eighth] [60 eighth] [48 eighth] [60 eighth]
|
|
[50 eighth] [50 eighth] [62 eighth] [50 eighth]
|
|
[50 eighth] [62 eighth] [50 eighth] [62 eighth]
|
|
[45 eighth] [45 eighth] [57 eighth] [45 eighth]
|
|
[45 eighth] [57 eighth] [52 eighth] [45 eighth]])
|
|
|
|
(local step-duration sixteenth)
|
|
|
|
(fn init []
|
|
(set ctx (pxl8.sfx_context_create))
|
|
|
|
(local reverb (pxl8.sfx_reverb_create
|
|
{:room 0.5 :damping 0.4 :mix 0.35}))
|
|
(local compressor (pxl8.sfx_compressor_create
|
|
{:threshold -18 :ratio 6 :attack 3 :release 100}))
|
|
(pxl8.sfx_context_append_node ctx reverb)
|
|
(pxl8.sfx_context_append_node ctx compressor)
|
|
|
|
(pxl8.sfx_mixer_attach ctx)
|
|
|
|
(set melody-params (pxl8.sfx_voice_params
|
|
{:waveform pxl8.SFX_WAVE_TRIANGLE
|
|
:attack 0.02 :decay 0.15 :sustain 0.5 :release 0.15
|
|
:filter_type pxl8.SFX_FILTER_LOWPASS
|
|
:filter_cutoff 4000 :filter_resonance 0.0
|
|
:fx_send 0.4}))
|
|
|
|
(set bass-params (pxl8.sfx_voice_params
|
|
{:waveform pxl8.SFX_WAVE_TRIANGLE
|
|
:attack 0.015 :decay 0.1 :sustain 0.7 :release 0.1
|
|
:filter_type pxl8.SFX_FILTER_LOWPASS
|
|
:filter_cutoff 1800 :filter_resonance 0.0
|
|
:fx_send 0.15})))
|
|
|
|
(fn start []
|
|
(set playing true)
|
|
(set time 0)
|
|
(set step 0))
|
|
|
|
(fn stop []
|
|
(set playing false)
|
|
(pxl8.sfx_stop_all ctx))
|
|
|
|
(fn update [dt]
|
|
(when playing
|
|
(set time (+ time dt))
|
|
(when (>= time step-duration)
|
|
(set time (- time step-duration))
|
|
|
|
(local melody-idx (+ 1 (% step (length melody))))
|
|
(local melody-entry (. melody melody-idx))
|
|
(local melody-note (. melody-entry 1))
|
|
(local melody-dur (. melody-entry 2))
|
|
(when (> melody-note 0)
|
|
(pxl8.sfx_play_note ctx melody-note melody-params 0.45 melody-dur))
|
|
|
|
(local bass-step (math.floor (/ step 2)))
|
|
(local bass-idx (+ 1 (% bass-step (length bass))))
|
|
(local bass-entry (. bass bass-idx))
|
|
(local bass-note (. bass-entry 1))
|
|
(local bass-dur (. bass-entry 2))
|
|
(when (= (% step 2) 0)
|
|
(pxl8.sfx_play_note ctx bass-note bass-params 0.55 bass-dur))
|
|
|
|
(set step (+ step 1)))))
|
|
|
|
{:init init
|
|
:start start
|
|
:stop stop
|
|
:update update
|
|
:is-playing (fn [] playing)}
|