v2 / examples / sokol / sounds / simple_bytebeat.v
37 lines · 30 sloc · 1.34 KB · e1b7cb16f36095dbe0ed62c9c7341850d78ae507
Raw
1// vtest build: !openbsd
2
3// This program illustrates how to use sokol.audio in a simple console app, *without a gui*.
4// See melody.v for an example of how it can be integrated into a graphics app.
5import time
6import sokol.audio
7
8fn audio_callback(mut soundbuffer &f32, num_frames int, num_channels int, mut frame_0 &i32) {
9 for frame := 0; frame < num_frames; frame++ {
10 t := i32(f32(*frame_0 + frame) * 0.245)
11 y := (t * (((t / 10 | 0) ^ ((t / 10 | 0) - 1280)) % 11) / 2 & 127) +
12 (t * (((t / 640 | 0) ^ ((t / 640 | 0) - 2)) % 13) / 2 & 127)
13 for ch := 0; ch < num_channels; ch++ {
14 idx := frame * num_channels + ch
15 a := f32(y - 127) / 255.0
16 soundbuffer[idx] = a
17 }
18 }
19 frame_0 += num_frames
20}
21
22// The example uses \r, to show a simple progress bar, while the music is playing.
23// That works best, if the output is not buffered at all.
24unbuffer_stdout()
25
26println('The ByteBeat formula used in this example is from https://www.youtube.com/watch?v=V4GfkFbDojc , "Techno" by Gabriel Miceli')
27
28mut frame_0 := i32(0) // offset of the current audio frames, relative to the start of the music
29audio.setup(stream_userdata_cb: audio_callback, user_data: &frame_0) // our state/user_data can be just a simple integer
30
31for t in 0 .. 600 {
32 print('\r> t: ${t:5}s , frame_0: ${frame_0:10} samples')
33 time.sleep(1 * time.second)
34}
35println('\nGood bye.')
36
37audio.shutdown()
38