examples: cleanup & fix the sound produced by melody.v, to be like the original https://www.youtube.com/watch?v=V4GfkFbDojc

This commit is contained in:
Delyan Angelov 2024-08-01 09:16:59 +03:00
parent da5dc8bb22
commit ab8f1ba21b
No known key found for this signature in database
GPG key ID: 66886C0F12D595ED

View file

@ -1,12 +1,8 @@
import gg import gg
import gx
import sokol.audio import sokol.audio
const credits = 'Based on the ByteBeat formula from: https://www.youtube.com/watch?v=V4GfkFbDojc \n "Techno" by Gabriel Miceli'
struct AppState { struct AppState {
mut: mut:
gframe int // the current graphical frame
frame_0 int // offset of the current audio frames, relative to the start of the music frame_0 int // offset of the current audio frames, relative to the start of the music
frames [2048]f32 // a copy of the last rendered audio frames frames [2048]f32 // a copy of the last rendered audio frames
gg &gg.Context = unsafe { nil } // used for drawing gg &gg.Context = unsafe { nil } // used for drawing
@ -20,7 +16,7 @@ fn my_audio_stream_callback(mut soundbuffer &f32, num_frames int, num_channels i
(t * (((t / 640 | 0) ^ ((t / 640 | 0) - 2)) % 13) / 2 & 127) (t * (((t / 640 | 0) ^ ((t / 640 | 0) - 2)) % 13) / 2 & 127)
for ch := 0; ch < num_channels; ch++ { for ch := 0; ch < num_channels; ch++ {
idx := frame * num_channels + ch idx := frame * num_channels + ch
a := f32(u8(y) - 127) / 255.0 a := f32(y - 127) / 255.0
soundbuffer[idx] = a soundbuffer[idx] = a
acontext.frames[idx & 2047] = a acontext.frames[idx & 2047] = a
} }
@ -28,15 +24,34 @@ fn my_audio_stream_callback(mut soundbuffer &f32, num_frames int, num_channels i
acontext.frame_0 += num_frames acontext.frame_0 += num_frames
} }
fn graphics_frame(mut state AppState) {
ws := gg.window_size()
center_y := ws.height / 2
state.gg.begin()
for x in 0 .. 1024 {
vx := int(ws.width * f64(x) / 1024.0)
vy := f32(center_y) * 3.0 / 4.0 * (state.frames[2 * x] + state.frames[2 * x + 1])
color := gg.Color{state.f(x), state.f(x + 300), state.f(x + 700), 255}
state.gg.draw_line(vx, center_y, vx, center_y + vy, color)
}
state.gg.end()
}
@[inline]
fn (state &AppState) f(idx int) u8 {
return u8(127 + state.frames[(int(state.gg.frame) + idx) & 2047] * 128)
}
fn main() { fn main() {
println(credits) println('Based on the ByteBeat formula from: https://www.youtube.com/watch?v=V4GfkFbDojc \n "Techno" by Gabriel Miceli')
mut state := &AppState{} mut state := &AppState{}
audio.setup( audio.setup(
stream_userdata_cb: my_audio_stream_callback stream_userdata_cb: my_audio_stream_callback
user_data: state user_data: state
) )
defer { audio.shutdown() }
state.gg = gg.new_context( state.gg = gg.new_context(
bg_color: gx.rgb(50, 50, 50) bg_color: gg.Color{50, 50, 50, 255}
width: 1024 width: 1024
height: 400 height: 400
create_window: true create_window: true
@ -45,26 +60,4 @@ fn main() {
user_data: state user_data: state
) )
state.gg.run() state.gg.run()
audio.shutdown()
}
fn graphics_frame(mut state AppState) {
state.gframe++
state.gg.begin()
state.draw()
state.gg.end()
}
@[inline]
fn (mut state AppState) bsample(idx int) u8 {
return u8(127 + state.frames[(state.gframe + idx) & 2047] * 128)
}
fn (mut state AppState) draw() {
// first, reset and setup ortho projection
for x in 0 .. 1024 {
mut y := 100 * (state.frames[2 * x] + state.frames[2 * x + 1])
state.gg.draw_line(x, 200, x, 200 + y, gx.rgba(state.bsample(x), state.bsample(x + 300),
state.bsample(x + 700), 255))
}
} }