From fc9b734d6b8b054665897adf3efc4a15ac9605e9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 29 Jul 2002 21:38:43 +0000 Subject: [PATCH] parse out the cuepoint info --- tools/wav/wav.c | 281 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 209 insertions(+), 72 deletions(-) diff --git a/tools/wav/wav.c b/tools/wav/wav.c index cf4680a99..50660e176 100644 --- a/tools/wav/wav.c +++ b/tools/wav/wav.c @@ -47,12 +47,13 @@ typedef struct d_ltxt_s { typedef struct cue_s { d_chunk_t ck; - d_cue_t cue; + d_cue_t *cue; } cue_t; typedef struct format_s { d_chunk_t ck; d_format_t format; + char fdata[0]; } format_t; typedef struct ltxt_s { @@ -71,6 +72,12 @@ typedef struct data_s { char *data; } data_t; +typedef struct list_s { + d_chunk_t ck; + char name[4]; + d_chunk_t *chunks[0]; +} list_t; + #define SWITCH(name) switch (((name)[0] << 24) | ((name)[1] << 16) \ | ((name)[2] << 8) | (name)[3]) #define CASE(a,b,c,d) (((unsigned char)(a) << 24) \ @@ -103,7 +110,7 @@ read_data (FILE *f, int len) { void *data = malloc (len); - fread (data, 1, 1, f); + fread (data, 1, len, f); fseek (f, len & 1, SEEK_CUR); return data; } @@ -115,14 +122,16 @@ read_ltxt (FILE *f, int len, d_ltxt_t *ltxt) } void -read_adtl (FILE *f, int len) +read_adtl (dstring_t *list_buf, FILE *f, int len) { - d_chunk_t ck; + d_chunk_t ck, *chunk = 0; ltxt_t *ltxt; label_t *label; data_t *data; + list_t *list; int r; + list = (list_t *) list_buf->str; while (len) { r = fread (&ck, 1, sizeof (ck), f); if (!r) { @@ -130,12 +139,12 @@ read_adtl (FILE *f, int len) break; } len -= r; - printf (" '%4.4s' %6d\n", ck.name, ck.len); SWITCH (ck.name) { case CASE ('l','t','x','t'): ltxt = malloc (sizeof (ltxt_t)); ltxt->ck = ck; read_ltxt (f, ck.len, <xt->ltxt); + chunk = <xt->ck; break; case CASE ('l','a','b','l'): case CASE ('n','o','t','e'): @@ -143,113 +152,241 @@ read_adtl (FILE *f, int len) label->ck = ck; fread (&label->ofs, 1, 4, f); label->label = read_string (f, ck.len - 4); + chunk = &label->ck; break; default: data = malloc (sizeof (data)); data->ck = ck; data->data = read_data (f, ck.len); + chunk = &data->ck; break; } len -= ck.len + (ck.len & 1); + dstring_append (list_buf, (char *)&chunk, sizeof (chunk)); + list = (list_t *) list_buf->str; + chunk = 0; } + dstring_append (list_buf, (char *)&chunk, sizeof (chunk)); + list = (list_t *) list_buf->str; } -void -read_list (FILE *f, int len) +list_t * +read_list (d_chunk_t *ck, FILE *f, int len) { - d_chunk_t ck; - unsigned char name[4]; + d_chunk_t *chunk = 0; + dstring_t *list_buf; + list_t *list; int r; - len -= fread (name, 1, sizeof (name), f); - printf (" '%4.4s' %6d\n", name, len); + list_buf = dstring_new (); + list_buf->size = sizeof (list_t); + dstring_adjust (list_buf); + list = (list_t *)list_buf->str; + list->ck = *ck; + + len -= fread (list->name, 1, sizeof (list->name), f); while (len) { - SWITCH (name) { + SWITCH (list->name) { case CASE ('I','N','F','O'): - r = fread (&ck, 1, sizeof (ck), f); - if (!r) { - len = 0; - break; - } - len -= r; - printf (" '%4.4s' %6d\n", ck.name, ck.len); - SWITCH (ck.name) { - case CASE ('I','C','R','D'): - case CASE ('I','S','F','T'): - read_string (f, ck.len); - break; - default: - read_data (f, ck.len); - //fseek (f, ck.len + (ck.len & 1), SEEK_CUR); + { + data_t *data = malloc (sizeof (data_t)); + chunk = &data->ck; + r = fread (&data->ck, 1, sizeof (data->ck), f); + if (!r) { + len = 0; break; + } + len -= r; + SWITCH (data->ck.name) { + case CASE ('I','C','R','D'): + case CASE ('I','S','F','T'): + data->data = read_string (f, data->ck.len); + break; + default: + data->data = read_data (f, data->ck.len); + break; + } + len -= data->ck.len + (data->ck.len & 1); } - len -= ck.len + (ck.len & 1); break; case CASE ('a','d','t','l'): - read_adtl (f, len); + read_adtl (list_buf, f, len); len = 0; + break; default: - read_data (f, len); + { + data_t *data = malloc (sizeof (data_t)); + fread (&data->ck, 1, sizeof (data->ck), f); + data->data = read_data (f, data->ck.len); + len -= data->ck.len + sizeof (data->ck); + chunk = &data->ck; + } len = 0; break; } + if (chunk) { + dstring_append (list_buf, (char *)&chunk, sizeof (chunk)); + list = (list_t *) list_buf->str; + } + chunk = 0; } + dstring_append (list_buf, (char *)&chunk, sizeof (chunk)); + list = (list_t *) list_buf->str; + return list; } -void +d_cue_t * read_cue (FILE *f, int len) { - d_cue_t *cue = alloca (len); - d_cue_point_t *cp; - int i; + d_cue_t *cue = malloc (len); fread (cue, 1, len, f); - printf (" %d\n", cue->count); - for (i = 0, cp = cue->cue_points; i < cue->count; i++) { - printf (" %8x %6d %4.4s %d %d %6d\n", cp->name, cp->position, - cp->chunk, cp->chunk_start, cp->block_start, - cp->sample_offset); + + return cue; +} + +list_t * +read_riff (const char *filename) +{ + dstring_t *riff_buf; + list_t *riff = 0; + d_chunk_t *chunk = 0; + FILE *f = fopen (filename, "rb"); + d_chunk_t ck; + int file_len, len; + + if (f) { + riff_buf = dstring_new (); + riff_buf->size = sizeof (list_t); + dstring_adjust (riff_buf); + riff = (list_t *)riff_buf->str; + + fseek (f, 0, SEEK_END); + file_len = ftell (f); + fseek (f, 0, SEEK_SET); + + fread (&riff->ck, 1, sizeof (riff->ck), f); + fread (riff->name, 1, sizeof (riff->name), f); + while (fread (&ck, 1, sizeof (ck), f)) { + if (ck.len < 0x80000000) + len = ck.len; + else + len = file_len - ftell (f); + SWITCH (ck.name) { + case CASE ('c','u','e',' '): + { + cue_t *cue = malloc (sizeof (cue_t)); + cue->ck = ck; + cue->cue = read_cue (f, len); + chunk = &cue->ck; + } + break; + case CASE ('L','I','S','T'): + { + list_t *list; + list = read_list (&ck, f, len); + chunk = &list->ck; + } + break; + default: + { + data_t *data = malloc (sizeof (data_t)); + data->ck = ck; + data->data = read_data (f, len); + chunk = &data->ck; + } + break; + } + dstring_append (riff_buf, (char *)&chunk, sizeof (chunk)); + riff = (list_t *) riff_buf->str; + chunk = 0; + } + dstring_append (riff_buf, (char *)&chunk, sizeof (chunk)); + riff = (list_t *) riff_buf->str; + fclose (f); } + return riff; } int main (int argc, char **argv) { - while (*++argv) { - FILE *f = fopen (*argv, "rb"); - d_chunk_t ck; - char name[4]; - int file_len, len; - if (f) { - fseek (f, 0, SEEK_END); - file_len = ftell (f); - fseek (f, 0, SEEK_SET); - printf ("%s\n", *argv); - fread (&ck, 1, sizeof (ck), f); - printf ("'%4.4s' %d\n", ck.name, ck.len); - fread (name, 1, sizeof (name), f); - printf (" '%4.4s'\n", name); - while (fread (&ck, 1, sizeof (ck), f)) { - if (ck.len < 0x80000000) - len = ck.len; - else - len = file_len - ftell (f); - printf (" '%4.4s' %6d\n", ck.name, len); - SWITCH (ck.name) { - case CASE ('c','u','e',' '): - read_cue (f, len); - break; - case CASE ('L','I','S','T'): - read_list (f, len); - break; - default: - fseek (f, len + (len & 1), SEEK_CUR); - break; - } - } - fclose (f); + while (*++argv) { + list_t *riff = read_riff (*argv); + d_chunk_t **ck; + int sample_start, sample_count; + + if (!riff) { + fprintf (stderr, "couldn't read %s\n", *argv); + continue; } + sample_start = -1; + sample_count = -1; + for (ck = riff->chunks; *ck; ck++) { + SWITCH ((*ck)->name) { + case CASE ('c', 'u', 'e', ' '): + { + cue_t *cue = (cue_t *)*ck; + d_cue_t *dcue = cue->cue; + d_cue_point_t *cp = dcue->cue_points; + int i; + + for (i = 0; i < dcue->count; i++) + sample_start = cp[i].sample_offset; +#if 0 + printf ("cuepoint: %d %d %.4s %d %d %d\n", + cp[i].name, + cp[i].position, + cp[i].chunk, + cp[i].chunk_start, + cp[i].block_start, + cp[i].sample_offset); +#endif + } + break; + case CASE ('L','I','S','T'): + { + list_t *list = (list_t *)*ck; + SWITCH (list->name) { + case CASE ('a','d','t','l'): + { + d_chunk_t **ck; + for (ck = list->chunks; *ck; ck++) { + SWITCH ((*ck)->name) { + case CASE ('l', 't', 'x', 't'): + { + ltxt_t *ltxt = (ltxt_t *)*ck; + d_ltxt_t *dltxt = <xt->ltxt; + sample_count = dltxt->len; +#if 0 + printf ("ltxt: %d %d %4s %d %d %d %d\n", + dltxt->name, + dltxt->len, + dltxt->purpose, + dltxt->country, + dltxt->language, + dltxt->dialect, + dltxt->codepage); +#endif + } + break; + } + } + } + break; + } + } + break; + case CASE ('d','a','t','a'): +#if 0 + printf ("data: %d\n", (*ck)->len); +#endif + sample_count = (*ck)->len; + break; + } + } + printf ("%s: CUEPOINT=%d %d\n", *argv, sample_start, sample_count); } return 0; }