Skip to content

Instantly share code, notes, and snippets.

@phenyque
Last active December 19, 2021 20:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phenyque/0137d70cad0ccababfd9b7629ae1b5aa to your computer and use it in GitHub Desktop.
Save phenyque/0137d70cad0ccababfd9b7629ae1b5aa to your computer and use it in GitHub Desktop.
Extract raw sample data from .wav files
/*
* wav2raw
*
* Read .wav file and write only the signal values into a .raw file
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DESC_SIZE 4
#define COPY_SIZE 1024
int32_t big_endian_int(unsigned char *buffer);
void usage(void);
const char riff_hdr[DESC_SIZE + 1] = {'R', 'I', 'F', 'F', '\0'};
const char wave_hdr[DESC_SIZE + 1] = {'W', 'A', 'V', 'E', '\0'};
const char data_hdr[DESC_SIZE + 1] = {'d', 'a', 't', 'a', '\0'};
int main(int argc, char **argv) {
int32_t file_size;
unsigned char buf[DESC_SIZE + 1];
FILE *in_file, *out_file;
if (argc != 3) {
usage();
exit(-1);
}
if ((in_file = fopen(argv[1], "rb")) == NULL) {
printf("Can not open input file '%s'\n", argv[1]);
exit(-1);
}
/* assert RIFF header */
fread(buf, 1, DESC_SIZE, in_file);
if (strcmp((char *)buf, riff_hdr)) {
printf("Invalid RIFF header in input wav file: %s\n", buf);
exit(-1);
}
/* read file size */
fread(buf, 1, DESC_SIZE, in_file);
file_size = big_endian_int(buf);
printf("File size: %d\n", file_size);
/* assert WAVE header */
fread(buf, 1, DESC_SIZE, in_file);
if (strcmp((char *)buf, wave_hdr)) {
printf("Invalid WAVE header in input wav file: %s\n", buf);
exit(-1);
}
if ((out_file = fopen(argv[2], "wb")) == NULL) {
printf("Can not open output file '%s'\n", argv[2]);
exit(-1);
}
/* skip chunks and copy only data chunk content to raw file */
while (fread(buf, 1, DESC_SIZE, in_file)) {
int is_data_chunk;
int32_t chunk_size;
printf("Descriptor: %s, ", buf);
is_data_chunk = !strcmp((char *)buf, data_hdr);
fread(buf, 1, DESC_SIZE, in_file);
chunk_size = big_endian_int(buf);
printf("size: %d\n", chunk_size);
if (is_data_chunk) {
int32_t num_blocks;
uint16_t trailing_bytes;
unsigned char copy_buffer[COPY_SIZE];
printf("Copy data chunk...\n");
num_blocks = chunk_size / COPY_SIZE;
trailing_bytes = chunk_size % COPY_SIZE;
/* blockwise copy <chunk_size> bytes into the .raw file */
for (int32_t i = 0; i < num_blocks; i++) {
fread(&copy_buffer, 1, COPY_SIZE, in_file);
fwrite(&copy_buffer, 1, COPY_SIZE, out_file);
}
fread(&copy_buffer, 1, trailing_bytes, in_file);
fwrite(&copy_buffer, 1, trailing_bytes, out_file);
}
else {
/* skip all other chunks */
fseek(in_file, chunk_size, SEEK_CUR);
}
}
return 0;
}
int32_t big_endian_int(unsigned char *buffer) {
return *buffer | (*(buffer + 1) << 8) | (*(buffer + 2) << 16) | (*(buffer + 3) << 24);
}
void usage(void) {
printf("\nwav2raw - Convert wav files to raw (no header)\n");
printf("Usage:\n");
printf("wav2raw INPUTWAV OUTPUTRAW\n\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment