summary refs log tree commit diff
path: root/lib/music.fnl
blob: d19a2694f7ba205363d619704d4364758f11becc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
(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.2 (. s.voices n)))) 1)))))

(fn fill [buffer n]
  (set s.alive* (+ s.alive* (* 0.03 (- s.alive s.alive*))))
  (when (= (math.random 0 35) 0)
    ;; (print s.t)
    (local index (math.random 3 23))
    (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 11]
        (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)
                   (if (> (. s.freqs vn) 1000) 0.3 1)
                   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 23] (tset t i 0)) t))
  (set s.freqs (do (var t [])
                 (for [i 0 23]
                   (tset t i (* 110 (^ 1.2 (math.floor (/ i 2))))))
                 t))
  (set s.rhythms (do (var t [])
                   (for [i 0 23] (tset t i (if (< i 2) 8 (< i 4) 6
                                               (+ (/ i 2) 8))))
                   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}