From c494c8415ef810a1ec1db9ee2d0905096dd77aae Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Tue, 23 Nov 2010 13:15:41 +0100 Subject: [PATCH 1/1] Initial import Signed-off-by: Antonio Ospite --- Makefile | 8 +++ wav_header.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ wav_header.py | 61 +++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 Makefile create mode 100644 wav_header.c create mode 100755 wav_header.py diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..37b1dd6 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +CFLAGS = -Wall -Wextra -pedantic -pedantic-errors -std=c99 -D_BSD_SOURCE + +EXECUTABLE = wav_header + +$(EXECUTABLE): $(EXECUTABLE).o + +clean: + rm -f *.o ~* $(EXECUTABLE) diff --git a/wav_header.c b/wav_header.c new file mode 100644 index 0000000..cdd64a2 --- /dev/null +++ b/wav_header.c @@ -0,0 +1,156 @@ +/* + * wav_header - write the header of a wav file + * + * Copyright (C) 2010 Antonio Ospite + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +#include +#include +#include +#include + +#include + +/* This is the logical arrangement of the struct but we are splitting it + * because it is more easy to handle the variable length extradata + * + * strongly inspired by http://www.mpg123.de/mpg123/mpg123/wav.c + */ +#if 0 +struct _RIFF { + char riffheader[4]; + uint32_t WAVElen; + struct _WAVE { + char fmtheader[8]; + uint32_t fmtlen; + struct _fmt { + uint16_t wFormatTag; + uint16_t nChannels; + uint32_t nSamplesPerSec; + uint32_t nAvgBytesPerSec; + uint16_t nBlockAlign; + uint16_t wBitsPerSample; + uint16_t cbSize; /* cbSize = sizeof(extardata) */ + uint8_t extradata[]; + } fmt; + struct _data + { + char dataheader[4]; + uint32_t datalen; + } data; + /* from here you insert your PCM data */ + } WAVE; +}; +#endif + +struct fmt { + uint16_t wFormatTag; + uint16_t nChannels; + uint32_t nSamplesPerSec; + uint32_t nAvgBytesPerSec; + uint16_t nBlockAlign; + uint16_t wBitsPerSample; + uint16_t cbSize; + uint8_t extradata[]; +} __attribute__((__packed__)); + +struct WAVE { + char fmtheader[8]; + uint32_t fmtlen; +} __attribute__((__packed__)); + +struct RIFF { + char riffheader[4]; + uint32_t WAVElen; +}; + +struct data { + char dataheader[4]; + uint32_t datalen; +}; + +struct extradata { + uint16_t len; /* same size as fmt.cbSize */ + uint8_t data[]; +}; + + +void write_wav_header(FILE *file, struct fmt *format, + struct extradata *extradata, unsigned data_len) +{ + struct RIFF r = { + { 'R','I','F','F' } , + 0 + }; + + struct WAVE w = { + { 'W','A','V','E','f','m','t',' ' }, + 0 + }; + + struct data d = { + { 'd','a','t','a' }, + 0 + }; + + format->cbSize = extradata->len; + w.fmtlen = sizeof(*format) + format->cbSize; + r.WAVElen = sizeof(w) + w.fmtlen + sizeof(d); + d.datalen = data_len; + + /* RIFF */ + fwrite(&r.riffheader, 1, 4, file); + fwrite(&htole32(r.WAVElen), 4, 1, file); + + /* WAVE */ + fwrite(&w.fmtheader, 1, 8, file); + fwrite(&htole32(w.fmtlen), 4, 1, file); + + /* fmt */ + fwrite(&htole16(format->wFormatTag), 2, 1, file); + fwrite(&htole16(format->nChannels), 2, 1, file); + fwrite(&htole32(format->nSamplesPerSec), 4, 1, file); + fwrite(&htole32(format->nAvgBytesPerSec), 4, 1, file); + fwrite(&htole16(format->nBlockAlign), 2, 1, file); + fwrite(&htole16(format->wBitsPerSample), 2, 1, file); + fwrite(&htole16(format->cbSize), 2, 1, file); + + /* extradata */ + fwrite(extradata->data, 1, extradata->len, file); + + /* data */ + fwrite(&d.dataheader, 1, 4, file); + fwrite(&htole32(d.datalen), 4, 1, file); +} + +int main(void) +{ + struct fmt format = { + .wFormatTag = 0x161, + .nChannels = 2, + .nSamplesPerSec = 48000, + .nAvgBytesPerSec = 192000 / 8, + .wBitsPerSample = 16, + .nBlockAlign = 8192, + .cbSize = 0, + }; + + static struct extradata codec_private_data = { + .len = 10, + .data = "\x00\x88\x00\x00\x0f\x00\x00\x00\x00\x00", + }; + + unsigned data_len; + + data_len = 70680576; + + write_wav_header(stdout, &format, &codec_private_data, data_len); + + return 0; +} diff --git a/wav_header.py b/wav_header.py new file mode 100755 index 0000000..0dedbcc --- /dev/null +++ b/wav_header.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# wav_header - write the header of a wav file +# +# Copyright (C) 2010 Antonio Ospite +# +# This program is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. + +import sys +import struct + +def hexstring_to_bytes(hex_string): + res = "" + for i in range(0, len(hex_string), 2): + res += chr(int(hex_string[i:i+2], 16)) + + return res + +def write_wav_header(out_file, fmt, codec_private_data, data_len): + + extradata = hexstring_to_bytes(codec_private_data) + + fmt['cbSize'] = len(extradata) + fmt_len = 18 + fmt['cbSize'] + wave_len = len("WAVEfmt ") + 4 + fmt_len + len('data') + 4 + + out_file.write("RIFF") + out_file.write(struct.pack('