This repository has been archived by the owner on Nov 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmusic.pyxl
73 lines (65 loc) · 3.16 KB
/
music.pyxl
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
const BGM_SECONDS_PER_BEAT = 0.2
const BGM_BEATS_PER_MEASURE = 12
const BGM_SECONDS_PER_MEASURE = 2.4 // SECONDS_PER_BEAT * BEATS_PER_MEASURE
const BGM_FRAMES_PER_BEAT = round(BGM_SECONDS_PER_BEAT * 60)
const BGM_FRAMES_PER_MEASURE = round(BGM_BEATS_PER_MEASURE * BGM_FRAMES_PER_BEAT)
let bgm_beat = -1 // whole-number beat
let bgm_measure = -1 // whole-number measure (12 beats/measure)
let bgm_beat_in_measure = -1 // whole-number beat index within each measure [0..11]
let bgm_beat_t = 0 // progress within the current beat [0..1]
let bgm_measure_t = 0 // progress within the current measure [0..1]
let bgm_beat_f = 0 // frame within the current beat [0..BGM_FRAMES_PER_BEAT-1]
let bgm_measure_f = 0 // frame within the current measure [0..BGM_FRAMES_PER_MEASURE-1]
// is this the first frame these variables have their current values?
let bgm_beat_ff = false
let bgm_measure_ff = false
// Internal state
let bgm_loops = []
def bgm_is_playing():
return size(bgm_loops) > 0
// loops is an array of objects; each will be passed to play_sound()
def bgm_start(loops):
bgm_stop() // stop existing loops
for l in loops:
push(bgm_loops, play_sound(l))
def bgm_stop():
for l in bgm_loops:
stop_audio(l)
bgm_loops = []
def bgm_update():
if size(bgm_loops) == 0:
return
let prev_beat = bgm_beat
let prev_measure = bgm_measure
let prev_beat_in_measure = bgm_beat_in_measure
let status = get_audio_status(bgm_loops[0])
const f = status.now * 60
bgm_beat = floor(f / BGM_FRAMES_PER_BEAT);
bgm_measure = floor(f / BGM_FRAMES_PER_MEASURE)
bgm_beat_in_measure = bgm_beat mod BGM_BEATS_PER_MEASURE
bgm_beat_f = f mod BGM_FRAMES_PER_BEAT
bgm_measure_f = f mod BGM_FRAMES_PER_MEASURE
bgm_beat_t = bgm_beat_f / BGM_FRAMES_PER_BEAT
bgm_measure_t = bgm_measure_f / BGM_FRAMES_PER_MEASURE
bgm_beat_ff = (bgm_beat != prev_beat)
bgm_measure_ff = (bgm_measure != prev_measure)
def bgm_set_volumes(volumes):
assert(size(volumes) == size(bgm_loops), "Must provide one volume per running loop")
for vol at i in volumes:
set_volume(bgm_loops[i], vol)
def bgm_draw_debug(z default 0) preserving_transform:
reset_transform()
let bb = xy(0,0)
const BGM_DEBUG_TEXT_ARGS = {font:font, color:#f, x_align:"left", y_align:"top", z:z}
const MAX_BAR_WIDTH = 40
const BAR_HEIGHT = 5
draw_text({text:"Beat: " + bgm_beat, pos:xy(0,0) + bb.y, ...BGM_DEBUG_TEXT_ARGS})
bb.y += font.line_height
draw_text({text:"Measure: " + bgm_measure, pos:xy(0,0+bb.y), ...BGM_DEBUG_TEXT_ARGS})
bb.y += font.line_height
draw_text({text:"BIM: " + bgm_beat_in_measure, pos:xy(0,0+bb.y), ...BGM_DEBUG_TEXT_ARGS})
bb.y += font.line_height
draw_corner_rect({corner:xy(0,bb.y), size:xy(MAX_BAR_WIDTH, BAR_HEIGHT), outline:#0ff, color:rgba(0,0,0,0), z:z})
draw_corner_rect({corner:xy(0,bb.y), size:xy(bgm_beat_t * MAX_BAR_WIDTH, BAR_HEIGHT), color:#0ff, z:z})
draw_corner_rect({corner:xy(0,bb.y+2*BAR_HEIGHT), size:xy(MAX_BAR_WIDTH, BAR_HEIGHT), outline:#0ff, color:rgba(0,0,0,0), z:z})
draw_corner_rect({corner:xy(0,bb.y+2*BAR_HEIGHT), size:xy(bgm_measure_t * MAX_BAR_WIDTH, BAR_HEIGHT), color:#0ff, z:z})