From bca0504a30158ca2dcee3eebefb4bd6c1d23a3bb Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Thu, 7 Jan 2021 22:57:14 +0200 Subject: [PATCH] wave: Introduce parse_wave header This parses a canonical WAVE header and fills in informationlike channels, rate and format. In tinycompress, we use canonical WAVE format described here: http://soundfile.sapp.org/doc/WaveFormat/ A WAVE file is often just a RIFF file with a single "WAVE" chunk which consists of two sub-chunks -- a "fmt " chunk specifying the data format and a "data" chunk containing the actual sample data. Signed-off-by: Daniel Baluta --- include/tinycompress/tinywave.h | 2 ++ src/utils/wave.c | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/tinycompress/tinywave.h b/include/tinycompress/tinywave.h index ac128e5..619cb8d 100644 --- a/include/tinycompress/tinywave.h +++ b/include/tinycompress/tinywave.h @@ -38,4 +38,6 @@ void init_wave_header(struct wave_header *header, uint16_t channels, uint32_t rate, uint16_t samplebits); void size_wave_header(struct wave_header *header, uint32_t size); +int parse_wave_header(struct wave_header *header, unsigned int *channels, + unsigned int *rate, unsigned int *format); #endif diff --git a/src/utils/wave.c b/src/utils/wave.c index 23691fc..a74149a 100644 --- a/src/utils/wave.c +++ b/src/utils/wave.c @@ -5,8 +5,10 @@ // // Copyright 2021 NXP +#include #include #include +#include #include "tinycompress/tinywave.h" @@ -50,3 +52,43 @@ void size_wave_header(struct wave_header *header, uint32_t size) sizeof(header->riff.chunk) + size; header->data.chunk.size = size; } + +int parse_wave_header(struct wave_header *header, unsigned int *channels, + unsigned int *rate, unsigned int *format) +{ + if (strncmp(header->riff.chunk.desc, "RIFF", 4) != 0) { + fprintf(stderr, "RIFF magic not found\n"); + return -1; + } + + if (strncmp(header->riff.format, "WAVE", 4) != 0) { + fprintf(stderr, "WAVE magic not found\n"); + return -1; + } + + if (strncmp(header->fmt.chunk.desc, "fmt", 3) != 0) { + fprintf(stderr, "FMT section not found"); + return -1; + } + + *channels = header->fmt.channels; + *rate = header->fmt.rate; + + switch(header->fmt.samplebits) { + case 8: + *format = SNDRV_PCM_FORMAT_U8; + break; + case 16: + *format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 32: + *format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + fprintf(stderr, "Unsupported sample bits %d\n", + header->fmt.samplebits); + return -1; + } + + return 0; +} -- 2.47.3