aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSan Jacobs2025-12-07 15:10:24 +0100
committerSan Jacobs2025-12-07 15:10:24 +0100
commitcd0191917c9591d18db9db6c812b0705ce55e591 (patch)
tree3162c2ccc155f51a3ec20fa49ae1835325bf3cb5
parent09ec5f18a0583c94286f1f1f1b462f675d93d94d (diff)
downloadbetter-report-cd0191917c9591d18db9db6c812b0705ce55e591.tar.gz
better-report-cd0191917c9591d18db9db6c812b0705ce55e591.tar.bz2
better-report-cd0191917c9591d18db9db6c812b0705ce55e591.zip
zoom wavs and ixml parse
-rw-r--r--src/wav/wav.odin70
1 files changed, 61 insertions, 9 deletions
diff --git a/src/wav/wav.odin b/src/wav/wav.odin
index 04cb0cf..500122e 100644
--- a/src/wav/wav.odin
+++ b/src/wav/wav.odin
@@ -4,19 +4,23 @@ 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,
- buf : []u8,
- reported_size : u32,
- bext : string,
- ixml : string,
format : Audio_Format,
channels : int,
- channel_names : []string,
sample_rate : int,
bit_depth : int,
+ reported_size : u32,
+
+ // Metadata
+ buf : []u8,
+ channel_names : []string,
+ bext : string,
+ ixml : string,
}
Audio_Format :: enum {
PCM = 1,
@@ -26,12 +30,13 @@ Audio_Format :: enum {
BUFFER_SIZE :: 1<<15
main :: proc() {
- sweden, sweden_ok := read_wav("test/sweden.wav", context.temp_allocator)
- fmt.printf("\n\nsweden = %#v\n\n", sweden)
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
@@ -110,22 +115,69 @@ read_wav :: proc(path : string, allocator:=context.allocator) -> (Wav, bool) {
head += chunk_size
}
- file.channel_names = make([]string, file.channels)
+ file.channel_names = make([]string, file.channels, allocator=allocator)
naming_channel := 0
for line in strings.split_lines(file.bext) {
- if strings.starts_with(line, "sTRK") {
+ if strings.starts_with(line, "sTRK") || strings.starts_with(line, "zTRK") {
eq_index := strings.index(line, "=")
file.channel_names[naming_channel] = strings.clone(line[eq_index+1:], allocator=allocator)
naming_channel += 1
}
}
+ // iXML Parsing
+
+ parsed_ixml : ^xml.Document
+
+ if file.ixml != "" {
+ parsed_ixml, _ = xml.parse(file.ixml, xml.Options{
+ flags={.Ignore_Unsupported},
+ expected_doctype = "",
+ })
+ }
+
+ xml_recurse(parsed_ixml, 0)
+
delete(file.buf)
file.buf = nil
return file, true
}
+xml_recurse :: proc(doc: ^xml.Document, element_id: xml.Element_ID, indent := 0) {
+ tab :: proc(indent: int) {
+ for _ in 0..=indent {
+ fmt.printf("\t")
+ }
+ }
+
+ tab(indent)
+
+ element := doc.elements[element_id]
+
+ if element.kind == .Element {
+ fmt.printf("<%v>\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]) |