diff options
author | pommicket <leonardomtenenbaum@gmail.com> | 2016-07-01 17:43:58 -0400 |
---|---|---|
committer | pommicket <leonardomtenenbaum@gmail.com> | 2016-07-01 17:43:58 -0400 |
commit | be06edbcfd1213ea1658d36f8934493a92205aac (patch) | |
tree | 28dca6130833e3a770611961bc6559c08bed4161 /js/riffwave.js |
Created pommicket.github.io
Diffstat (limited to 'js/riffwave.js')
-rw-r--r-- | js/riffwave.js | 130 |
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 |