From c494c8415ef810a1ec1db9ee2d0905096dd77aae Mon Sep 17 00:00:00 2001
From: Antonio Ospite <ospite@studenti.unina.it>
Date: Tue, 23 Nov 2010 13:15:41 +0100
Subject: [PATCH] Initial import

Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
---
 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 <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;
+}
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 <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)
-- 
2.1.4