summaryrefslogtreecommitdiff
path: root/js/riffwave.js
diff options
context:
space:
mode:
authorpommicket <leonardomtenenbaum@gmail.com>2016-07-01 17:43:58 -0400
committerpommicket <leonardomtenenbaum@gmail.com>2016-07-01 17:43:58 -0400
commitbe06edbcfd1213ea1658d36f8934493a92205aac (patch)
tree28dca6130833e3a770611961bc6559c08bed4161 /js/riffwave.js
Created pommicket.github.io
Diffstat (limited to 'js/riffwave.js')
-rw-r--r--js/riffwave.js130
1 files changed, 130 insertions, 0 deletions
diff --git a/js/riffwave.js b/js/riffwave.js
new file mode 100644
index 0000000..3c0b5e4
--- /dev/null
+++ b/js/riffwave.js
@@ -0,0 +1,130 @@
+/*
+ * RIFFWAVE.js v0.03 - Audio encoder for HTML5 <audio> elements.
+ * Copyleft 2011 by Pedro Ladaria <pedro.ladaria at Gmail dot com>
+ *
+ * Public Domain
+ *
+ * Changelog:
+ *
+ * 0.01 - First release
+ * 0.02 - New faster base64 encoding
+ * 0.03 - Support for 16bit samples
+ *
+ * Notes:
+ *
+ * 8 bit data is unsigned: 0..255
+ * 16 bit data is signed: −32,768..32,767
+ *
+ */
+
+var FastBase64 = {
+
+ chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
+ encLookup: [],
+
+ Init: function() {
+ for (var i=0; i<4096; i++) {
+ this.encLookup[i] = this.chars[i >> 6] + this.chars[i & 0x3F];
+ }
+ },
+
+ Encode: function(src) {
+ var len = src.length;
+ var dst = '';
+ var i = 0;
+ while (len > 2) {
+ n = (src[i] << 16) | (src[i+1]<<8) | src[i+2];
+ dst+= this.encLookup[n >> 12] + this.encLookup[n & 0xFFF];
+ len-= 3;
+ i+= 3;
+ }
+ if (len > 0) {
+ var n1= (src[i] & 0xFC) >> 2;
+ var n2= (src[i] & 0x03) << 4;
+ if (len > 1) n2 |= (src[++i] & 0xF0) >> 4;
+ dst+= this.chars[n1];
+ dst+= this.chars[n2];
+ if (len == 2) {
+ var n3= (src[i++] & 0x0F) << 2;
+ n3 |= (src[i] & 0xC0) >> 6;
+ dst+= this.chars[n3];
+ }
+ if (len == 1) dst+= '=';
+ dst+= '=';
+ }
+ return dst;
+ } // end Encode
+
+}
+
+FastBase64.Init();
+
+var RIFFWAVE = function(data) {
+
+ this.data = []; // Array containing audio samples
+ this.wav = []; // Array containing the generated wave file
+ this.dataURI = ''; // http://en.wikipedia.org/wiki/Data_URI_scheme
+
+ this.header = { // OFFS SIZE NOTES
+ chunkId : [0x52,0x49,0x46,0x46], // 0 4 "RIFF" = 0x52494646
+ chunkSize : 0, // 4 4 36+SubChunk2Size = 4+(8+SubChunk1Size)+(8+SubChunk2Size)
+ format : [0x57,0x41,0x56,0x45], // 8 4 "WAVE" = 0x57415645
+ subChunk1Id : [0x66,0x6d,0x74,0x20], // 12 4 "fmt " = 0x666d7420
+ subChunk1Size: 16, // 16 4 16 for PCM
+ audioFormat : 1, // 20 2 PCM = 1
+ numChannels : 1, // 22 2 Mono = 1, Stereo = 2...
+ sampleRate : 8000, // 24 4 8000, 44100...
+ byteRate : 0, // 28 4 SampleRate*NumChannels*BitsPerSample/8
+ blockAlign : 0, // 32 2 NumChannels*BitsPerSample/8
+ bitsPerSample: 8, // 34 2 8 bits = 8, 16 bits = 16
+ subChunk2Id : [0x64,0x61,0x74,0x61], // 36 4 "data" = 0x64617461
+ subChunk2Size: 0 // 40 4 data size = NumSamples*NumChannels*BitsPerSample/8
+ };
+
+ function u32ToArray(i) {
+ return [i&0xFF, (i>>8)&0xFF, (i>>16)&0xFF, (i>>24)&0xFF];
+ }
+
+ function u16ToArray(i) {
+ return [i&0xFF, (i>>8)&0xFF];
+ }
+
+ function split16bitArray(data) {
+ var r = [];
+ var j = 0;
+ var len = data.length;
+ for (var i=0; i<len; i++) {
+ r[j++] = data[i] & 0xFF;
+ r[j++] = (data[i]>>8) & 0xFF;
+ }
+ return r;
+ }
+
+ this.Make = function(data) {
+ if (data instanceof Array) this.data = data;
+ this.header.blockAlign = (this.header.numChannels * this.header.bitsPerSample) >> 3;
+ this.header.byteRate = this.header.blockAlign * this.sampleRate;
+ this.header.subChunk2Size = this.data.length * (this.header.bitsPerSample >> 3);
+ this.header.chunkSize = 36 + this.header.subChunk2Size;
+
+ this.wav = this.header.chunkId.concat(
+ u32ToArray(this.header.chunkSize),
+ this.header.format,
+ this.header.subChunk1Id,
+ u32ToArray(this.header.subChunk1Size),
+ u16ToArray(this.header.audioFormat),
+ u16ToArray(this.header.numChannels),
+ u32ToArray(this.header.sampleRate),
+ u32ToArray(this.header.byteRate),
+ u16ToArray(this.header.blockAlign),
+ u16ToArray(this.header.bitsPerSample),
+ this.header.subChunk2Id,
+ u32ToArray(this.header.subChunk2Size),
+ (this.header.bitsPerSample == 16) ? split16bitArray(this.data) : this.data
+ );
+ this.dataURI = 'data:audio/wav;base64,'+FastBase64.Encode(this.wav);
+ };
+
+ if (data instanceof Array) this.Make(data);
+
+}; // end RIFFWAVE