diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index a11d7ca..2750e54 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,6 +29,9 @@ jobs: echo "$(pwd)" >> "$GITHUB_PATH" ./odin report + - name: Build miniaudio + run: make -C "./Odin/vendor/miniaudio/src" + - name: Check everything run: | FLAGS="-vet -strict-style -vet-tabs -disallow-do -warnings-as-errors" @@ -166,3 +169,6 @@ jobs: odin check net/udp_echo_server/client $FLAGS odin check net/udp_echo_server/server $FLAGS + + odin check miniaudio/simple_playback_sine.odin -file $FLAGS + odin check miniaudio/playback_scale.odin -file $FLAGS diff --git a/miniaudio/playback_scale.odin b/miniaudio/playback_scale.odin new file mode 100644 index 0000000..4aabb26 --- /dev/null +++ b/miniaudio/playback_scale.odin @@ -0,0 +1,66 @@ +package main +// Solution of https://rosettacode.org/wiki/Musical_scale + +import "core:time" +import "core:fmt" +import ma "vendor:miniaudio" + +data_callback :: proc "c" (device: ^ma.device, output: rawptr, input: rawptr, frameCount: u32) { + assert_contextless(device.playback.channels == 2) + + sine := (^ma.waveform)(device.pUserData) + assert_contextless(sine != nil) + + ma.waveform_read_pcm_frames(sine, output, u64(frameCount), nil) +} + +main :: proc() { + NOTE :: [8]f64 {261.63, 293.67, 329.63, 349.23, 392.00, 440.01, 493.89, 523.26} + NOTE_NAME := [8]string {"C", "D", "E", "F", "G", "A", "B", "C'" } + + wave_config : ma.waveform_config = --- + device_config : ma.device_config = --- + wave : ma.waveform = --- + device : ma.device = --- + + device_config = ma.device_config_init(.playback) + device_config.dataCallback = data_callback + device_config.pUserData = &wave + + if ma.device_init(nil, &device_config, &device) != .SUCCESS { + panic("Failed to open playback device") + } + fmt.printfln("Device Name: %s", device.playback.name) + + for freq, i in NOTE { + wave_config = ma.waveform_config_init( + device.playback.playback_format, + device.playback.channels, + device.sampleRate, + .triangle, + 0.2, + freq, + ) + + if ma.waveform_init(&wave_config, &wave) != .SUCCESS { + fmt.eprintln("Failed to init waveform") + break + } + + if ma.device_start(&device) != .SUCCESS { + fmt.eprintln("Failed to start playback device") + break + } else { + fmt.printfln("Playing %s", NOTE_NAME[i]) + } + + time.sleep(time.Second) + + if ma.device_stop(&device) != .SUCCESS { + fmt.eprintln("Failed to stop playback device") + break + } + } + + ma.device_uninit(&device) +} diff --git a/miniaudio/simple_playback_sine.odin b/miniaudio/simple_playback_sine.odin new file mode 100644 index 0000000..6a37cf5 --- /dev/null +++ b/miniaudio/simple_playback_sine.odin @@ -0,0 +1,58 @@ +package main + +// port of https://miniaud.io/docs/examples/simple_playback_sine.html + +import "core:c/libc" +import "core:fmt" +import ma "vendor:miniaudio" + +data_callback :: proc "c" (device: ^ma.device, output: rawptr, input: rawptr, frameCount: u32) { + assert_contextless(device.playback.channels == 2) + + sine := (^ma.waveform)(device.pUserData) + assert_contextless(sine != nil) + + ma.waveform_read_pcm_frames(sine, output, u64(frameCount), nil) +} + +main :: proc() { + sine_config : ma.waveform_config = --- + device_config : ma.device_config = --- + sine : ma.waveform = --- + device : ma.device = --- + + device_config = ma.device_config_init(.playback) + device_config.playback.format = .f32 + device_config.playback.channels = 2 + device_config.sampleRate = 48000 + device_config.dataCallback = data_callback + device_config.pUserData = &sine + + if ma.device_init(nil, &device_config, &device) != .SUCCESS { + panic("Failed to open playback device") + } + fmt.printfln("Device Name: %s", device.playback.name) + + sine_config = ma.waveform_config_init( + device.playback.playback_format, + device.playback.channels, + device.sampleRate, + .sine, + 0.2, + 220, + ) + + if ma.waveform_init(&sine_config, &sine) != .SUCCESS { + panic("Failed to init waveform") + } + + if ma.device_start(&device) != .SUCCESS { + ma.device_uninit(&device) + panic("Failed to start playback device") + } + + fmt.printfln("Press Enter to quit...") + libc.getchar() + + ma.device_uninit(&device) +}