aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordvdli <dvdli@google.com>2021-06-29 18:53:23 +0800
committerdvdli <dvdli@google.com>2021-06-29 18:53:23 +0800
commita840dee85646a4e6330e9a2921a7dece619e1020 (patch)
treea46268107ea24419f3314b2352ba570e2b5a812c
parent496e653335d27557bbd1f795b1eacd2948ab192a (diff)
refactoring: add a wave-file parsing function
-rw-r--r--utils/tinyplay.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/utils/tinyplay.c b/utils/tinyplay.c
index 96d0f60..3c8c3bf 100644
--- a/utils/tinyplay.c
+++ b/utils/tinyplay.c
@@ -127,6 +127,48 @@ static bool signed_pcm_bits_to_format(int bits)
}
}
+static int parse_wave_file(struct ctx *ctx, const char *filename)
+{
+ if (fread(&ctx->wave_header, sizeof(ctx->wave_header), 1, ctx->file) != 1){
+ fprintf(stderr, "error: '%s' does not contain a riff/wave header\n", filename);
+ return -1;
+ }
+
+ if (ctx->wave_header.riff_id != ID_RIFF || ctx->wave_header.wave_id != ID_WAVE) {
+ fprintf(stderr, "error: '%s' is not a riff/wave file\n", filename);
+ return -1;
+ }
+
+ bool more_chunks = true;
+ do {
+ if (fread(&ctx->chunk_header, sizeof(ctx->chunk_header), 1, ctx->file) != 1) {
+ fprintf(stderr, "error: '%s' does not contain a data chunk\n", filename);
+ return -1;
+ }
+ switch (ctx->chunk_header.id) {
+ case ID_FMT:
+ if (fread(&ctx->chunk_fmt, sizeof(ctx->chunk_fmt), 1, ctx->file) != 1) {
+ fprintf(stderr, "error: '%s' has incomplete format chunk\n", filename);
+ return -1;
+ }
+ /* If the format header is larger, skip the rest */
+ if (ctx->chunk_header.sz > sizeof(ctx->chunk_fmt)) {
+ fseek(ctx->file, ctx->chunk_header.sz - sizeof(ctx->chunk_fmt), SEEK_CUR);
+ }
+ break;
+ case ID_DATA:
+ /* Stop looking for chunks */
+ more_chunks = false;
+ break;
+ default:
+ /* Unknown chunk, skip bytes */
+ fseek(ctx->file, ctx->chunk_header.sz, SEEK_CUR);
+ }
+ } while (more_chunks);
+
+ return 0;
+}
+
static int ctx_init(struct ctx* ctx, struct cmd *cmd)
{
unsigned int bits = cmd->bits;
@@ -149,44 +191,10 @@ static int ctx_init(struct ctx* ctx, struct cmd *cmd)
}
if (is_wave_file(cmd->filetype)) {
- if (fread(&ctx->wave_header, sizeof(ctx->wave_header), 1, ctx->file) != 1){
- fprintf(stderr, "error: '%s' does not contain a riff/wave header\n", cmd->filename);
- fclose(ctx->file);
- return -1;
- }
- if ((ctx->wave_header.riff_id != ID_RIFF) ||
- (ctx->wave_header.wave_id != ID_WAVE)) {
- fprintf(stderr, "error: '%s' is not a riff/wave file\n", cmd->filename);
+ if (parse_wave_file(ctx, cmd->filename) != 0) {
fclose(ctx->file);
return -1;
}
- unsigned int more_chunks = 1;
- do {
- if (fread(&ctx->chunk_header, sizeof(ctx->chunk_header), 1, ctx->file) != 1){
- fprintf(stderr, "error: '%s' does not contain a data chunk\n", cmd->filename);
- fclose(ctx->file);
- return -1;
- }
- switch (ctx->chunk_header.id) {
- case ID_FMT:
- if (fread(&ctx->chunk_fmt, sizeof(ctx->chunk_fmt), 1, ctx->file) != 1){
- fprintf(stderr, "error: '%s' has incomplete format chunk\n", cmd->filename);
- fclose(ctx->file);
- return -1;
- }
- /* If the format header is larger, skip the rest */
- if (ctx->chunk_header.sz > sizeof(ctx->chunk_fmt))
- fseek(ctx->file, ctx->chunk_header.sz - sizeof(ctx->chunk_fmt), SEEK_CUR);
- break;
- case ID_DATA:
- /* Stop looking for chunks */
- more_chunks = 0;
- break;
- default:
- /* Unknown chunk, skip bytes */
- fseek(ctx->file, ctx->chunk_header.sz, SEEK_CUR);
- }
- } while (more_chunks);
config->channels = ctx->chunk_fmt.num_channels;
config->rate = ctx->chunk_fmt.sample_rate;
bits = ctx->chunk_fmt.bits_per_sample;