From 6d670d069efddddce0a211ca5d9f1ae3a3d7a287 Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Fri, 29 Aug 2025 17:42:49 +0200 Subject: SoundDevices 8-series support! --- main.odin | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 188 insertions(+), 44 deletions(-) (limited to 'main.odin') diff --git a/main.odin b/main.odin index c5f3125..cd3d3c5 100755 --- a/main.odin +++ b/main.odin @@ -8,11 +8,13 @@ import "core:sys/windows" import "core:strings" /* -TODO: Drag-n-drop window -TODO: Testing with 8-series +TODO: Simplify pre-allocation. Just allocate a bunch. It's probably fine. + Maybe do it by just counting how many lines are longer than 2 characters. +TODO: Drag-n-drop window if no files are specified */ VERBOSE :: false +INCLUDE_DATE :: false // By default I delete the retarded date field that says what day the report was generated. PART_ONE :: #load("parts/start.html", string) PART_TWO :: #load("parts/start2.html", string) @@ -22,6 +24,7 @@ Device :: enum { UNSET, ZOOM, SD6, + SD8, // Tested with 888 } Stages :: enum { @@ -123,20 +126,25 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { // STAGE 1 -------------------------------------------------------------- // First, we detect what kind of sound report this is - for line, line_number in lines { + for line, line_number in lines[:3] { if (device!=.UNSET) { break } - if line == "\"SOUND REPORT\"," { + if line == "\"SOUND REPORT\"," { device = .ZOOM if VERBOSE do fmt.printf("Detected ZOOM from quotes and comma on line index {}\n", line_number) } - if line == "\"ZOOM F8\"," { + if line == "\"ZOOM F8\"," { device = .ZOOM if VERBOSE do fmt.printf("Detected ZOOM from \"ZOOM F8\" on line index {}\n", line_number) } - if line == "SOUND REPORT" { + if line == "SOUND REPORT" { device = .SD6 if VERBOSE do fmt.printf("Detected SOUND_DEVICES from unquoted SOUND REPORT line index {}\n", line_number) } + if len(line)<15 do continue + if line[:13] == "SOUND REPORT," { + device = .SD8 + if VERBOSE do fmt.printf("Detected SOUND_DEVICES 8-series from SOUND REPORT with missing newline on line index {}\n", line_number) + } } if device == .UNSET { @@ -148,44 +156,76 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { // STAGE 2 -------------------------------------------------------------- // Measuring content for allocation - if device == .ZOOM { - output.column_count = 21 // Ugly magic number, could be fucked by firmware update - - // Padded for expanding info lines from unchanging columns - output.info_lines = make([]Info_Line, 2+output.column_count, context.temp_allocator) - output.info_line_count = 2 + + switch device { + case .ZOOM: + output.column_count = 21 // Ugly magic number, could be fucked by firmware update + + // Padded for expanding info lines from unchanging columns + output.info_lines = make([]Info_Line, 2+output.column_count, context.temp_allocator) + output.info_line_count = 2 + + output.row_count = strings.count(string(data), "\n") - 7 // Ugly magic number, could be fucked by firmware update + output.table = make([][]string, output.row_count, context.temp_allocator) + output.header = make([]string, output.column_count, context.temp_allocator) + for &row in output.table { + row = make([]string, output.column_count, context.temp_allocator) + } + case .SD6: + second_to_last_line := lines[len(lines)-2] + output.column_count = strings.count(second_to_last_line, ",") + count_stage : Stages = .TITLE + for line, l in lines { + switch count_stage { + case .TITLE: + if l == 1 { // Ugly magic number, could be fucked by firmware update + count_stage = .INFO + } + case .INFO: + if line == "," { + count_stage = .HEADER + continue + } else if len(line) > 2 { + output.info_line_count += 1 + } + case .HEADER: + if line == "" { + count_stage = .BODY + } + case .BODY: + if len(line)>2 { + output.row_count += 1 + } + } + } + output.info_lines = make([]Info_Line, output.info_line_count+output.column_count, context.temp_allocator) + output.header = make([]string, output.column_count, context.temp_allocator) + output.table = make([][]string, output.row_count, context.temp_allocator) + for &row in output.table { + row = make([]string, output.column_count, context.temp_allocator) + } - output.row_count = strings.count(string(data), "\n") - 7 // Ugly magic number, could be fucked by firmware update - output.table = make([][]string, output.row_count, context.temp_allocator) - output.header = make([]string, output.column_count, context.temp_allocator) - for &row in output.table { - row = make([]string, output.column_count, context.temp_allocator) - } - } else if device == .SD6 { - second_to_last_line := lines[len(lines)-2] - output.column_count = strings.count(second_to_last_line, ",") - count_stage : Stages = .TITLE - for line, l in lines { - switch count_stage { - case .TITLE: - if l == 1 { // Ugly magic number, could be fucked by firmware update - count_stage = .INFO - } - case .INFO: - if line == "," { - count_stage = .HEADER - continue - } else if len(line) > 2 { - output.info_line_count += 1 - } - case .HEADER: - if line == "" { - count_stage = .BODY - } - case .BODY: - if len(line)>2 { - output.row_count += 1 - } + case .SD8: + count_stage : Stages = .INFO + for line, l in lines { + #partial switch count_stage { + case .INFO: + if line == "," { + count_stage = .HEADER + continue + } else if len(line) > 2 { + output.info_line_count += 1 + } + case .HEADER: + if len(line) > 2 { + // Missing comma at the en in 8-series report, v therefore + 1 + output.column_count = strings.count(line, ",") + 1 + count_stage = .BODY + } + case .BODY: + if len(line)>2 { + output.row_count += 1 + } } } output.info_lines = make([]Info_Line, output.info_line_count+output.column_count, context.temp_allocator) @@ -194,10 +234,12 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { for &row in output.table { row = make([]string, output.column_count, context.temp_allocator) } + + case .UNSET: + unreachable() } - // STAGE 3 -------------------------------------------------------------- // Filling with data @@ -208,6 +250,107 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { stage : Stages = .TITLE #partial switch device { + case .SD8: + // .d8888b. 8888888b. .d8888b. + // d88P Y88b 888 "Y88b d88P Y88b + // Y88b. 888 888 Y88b. d88P + // "Y888b. 888 888 "Y88888" + // "Y88b. 888 888 .d8P""Y8b. + // "888 888 888 888 888 + // Y88b d88P 888 .d88P Y88b d88P + // "Y8888P" 8888888P" "Y8888P" + fmt.printf("Parsing [{}] as Sound Devices 8XX report, ", file_info.name) + if strings.contains(file_info.name, "_1.CSV") || strings.contains(file_info.name, "_2.CSV") { + output.title = file_info.name[7:len(file_info.name)-6] + } else { + output.title = file_info.name + } + fmt.printf("titled \"{}\".\n", output.title) + + info_line_index := 0 + body_line_index := 0 + for line, line_index in lines { + switch stage { + case .TITLE: + // Missing newline on 8-series means we get info on the title line + stage = .INFO + + line_elements := strings.split(line, ",") + if VERBOSE do fmt.printf(".INFO {}: {}\n", line_index, line_elements) + field := fmt.aprintf("{}:", line_elements[1], allocator=context.temp_allocator) + entry := line_elements[2] + output.info_lines[info_line_index].field = field + output.info_lines[info_line_index].entry = entry + info_line_index += 1 + + + case .INFO: + if line == "," { + stage = .HEADER + continue + } + line_elements := strings.split(line, ",") + if VERBOSE do fmt.printf(".INFO {}: {}\n", line_index, line_elements) + if line_elements[0] == "Date" { + if VERBOSE do fmt.printf("Skipping line {}, because it's the retarded date field on an 8-series\n", line_index) + output.info_line_count -= 1 + continue + } + field := fmt.aprintf("{}:", line_elements[0], allocator=context.temp_allocator) + entry := line_elements[1] + output.info_lines[info_line_index].field = field + output.info_lines[info_line_index].entry = entry + info_line_index += 1 + + + case .HEADER: + if line == "," { + continue // This is here because there are a bunch of lines that are just commas before the header + } else if len(line)>3 { + if VERBOSE do fmt.printf(".HEADER {}:", line_index) + // No trailing comma in the header?? + for element, e in strings.split(line, ",") { + if VERBOSE do fmt.printf(" {}", element) + + output.header[e] = element + if element[:3] == "Trk" { + if first_channel_index == -1 do first_channel_index = e + last_channel_index = e + output.header[e] = fmt.aprintf("Trk {}", e-first_channel_index+1, allocator=context.temp_allocator) + } + if element == "Start TC" { + output.tc_column_index = e + } + } + + if VERBOSE do fmt.printf("\n") + if VERBOSE do fmt.printf("first_channel_index: {}\n", first_channel_index) + if VERBOSE do fmt.printf("last_channel_index: {}\n", last_channel_index) + stage = .BODY + } + + + case .BODY: + if len(line) > 2 { + if VERBOSE do fmt.printf(".BODY {}:", line_index) + for element, e in strings.split(line, ",") { + if VERBOSE do fmt.printf(" {}", element) + entry : string = element + output.table[body_line_index][e] = entry + } + if VERBOSE do fmt.printf("\n") + body_line_index += 1 + } + + + } + } + + fmt.printf("\n") + + + + case .SD6: // .d8888b. 8888888b. .d8888b. // d88P Y88b 888 "Y88b d88P Y88b @@ -262,6 +405,7 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { if element[:4] == "Trk " { if first_channel_index == -1 do first_channel_index = e last_channel_index = e + // TODO: Rename track column with corrected numbers } if element == "Start TC" { output.tc_column_index = e -- cgit v1.2.1