(function(self) { var min = Math.min, max = Math.max; var setString = function(view, offset, str) { var len = str.length; for (var i = 0; i < len; ++i) view.setUint8(offset + i, str.charCodeAt(i)); }; var Encoder = function(sampleRate, numChannels) { this.sampleRate = sampleRate; this.numChannels = numChannels; this.numSamples = 0; this.dataViews = []; }; Encoder.prototype.encode = function(buffer) { var len = 1024; this.dataViews.push(buffer); this.numSamples += len; }; Encoder.prototype.finish = function(mimeType) { var dataSize = this.numChannels * this.numSamples * 2, view = new DataView(new ArrayBuffer(44)); setString(view, 0, 'RIFF'); view.setUint32(4, 36 + dataSize, true); setString(view, 8, 'WAVE'); setString(view, 12, 'fmt '); view.setUint32(16, 16, true); view.setUint16(20, 1, true); view.setUint16(22, this.numChannels, true); view.setUint32(24, this.sampleRate, true); view.setUint32(28, this.sampleRate * 4, true); view.setUint16(32, this.numChannels * 2, true); view.setUint16(34, 16, true); setString(view, 36, 'data'); view.setUint32(40, dataSize, true); this.dataViews.unshift(view); var blob = new Blob(this.dataViews, { type: 'audio/wav' }); this.cleanup(); return blob; }; Encoder.prototype.cancel = Encoder.prototype.cleanup = function() { delete this.dataViews; }; self.WavAudioEncoder = Encoder; })(self);