mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
examples: add examples/sokol/sounds/simple_keyboard_synth.v
This commit is contained in:
parent
f177237037
commit
952f63ef43
1 changed files with 114 additions and 0 deletions
114
examples/sokol/sounds/simple_keyboard_synth.v
Normal file
114
examples/sokol/sounds/simple_keyboard_synth.v
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
import time
|
||||||
|
import math
|
||||||
|
import term
|
||||||
|
import sokol.audio
|
||||||
|
|
||||||
|
struct Note {
|
||||||
|
mut:
|
||||||
|
phase f32
|
||||||
|
freq f32
|
||||||
|
amplitude f32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
mut:
|
||||||
|
notes shared []Note
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println('Press the keys (a, s, d, f, g, h, j, k) to play notes. Press ESC to quit.')
|
||||||
|
mut app := &App{
|
||||||
|
notes: []Note{len: 32}
|
||||||
|
}
|
||||||
|
audio.setup(
|
||||||
|
stream_userdata_cb: audio_callback
|
||||||
|
user_data: app
|
||||||
|
)
|
||||||
|
defer { audio.shutdown() }
|
||||||
|
term.enable_echo(false)
|
||||||
|
defer { term.enable_echo(true) }
|
||||||
|
for {
|
||||||
|
key := term.key_pressed(blocking: false)
|
||||||
|
app.handle_key(key) or { break }
|
||||||
|
time.sleep(5 * time.millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const c_2_pi = 2 * math.pi
|
||||||
|
const c_phase_step_per_freq = c_2_pi / 44100.0
|
||||||
|
const c_note_start_amplitude = 0.33
|
||||||
|
const c_note_decay = 0.3 / 44100.0
|
||||||
|
|
||||||
|
fn (mut app App) handle_key(key i64) ? {
|
||||||
|
if key == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mut freq := f32(0.0)
|
||||||
|
match key {
|
||||||
|
27 { return none }
|
||||||
|
` ` { app.silence() }
|
||||||
|
`a` { freq = 261.63 }
|
||||||
|
`s` { freq = 293.66 }
|
||||||
|
`d` { freq = 329.63 }
|
||||||
|
`f` { freq = 349.23 }
|
||||||
|
`g` { freq = 392.00 }
|
||||||
|
`h` { freq = 440.00 }
|
||||||
|
`j` { freq = 493.88 }
|
||||||
|
`k` { freq = 523.25 }
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
if freq > 0 {
|
||||||
|
app.play(freq, c_note_start_amplitude)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) play(freq f32, volume f32) {
|
||||||
|
lock app.notes {
|
||||||
|
for mut note in app.notes {
|
||||||
|
note.amplitude -= 0.2
|
||||||
|
}
|
||||||
|
for mut note in app.notes {
|
||||||
|
if note.amplitude <= 0 {
|
||||||
|
note = Note{
|
||||||
|
phase: 0.0
|
||||||
|
freq: freq
|
||||||
|
amplitude: volume
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) silence() {
|
||||||
|
lock app.notes {
|
||||||
|
for mut note in app.notes {
|
||||||
|
note.amplitude = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn audio_callback(mut soundbuffer &f32, num_frames int, num_channels int, mut app App) {
|
||||||
|
lock app.notes {
|
||||||
|
for frame in 0 .. num_frames {
|
||||||
|
mut sample := f32(0.0)
|
||||||
|
for mut note in app.notes {
|
||||||
|
if note.amplitude <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sample += note.amplitude * math.sinf(note.phase)
|
||||||
|
sample += note.amplitude * math.sinf(note.phase * 2.718)
|
||||||
|
sample += note.amplitude * math.sinf(note.phase * 3.141)
|
||||||
|
|
||||||
|
note.phase += note.freq * c_phase_step_per_freq
|
||||||
|
for note.phase >= c_2_pi {
|
||||||
|
note.phase -= c_2_pi
|
||||||
|
}
|
||||||
|
note.amplitude -= c_note_decay
|
||||||
|
}
|
||||||
|
for ch in 0 .. num_channels {
|
||||||
|
soundbuffer[frame * num_channels + ch] = sample
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue