From 3c018eab670be40ffd1841ad9946f5f555b4a76a Mon Sep 17 00:00:00 2001 From: cbdev Date: Mon, 25 Sep 2023 22:00:50 +0200 Subject: Refactor header parsing --- wavextract.c | 134 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 52 deletions(-) diff --git a/wavextract.c b/wavextract.c index 4192f64..137d1a0 100644 --- a/wavextract.c +++ b/wavextract.c @@ -61,6 +61,80 @@ static int usage(char* fn){ return EXIT_FAILURE; } +int wave_verify_riff(int fd, hdr_riff_t* hdr){ + if(read(fd, hdr, sizeof(hdr_riff_t)) != sizeof(hdr_riff_t)){ + fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); + return 1; + } + + if(memcmp(hdr->magic_riff, "RIFF", 4) || memcmp(hdr->magic_wave, "WAVE", 4)){ + fprintf(stderr, "Invalid RIFF/WAVE magic - probably not a WAVE file\n"); + return 1; + } + + fprintf(stderr, "RIFF chunk size: %d\n", hdr->size); + return 0; +} + +int wave_verify_fmt(int fd, hdr_fmt_t* hdr){ + uint16_t extra_data; + uint8_t skip_byte; + size_t n; + + if(read(fd, hdr, sizeof(hdr_fmt_t)) != sizeof(hdr_fmt_t)){ + fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); + return 1; + } + + if(memcmp(hdr->magic, "fmt ", 4)){ + fprintf(stderr, "Invalid format header magic - format probably incompatible\n"); + return 1; + } + + fprintf(stderr, "Format chunk size: %d\n", hdr->size); + fprintf(stderr, "Format: %d\n", hdr->fmt); + fprintf(stderr, "Channels: %d\n", hdr->channels); + fprintf(stderr, "Samplerate: %d\n", hdr->sample_rate); + fprintf(stderr, "Byterate: %d\n", hdr->byte_rate); + fprintf(stderr, "Align: %d\n", hdr->bitdepth); + fprintf(stderr, "Samplebits: %d\n", hdr->samplebits); + + if(hdr->fmt != 1){ + if(read(fd, &extra_data, 2) != 2){ + fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); + return 1; + } + } + else if(hdr->size > 16 /* length of fmt header as counted from after the size member */){ + fprintf(stderr, "Skipping %d additional header bytes:", hdr->size - 16); + for(n = 16; n < hdr->size; n++){ + if(read(fd, &skip_byte, 1) != 1){ + fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); + return 1; + } + fprintf(stderr, " %02X", skip_byte); + } + fprintf(stderr, "\n"); + } + + return 0; +} + +int wave_verify_data(int fd, hdr_data_t* hdr){ + if(read(fd, hdr, sizeof(hdr_data_t)) != sizeof(hdr_data_t)){ + fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); + return 1; + } + + if(memcmp(hdr->magic, "data", 4)){ + fprintf(stderr, "Invalid data magic\n"); + return 1; + } + + fprintf(stderr, "%d bytes of sample data in file\n", hdr->size); + return 0; +} + int main(int argc, char** argv){ size_t n; #ifdef _WIN32 @@ -79,53 +153,24 @@ int main(int argc, char** argv){ } hdr_riff_t riff; - if(read(source_fd, &riff, sizeof(riff)) != sizeof(riff)){ - close(source_fd); - fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); - return EXIT_FAILURE; - } + hdr_fmt_t fmt; + hdr_data_t data; - if(memcmp(riff.magic_riff, "RIFF", 4) || memcmp(riff.magic_wave, "WAVE", 4)){ + if(wave_verify_riff(source_fd, &riff)){ close(source_fd); - fprintf(stderr, "Invalid RIFF/WAVE magic\n"); return EXIT_FAILURE; } - fprintf(stderr, "Chunk size: %d\n", riff.size); - - hdr_fmt_t fmt; - uint16_t extra_data; - if(read(source_fd, &fmt, sizeof(fmt)) != sizeof(fmt)){ + if(wave_verify_fmt(source_fd, &fmt)){ close(source_fd); - fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); - return EXIT_FAILURE; + return EXIT_FAILURE; } - if(memcmp(fmt.magic, "fmt ", 4)){ + if(wave_verify_data(source_fd, &data)){ close(source_fd); - fprintf(stderr, "Invalid format magic\n"); return EXIT_FAILURE; } - fprintf(stderr, "Format chunk size: %d\n", fmt.size); - fprintf(stderr, "Format: %d\n", fmt.fmt); - fprintf(stderr, "Channels: %d\n", fmt.channels); - fprintf(stderr, "Samplerate: %d\n", fmt.sample_rate); - fprintf(stderr, "Byterate: %d\n", fmt.byte_rate); - fprintf(stderr, "Align: %d\n", fmt.bitdepth); - fprintf(stderr, "Samplebits: %d\n", fmt.samplebits); - - if(fmt.fmt != 1){ - read(source_fd, &extra_data, 2); - } - - if(fmt.fmt == 1 && fmt.size > 16){ - fprintf(stderr, "Skipping %d additional header bytes\n", fmt.size - 16); - for(n = 16; n < fmt.size; n++){ - read(source_fd, &extra_data, 1); - } - } - /* For now, just skip further analysis and bail on incompatible format */ if(fmt.samplebits != 16){ close(source_fd); @@ -133,25 +178,10 @@ int main(int argc, char** argv){ return EXIT_FAILURE; } - hdr_data_t data_header; - if(read(source_fd, &data_header, sizeof(data_header)) != sizeof(data_header)){ - close(source_fd); - fprintf(stderr, "Failed to read input data: %s\n", strerror(errno)); - return EXIT_FAILURE; - } - - if(memcmp(data_header.magic, "data", 4)){ - close(source_fd); - fprintf(stderr, "Invalid data magic\n"); - return EXIT_FAILURE; - } - - fprintf(stderr, "%d bytes of sample data in file\n", data_header.size); - uint16_t sample; uint8_t channel = 0; - for(n = 0; n < data_header.size / 2; n++){ + for(n = 0; n < data.size / 2; n++){ //read sample if(read(source_fd, &sample, 2) != 2){ close(source_fd); @@ -175,6 +205,6 @@ int main(int argc, char** argv){ } close(source_fd); - fprintf(stderr, "All done\n"); + fprintf(stderr, "Done, exported %ld frames of data %d channels, processed %ld samples\n", n, fmt.channels, fmt.channels * n); return EXIT_SUCCESS; } -- cgit v1.2.3