feat: buffered decoding API

This commit is contained in:
2024-06-19 04:08:54 +02:00
parent ae6ad428ab
commit c7a634eeb3
10 changed files with 1985 additions and 305 deletions
+81
View File
@@ -0,0 +1,81 @@
package main
import "core:os"
import "core:fmt"
import "core:mem"
import "core:mem/virtual"
import "core:time"
import "shared:alsa"
import "shared:flac"
DEVICE :: "default"
main :: proc() {
if len(os.args) < 2 {
fmt.eprintln("Please provide a path to a flac file.")
os.exit(1)
}
handle: ^alsa.pcm_t
arena: virtual.Arena
arena_err := virtual.arena_init_growing(&arena, mem.Megabyte * 8)
if arena_err != nil {
fmt.eprintln("Failed to alloc memory")
return
}
allocator := virtual.arena_allocator(&arena)
alsa_err := alsa.pcm_open(&handle, DEVICE, .PLAYBACK, .BLOCK)
if alsa_err < 0 {
fmt.eprintln("Failed to initialize audio device: ", alsa.strerror(alsa_err))
os.exit(1)
}
start := time.now()
flac_data, err := flac.load_from_file(os.args[1], allocator = allocator)
if err != nil {
fmt.eprintln(err)
if err == .MD5_Mismatch {
fmt.printfln("Expected: %v, got: %v", flac_data.metadata.expected_md5, flac_data.metadata.calculated_md5)
}
os.exit(1)
}
defer flac.destroy(flac_data, allocator = allocator)
end := time.now()
fmt.println(flac_data.metadata)
alsa_err = alsa.pcm_set_params(handle, .S16_LE, .RW_INTERLEAVED, u32(flac_data.metadata.channels), flac_data.metadata.sample_rate, 1, 500000)
if alsa_err < 0 {
fmt.eprintln("Playback open error:", alsa.strerror(alsa_err))
os.exit(1)
}
converted_samples := make([]i16, len(flac_data.samples))
for sample, i in flac_data.samples {
new_sample := sample & 0xFF
new_sample |= ((sample >> 8) & 0xFF) << 8
converted_samples[i] = i16(new_sample)
}
for {
frames := alsa.pcm_writei(handle, raw_data(converted_samples), u64(len(flac_data.samples)) / u64(flac_data.metadata.channels))
if frames < 0 {
fmt.eprintln("Error writing to PCM device:", alsa.strerror(auto_cast frames))
break
}
fmt.printfln("Played %d frames", frames)
}
alsa_err = alsa.pcm_drain(handle)
if alsa_err < 0 {
fmt.eprintln("pcm_drain failed with:", alsa.strerror(alsa_err))
}
alsa.pcm_close(handle)
elapsed := time.diff(start, end)
fmt.println("Decoding took", elapsed)
}