summaryrefslogtreecommitdiff
path: root/riffprobe/riffprobe.c
diff options
context:
space:
mode:
Diffstat (limited to 'riffprobe/riffprobe.c')
-rw-r--r--riffprobe/riffprobe.c127
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;
}