(
function
(f){
if
(typeof exports===
"object"
&&typeof module!==
"undefined"
){module.exports=f()}
else
if
(typeof define===
"function"
&&define.amd){define([],f)}
else
{
var
g;
if
(typeof window!==
"undefined"
){g=window}
else
if
(typeof
global
!==
"undefined"
){g=
global
}
else
if
(typeof self!==
"undefined"
){g=self}
else
{g=this}g.Recorder = f()}})(
function
(){
var
define,module,exports;
return
(
function
e(t,n,r){
function
s(o,u){
if
(!n[o]){
if
(!t[o]){
var
a=typeof
require
==
"function"
&&
require
;
if
(!u&&a)
return
a(o,!0);
if
(i)
return
i(o,!0);
var
f=
new
Error(
"Cannot find module '"
+o+
"'"
);
throw
f.code=
"MODULE_NOT_FOUND"
,f}
var
l=n[o]={exports:{}};t[o][0].call(l.exports,
function
(e){
var
n=t[o][1][e];
return
s(n?n:e)},l,l.exports,e,t,n,r)}
return
n[o].exports}
var
i=typeof
require
==
"function"
&&
require
;
for
(
var
o=0;o<r.length;o++)s(r[o]);
return
s})({1:[
function
(
require
,module,exports){
"use strict"
;
module.exports =
require
(
"./recorder"
).Recorder;
},{
"./recorder"
:2}],2:[
function
(
require
,module,exports){
'
use
strict';
var
_createClass = (
function
() {
function
defineProperties(target, props) {
for
(
var
i = 0; i < props.length; i++) {
var
descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;
if
(
"value"
in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}
return
function
(Constructor, protoProps, staticProps) {
if
(protoProps) defineProperties(Constructor.prototype, protoProps);
if
(staticProps) defineProperties(Constructor, staticProps);
return
Constructor;
};
})();
Object.defineProperty(exports,
"__esModule"
, {
value: true
});
exports.Recorder = undefined;
var
_inlineWorker =
require
('inline-worker');
var
_inlineWorker2 = _interopRequireDefault(_inlineWorker);
function
_interopRequireDefault(obj) {
return
obj && obj.__esModule ? obj : {
default
: obj };
}
function
_classCallCheck(instance, Constructor) {
if
(!(instance
instanceof
Constructor)) {
throw
new
TypeError(
"Cannot call a class as a function"
);
}
}
var
Recorder = exports.Recorder = (
function
() {
function
Recorder(source, cfg) {
var
_this = this;
_classCallCheck(this, Recorder);
this.config = {
bufferLen: 4096,
numChannels: 2,
mimeType: 'audio_pcm/wav'
};
this.recording = false;
this.callbacks = {
getBuffer: [],
exportWAV: []
};
Object.assign(this.config, cfg);
this.context = source.context;
this.node = (this.context.createScriptProcessor || this.context.createJavaScriptNode).call(this.context, this.config.bufferLen, this.config.numChannels, this.config.numChannels);
this.node.onaudioprocess =
function
(e) {
if
(!_this.recording)
return
;
var
buffer = [];
for
(
var
channel = 0; channel < _this.config.numChannels; channel++) {
buffer.push(e.inputBuffer.getChannelData(channel));
}
_this.worker.postMessage({
command: 'record',
buffer: buffer
});
};
source.connect(this.node);
this.node.connect(this.context.destination);
var
self = {};
this.worker =
new
_inlineWorker2.
default
(
function
() {
var
recLength = 0,
recBuffers = [],
sampleRate = undefined,
numChannels = undefined;
self.onmessage =
function
(e) {
switch
(e.data.command) {
case
'init':
init(e.data.config);
break
;
case
'record':
record(e.data.buffer);
break
;
case
'exportWAV':
exportWAV(e.data.type);
break
;
case
'getBuffer':
getBuffer();
break
;
case
'clear':
clear();
break
;
}
};
function
init(config) {
sampleRate = config.sampleRate;
numChannels = config.numChannels;
initBuffers();
}
function
record(inputBuffer) {
for
(
var
channel = 0; channel < numChannels; channel++) {
recBuffers[channel].push(inputBuffer[channel]);
}
recLength += inputBuffer[0].length;
}
function
exportWAV(type) {
var
buffers = [];
for
(
var
channel = 0; channel < numChannels; channel++) {
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
var
interleaved = undefined;
if
(numChannels === 2) {
interleaved = interleave(buffers[0], buffers[1]);
}
else
{
interleaved = buffers[0];
}
var
dataview = encodeWAV(interleaved);
var
audioBlob =
new
Blob([dataview], { type: type });
self.postMessage({ command: 'exportWAV', data: audioBlob });
}
function
getBuffer() {
var
buffers = [];
for
(
var
channel = 0; channel < numChannels; channel++) {
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
self.postMessage({ command: 'getBuffer', data: buffers });
}
function
clear() {
recLength = 0;
recBuffers = [];
initBuffers();
}
function
initBuffers() {
for
(
var
channel = 0; channel < numChannels; channel++) {
recBuffers[channel] = [];
}
}
function
mergeBuffers(recBuffers, recLength) {
var
result =
new
Float32Array(recLength);
var
offset = 0;
for
(
var
i = 0; i < recBuffers.length; i++) {
result.set(recBuffers[i], offset);
offset += recBuffers[i].length;
}
return
result;
}
function
interleave(inputL, inputR) {
var
length = inputL.length + inputR.length;
var
result =
new
Float32Array(length);
var
index = 0,
inputIndex = 0;
while
(index < length) {
result[index++] = inputL[inputIndex];
result[index++] = inputR[inputIndex];
inputIndex++;
}
return
result;
}
function
floatTo16BitPCM(output, offset, input) {
for
(
var
i = 0; i < input.length; i++, offset += 2) {
var
s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
}
function
writeString(view, offset, string) {
for
(
var
i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
function
encodeWAV(samples) {
var
buffer =
new
ArrayBuffer(44 + samples.length * 2);
var
view =
new
DataView(buffer);
writeString(view, 0, 'RIFF');
view.setUint32(4, 36 + samples.length * 2, true);
writeString(view, 8, 'WAVE');
writeString(view, 12, 'fmt ');
view.setUint32(16, 16, true);
view.setUint16(20, 1, true);
view.setUint16(22, numChannels, true);
view.setUint32(24, sampleRate, true);
view.setUint32(28, sampleRate * 4, true);
view.setUint16(32, numChannels * 2, true);
view.setUint16(34, 16, true);
writeString(view, 36, 'data');
view.setUint32(40, samples.length * 2, true);
floatTo16BitPCM(view, 44, samples);
return
view;
}
}, self);
this.worker.postMessage({
command: 'init',
config: {
sampleRate: this.context.sampleRate,
numChannels: this.config.numChannels
}
});
this.worker.onmessage =
function
(e) {
var
cb = _this.callbacks[e.data.command].pop();
if
(typeof cb == '
function
') {
cb(e.data.data);
}
};
}
_createClass(Recorder, [{
key: 'record',
value:
function
record() {
this.recording = true;
}
}, {
key: 'stop',
value:
function
stop() {
this.recording = false;
}
}, {
key: 'clear',
value:
function
clear() {
this.worker.postMessage({ command: 'clear' });
}
}, {
key: 'getBuffer',
value:
function
getBuffer(cb) {
cb = cb || this.config.callback;
if
(!cb)
throw
new
Error('Callback not set');
this.callbacks.getBuffer.push(cb);
this.worker.postMessage({ command: 'getBuffer' });
}
}, {
key: 'exportWAV',
value:
function
exportWAV(cb, mimeType) {
mimeType = mimeType || this.config.mimeType;
cb = cb || this.config.callback;
if
(!cb)
throw
new
Error('Callback not set');
this.callbacks.exportWAV.push(cb);
this.worker.postMessage({
command: 'exportWAV',
type: mimeType
});
}
}], [{
key: 'forceDownload',
value:
function
forceDownload(blob, filename) {
var
url = (window.URL || window.webkitURL).createObjectURL(blob);
var
link = window.document.createElement('a');
link.href = url;
link.download = filename || 'output.wav';
var
click = document.createEvent(
"Event"
);
click.initEvent(
"click"
, true, true);
link.dispatchEvent(click);
}
}]);
return
Recorder;
})();
exports.
default
= Recorder;
},{
"inline-worker"
:3}],3:[
function
(
require
,module,exports){
"use strict"
;
module.exports =
require
(
"./inline-worker"
);
},{
"./inline-worker"
:4}],4:[
function
(
require
,module,exports){
(
function
(
global
){
"use strict"
;
var
_createClass = (
function
() {
function
defineProperties(target, props) {
for
(
var
key in props) {
var
prop = props[key]; prop.configurable = true;
if
(prop.value) prop.writable = true; } Object.defineProperties(target, props); }
return
function
(Constructor, protoProps, staticProps) {
if
(protoProps) defineProperties(Constructor.prototype, protoProps);
if
(staticProps) defineProperties(Constructor, staticProps);
return
Constructor; }; })();
var
_classCallCheck =
function
(instance, Constructor) {
if
(!(instance
instanceof
Constructor)) {
throw
new
TypeError(
"Cannot call a class as a function"
); } };
var
WORKER_ENABLED = !!(
global
===
global
.window &&
global
.URL &&
global
.Blob &&
global
.Worker);
var
InlineWorker = (
function
() {
function
InlineWorker(func, self) {
var
_this = this;
_classCallCheck(this, InlineWorker);
if
(WORKER_ENABLED) {
var
functionBody = func.toString().trim().match(/^
function
\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1];
var
url =
global
.URL.createObjectURL(
new
global
.Blob([functionBody], { type:
"text/javascript"
}));
return
new
global
.Worker(url);
}
this.self = self;
this.self.postMessage =
function
(data) {
setTimeout(
function
() {
_this.onmessage({ data: data });
}, 0);
};
setTimeout(
function
() {
func.call(self);
}, 0);
}
_createClass(InlineWorker, {
postMessage: {
value:
function
postMessage(data) {
var
_this = this;
setTimeout(
function
() {
_this.self.onmessage({ data: data });
}, 0);
}
}
});
return
InlineWorker;
})();
module.exports = InlineWorker;
}).call(this,typeof
global
!==
"undefined"
?
global
: typeof self !==
"undefined"
? self : typeof window !==
"undefined"
? window : {})
},{}]},{},[1])(1)
});