Initial import
authorAntonio Ospite <ospite@studenti.unina.it>
Tue, 23 Nov 2010 12:15:41 +0000 (13:15 +0100)
committerAntonio Ospite <ospite@studenti.unina.it>
Tue, 23 Nov 2010 12:15:41 +0000 (13:15 +0100)
Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
Makefile [new file with mode: 0644]
wav_header.c [new file with mode: 0644]
wav_header.py [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
index 0000000..cdd64a2
--- /dev/null
@@ -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 (executable)
index 0000000..0dedbcc
--- /dev/null
@@ -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)