diff options
| author | Hunter Kvalevog <hunter@kvog.sh> | 2026-09-22 21:17:51 -0500 |
|---|---|---|
| committer | Hunter Kvalevog <hunter@kvog.sh> | 2026-09-22 21:17:51 -0500 |
| commit | 5457f377967b3fc910d98c138b988c58f6462aa5 (patch) | |
| tree | 6fc0fc8ef982d76d959b5719abd568ee6a5c791f /riffprobe/riffprobe.c | |
| parent | 3fea2a42083c6c82f8511e671f1955b447774328 (diff) | |
riffprobe: rewrite and simplify
Diffstat (limited to 'riffprobe/riffprobe.c')
| -rw-r--r-- | riffprobe/riffprobe.c | 127 |
1 files changed, 20 insertions, 107 deletions
diff --git a/riffprobe/riffprobe.c b/riffprobe/riffprobe.c index 100b2fa..29918df 100644 --- a/riffprobe/riffprobe.c +++ b/riffprobe/riffprobe.c @@ -1,10 +1,11 @@ // ================================================================================================ -// Basic RIFF/WAVE file traversal. Does not decode media data. +// Basic RIFF/WAVE file traversal. Does not do any real parsing. // // ref: https://mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf // // Changelog: // 9/20/2026: Initial release +// 9/22/2026: Can now accept multiple files // // License: // SPDX-License-Identifier: 0BSD @@ -44,29 +45,6 @@ static void die(const char *fmt, ...) exit(1); } -typedef struct Chunk Chunk; -struct Chunk -{ - uint32_t id; - uint32_t size; -}; - -// WAVE chunks -typedef struct WAVE_Fmt WAVE_Fmt; -struct WAVE_Fmt -{ - uint16_t fmt_tag; - uint16_t channels; - uint32_t samples_per_sec; - uint32_t avg_bytes_per_sec; - uint16_t block_align; -}; - -static bool read_chunk(FILE *fp, Chunk *chunk) -{ - return fread(chunk, sizeof(Chunk), 1, fp) == 1; -} - static const char *unfourcc(uint32_t id) { static char b[5] = { 0 }; @@ -77,102 +55,37 @@ static const char *unfourcc(uint32_t id) return b; } -static bool match_id(uint32_t id, const char *fourcc) -{ - const char *id_fourcc = unfourcc(id); - for (int i = 0; i < 4; ++i) - { - if (tolower(id_fourcc[i]) != tolower(fourcc[i])) - return false; - } - return true; -} - -static uint32_t pad_size(uint32_t size) -{ - if (size % 2 != 0) - return size + 1; - return size; -} - int main(int argc, const char **argv) { if (argc < 2) die("no file"); - FILE* fp = fopen(argv[1], "rb"); - if (!fp) - die("failed to open file: %s", strerror(errno)); - - fseek(fp, 0, SEEK_END); - size_t flen = ftell(fp); - fseek(fp, 0, SEEK_SET); - - Chunk root; - if (!read_chunk(fp, &root) || !match_id(root.id, "RIFF")) - die("unsupported or malformed file"); - if (root.size + sizeof(Chunk) != flen) - printf("file length mismatch\n"); - - uint32_t riff_type = 0; - fread(&riff_type, sizeof(riff_type), 1, fp); - printf("type: %s\n", unfourcc(riff_type)); - - Chunk chunk; - while (read_chunk(fp, &chunk)) + for (int i = 1; i < argc; ++i) { - size_t next_pos = ftell(fp) + pad_size(chunk.size); - printf("chunk: %s\n", unfourcc(chunk.id)); - if (match_id(riff_type, "WAVE") && match_id(chunk.id, "FMT ")) - { - WAVE_Fmt fmt; - fread(&fmt, sizeof(fmt), 1, fp); + printf("%s:\n", argv[i]); - printf(" fmt category: %d\n", fmt.fmt_tag); - printf(" channels: %d\n", fmt.channels); - printf(" sample rate: %d\n", fmt.samples_per_sec); - } - if (match_id(riff_type, "WAVE") && match_id(chunk.id, "FACT")) { - uint32_t file_size = 0; - fread(&file_size, sizeof(file_size), 1, fp); - - printf(" file size: %d\n", file_size); - } - if (match_id(chunk.id, "LIST")) { - uint32_t list_type = 0; - fread(&list_type, sizeof(list_type), 1, fp); + FILE* fp = fopen(argv[i], "rb"); + if (!fp) + die("failed to open file: %s", strerror(errno)); - printf(" list type: %s\n", unfourcc(list_type)); + uint8_t buf[256]; - size_t list_start = ftell(fp); - size_t list_end = list_start + chunk.size - sizeof(list_type); + if (fread(buf, 1, 12, fp) != 12) + return 1; - Chunk subchunk; - while ((size_t)ftell(fp) < list_end && read_chunk(fp, &subchunk)) - { - size_t next_sub_pos = ftell(fp) + pad_size(subchunk.size); - printf(" subchunk: %s\n", unfourcc(subchunk.id)); + if (memcmp(buf, "RIFF", 4) || memcmp(buf + 8, "WAVE", 4)) + die("Invalid file"); - if (match_id(subchunk.id, "IART") || - match_id(subchunk.id, "IGNR") || - match_id(subchunk.id, "IPRD") || - match_id(subchunk.id, "ISFT")) - { - char buf[1024] = { 0 }; - size_t len = sizeof(buf) - 1; - if (subchunk.size < len) - len = subchunk.size; - fread(buf, len, 1, fp); - printf(" data: %s\n", buf); - } - - fseek(fp, next_sub_pos, SEEK_SET); - } + while (!feof(fp)) + { + if (fread(buf, 1, 8, fp) != 8) + break; + uint32_t tag = *(uint32_t *)buf; + uint32_t size = *(uint32_t *)(buf + 4); + printf(" %s\n", unfourcc(tag)); + fseek(fp, size, SEEK_CUR); } - fseek(fp, next_pos, SEEK_SET); } - fclose(fp); - return 0; } |