package wav import "core:fmt" import "core:math" import "core:strings" import "core:os" import "core:encoding/xml" Wav :: struct { // Basic data path : string, handle : os.Handle, format : Audio_Format, channels : int, sample_rate : int, bit_depth : int, reported_size : u32, // Metadata buf : []u8, channel_names : []string, bext : string, ixml : string, } Audio_Format :: enum { PCM = 1, FLOAT = 3, } BUFFER_SIZE :: 1<<15 main :: proc() { enok, enok_ok := read_wav("test/ENOKS-BIRHTDAYT02.WAV", context.temp_allocator) fmt.printf("\n\nenok = %#v\n\n", enok) f8, f8_ok := read_wav("test/F8-SL098-T001.WAV", context.temp_allocator) fmt.printf("\n\nf8 = %#v\n\n", f8) } // TODO: Maybe split reading metadata into its own function call. read_wav :: proc(path : string, allocator:=context.allocator) -> (Wav, bool) { file : Wav file_ok : os.Error file.handle, file_ok = os.open(path) defer os.close(file.handle) assert(file_ok == os.General_Error.None) file.buf = new([BUFFER_SIZE]u8)[:] defer delete(file.buf) os.read(file.handle, file.buf) head : int = 0 // RIFF header fmt.println(string(file.buf[0:4])) if string(file.buf[0:4]) != "RIFF" do return {}, false head += 4 // Size file.reported_size = read_little_endian_u32(file.buf[head:head+4]) fmt.println("Reported size:", file.reported_size) head += 4 // Confirming again that this is a wave file fmt.println(string(file.buf[head:head+4])) if string(file.buf[head:head+4]) != "WAVE" do return {}, false head += 4 fmt.println("\nChunks:\n") // Looping through chunks for _ in 0..\n", element.ident) for value in element.value { switch v in value { case string: tab(indent + 1) fmt.printf("[Value] %v\n", v) case xml.Element_ID: xml_recurse(doc, v, indent + 1) } } for attr in element.attribs { tab(indent + 1) fmt.printf("[Attr] %v: %v\n", attr.key, attr.val) } } else if element.kind == .Comment { fmt.printf("[COMMENT] %v\n", element.value) } return } read_little_endian_u32 :: proc(x : []u8) -> u32 { return u32(x[0]) | u32(x[1]) << 8 | u32(x[2]) << 16 | u32(x[3]) << 24 } read_little_endian_u16 :: proc(x : []u8) -> u16 { return u16(x[0]) | u16(x[1]) << 8 }