--- /dev/null
+/*
+ * wav_header - write the header of a wav file
+ *
+ * Copyright (C) 2010 Antonio Ospite <ospite@studenti.unina.it>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <endian.h>
+
+/* 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;
+}
--- /dev/null
+#!/usr/bin/env python
+#
+# wav_header - write the header of a wav file
+#
+# Copyright (C) 2010 Antonio Ospite <ospite@studenti.unina.it>
+#
+# 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('<L', wave_len))
+ out_file.write("WAVEfmt ")
+ out_file.write(struct.pack('<L', fmt_len))
+ out_file.write(struct.pack('<H', fmt['wFormatTag']))
+ out_file.write(struct.pack('<H', fmt['nChannels']))
+ out_file.write(struct.pack('<L', fmt['nSamplesPerSec']))
+ out_file.write(struct.pack('<L', fmt['nAvgBytesPerSec']))
+ out_file.write(struct.pack('<H', fmt['nBlockAlign']))
+ out_file.write(struct.pack('<H', fmt['wBitsPerSample']))
+ out_file.write(struct.pack('<H', fmt['cbSize']))
+ out_file.write(extradata)
+ out_file.write("data")
+ out_file.write(struct.pack('<L', data_len))
+
+if __name__ == "__main__":
+
+ codec_private_data = "008800000f0000000000"
+
+ fmt = {}
+ fmt['wFormatTag'] = 0x161
+ fmt['nChannels'] = 2
+ fmt['nSamplesPerSec'] = 48000
+ fmt['nAvgBytesPerSec'] = 192000 / 8
+ fmt['wBitsPerSample'] = 16
+ fmt['nBlockAlign'] = 8192
+ fmt['cbSize'] = 0
+
+ data_len = 70680576
+
+ write_wav_header(sys.stdout, fmt, codec_private_data, data_len)