summary refs log tree commit diff
path: root/lib/music.fnl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/music.fnl')
-rw-r--r--lib/music.fnl83
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/music.fnl b/lib/music.fnl
new file mode 100644
index 0000000..434855b
--- /dev/null
+++ b/lib/music.fnl
@@ -0,0 +1,83 @@
+(local s (require :lib.music-state))
+
+(local sample-rate 8000)
+(local bit-depth 8)
+(local channels 2)
+(local buffers 4)
+(local buffer-size 256)
+
+(fn osc [n freq]
+  (tset s.voices n (% (+ (. s.voices n) (/ freq sample-rate)) 1))
+  (if (= s.screen :game)
+      (math.max -1 (math.min 1 (* (math.sin (* math.pi 2 (. s.voices n))) 2)))
+      (math.max -1 (math.min 1 (* (math.sin (* math.pi 2 (math.min 0.3 (. s.voices n)))) 1)))))
+
+(fn fill [buffer n]
+  (set s.alive* (+ s.alive* (* 0.03 (- s.alive s.alive*))))
+  (when (= (math.random 0 30) 0)
+    ;; (print s.t)
+    (local index (math.random 3 31))
+    (tset s.rhythms index (math.random 3 8))
+    (tset s.freqs index (* (. s.freqs (- index 1))
+                           (. [1 1.2 1.2 1.2 1.5 1.5 1.2 (/ 4 3) 1.75 2]
+                              (math.random 10)))))
+  (for [x 0 (- n 1)]
+    (for [side 1 2]
+      (var total 0)
+      (for [z 0 15]
+        (local vn (+ (* z 2) side -1))
+        (set total
+             (+ total
+                (* (osc vn (* (math.max 0.6 (or s.speed 0)) (/ 0.6) (. s.freqs vn)))
+                   (if (< vn (+ (/ s.alive* 23) 1)) 1 0)
+                   0.04
+                   (math.max 0
+                             (- 1 (* 0.00005
+                                     (% (- s.t (* vn 1600))
+                                        (* (. s.rhythms vn) 1600)))))))))
+      (set total (+ total
+                    (* 0.3
+                       (+ s.fire
+                          (if s.forward 0.3 0)
+                          (if (and s.shot-age (> s.shot-age 0)) 0.4 0))
+                       (^ (- (math.random) 0.5) 2))))
+      (buffer:setSample x side total))
+    (set s.t (+ s.t 1))))
+
+(fn load []
+  (set s.t 0)
+  (set s.alive* 0)
+  (set s.ring {})
+  (set s.ring-index 1)
+  (set s.voices (do (var t []) (for [i 0 31] (tset t i 0)) t))
+  (set s.freqs (do (var t [])
+                 (for [i 0 31]
+                   (tset t i (* 110 (^ 1.2 (math.floor (/ i 2))))))
+                 t))
+  (set s.rhythms (do (var t [])
+                   (for [i 0 31] (tset t i (if (< i 2) 8 (< i 4) 6
+                                               (+ (/ i 2) 8))))
+                   t))
+  (set s.volumes (do (var t []) (for [i 0 31]
+                                  (tset t i (if (< i 6) 1 0))) t))
+  (set s.source (love.audio.newQueueableSource
+                  sample-rate
+                  bit-depth
+                  channels
+                  buffers))
+  (for [i 1 buffers]
+    (tset s.ring i (love.sound.newSoundData buffer-size sample-rate bit-depth channels))))
+
+(fn pre-update []
+  )
+
+(fn update []
+  (when (not (s.source:isPlaying))
+    (s.source:play))
+  (while (> (s.source:getFreeBufferCount) 0)
+    (fill (. s.ring s.ring-index) buffer-size)
+    (do)
+    (s.source:queue (. s.ring s.ring-index))
+    (set s.ring-index (+ (% s.ring-index buffers) 1))))
+
+{: load : update : pre-update}