UNPKG

webdaw-modules

Version:

a set of modules for building a web-based DAW

220 lines (177 loc) 7.06 kB
function audioEncoder() { 'use strict'; var self, importScripts, Lame, // import encode64, // defined in util.js base64EncArr, // defined in util.js context, // defined in open_module.js oggEncoder, mp3Encoder; function encodeAudio(audioBuffer, type, bitrate, callback) { if (type === 'mp3') { var interleavedSamples = getInterleavedSamples(audioBuffer); bitrate = bitrate || sequencer.bitrate_mp3_encoding; //kbps if (mp3Encoder === undefined) { mp3Encoder = createWorker(); mp3Encoder.onmessage = function (e) { if (e.data.cmd === 'data') { //console.log(e); callback({ blob: new Blob([new Uint8Array(e.data.buf)], { type: 'audio/mp3' }), base64: base64EncArr(e.data.buf), dataUrl: 'data:audio/mp3;base64,' + encode64(e.data.buf) }); } }; } mp3Encoder.postMessage({ cmd: 'init', config: { mode: 3, channels: 1, samplerate: context.sampleRate, bitrate: bitrate } }); mp3Encoder.postMessage({ cmd: 'encode', buf: interleavedSamples }); mp3Encoder.postMessage({ cmd: 'finish' }); } else if (type === 'ogg') { if (sequencer.debug >= sequencer.WARN) { console.warn('support for ogg is not yet implemented'); } callback(false); } else { if (sequencer.debug >= sequencer.WARN) { console.warn('unsupported type', type); } callback(false); } } function getInterleavedSamples(audioBuffer) { if (audioBuffer.numberOfChannels === 1) { return audioBuffer.getChannelData(0); } if (audioBuffer.numberOfChannels === 2) { var left = audioBuffer.getChannelData(0), right = audioBuffer.getChannelData(1), numFrames = left.length, interleaved = new Float32Array(numFrames), i, index = 0; for (i = 0; i < numFrames; i++) { interleaved[index++] = left[i]; interleaved[index++] = right[i]; } return interleaved; } } function cleanUp() { if (mp3Encoder !== undefined) { mp3Encoder.terminate(); } if (oggEncoder !== undefined) { oggEncoder.terminate(); } } // credits: https://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/ function encoder() { /* credits: https://github.com/akrennmair/libmp3lame-js/ https://github.com/kobigurk/libmp3lame-js */ importScripts('https://raw.githubusercontent.com/kobigurk/libmp3lame-js/master/dist/libmp3lame.min.js'); //importScripts('/heartbeat/src/kobigurk/libmp3lame.min.js'); var mp3codec, mp3data; self.onmessage = function (e) { switch (e.data.cmd) { case 'init': if (!e.data.config) { e.data.config = {}; } mp3codec = Lame.init(); Lame.set_mode(mp3codec, e.data.config.mode || Lame.JOINT_STEREO); Lame.set_num_channels(mp3codec, e.data.config.channels || 2); Lame.set_num_samples(mp3codec, e.data.config.samples || -1); Lame.set_in_samplerate(mp3codec, e.data.config.samplerate || 44100); Lame.set_out_samplerate(mp3codec, e.data.config.samplerate || 44100); Lame.set_bitrate(mp3codec, e.data.config.bitrate || 128); Lame.init_params(mp3codec); /* console.log('Version :'+ Lame.get_version() + ' / ' + 'Mode: ' + Lame.get_mode(mp3codec) + ' / ' + 'Samples: ' + Lame.get_num_samples(mp3codec) + ' / ' + 'Channels: ' + Lame.get_num_channels(mp3codec) + ' / ' + 'Input Samplate: ' + Lame.get_in_samplerate(mp3codec) + ' / ' + 'Output Samplate: ' + Lame.get_in_samplerate(mp3codec) + ' / ' + 'Bitlate :' + Lame.get_bitrate(mp3codec) + ' / ' + 'VBR :' + Lame.get_VBR(mp3codec)); */ break; case 'encode': //console.log('encode'); mp3data = Lame.encode_buffer_ieee_float(mp3codec, e.data.buf, e.data.buf); self.postMessage({ cmd: 'data', buf: mp3data.data }); break; case 'finish': //console.log('finish'); mp3data = Lame.encode_flush(mp3codec); self.postMessage({ cmd: 'end', buf: mp3data.data }); Lame.close(mp3codec); mp3codec = null; break; } }; } function createWorker() { var blob = new Blob(['(', encoder.toString(), ')()'], { type: 'application/javascript' }); return new Worker(URL.createObjectURL(blob)); } sequencer.encodeAudio = encodeAudio; sequencer.protectedScope.cleanupAudioEncoder = cleanUp; sequencer.protectedScope.addInitMethod(function () { encode64 = sequencer.util.encode64; base64EncArr = sequencer.util.base64EncArr; context = sequencer.protectedScope.context; }); } /* //not needed anymore because we use AudioBuffer for input function parseWav(wav) { function readInt(i, bytes) { var ret = 0, shft = 0; while (bytes) { ret += wav[i] << shft; shft += 8; i++; bytes--; } return ret; } if (readInt(20, 2) != 1) throw 'Invalid compression code, not PCM'; if (readInt(22, 2) != 1) throw 'Invalid number of channels, not 1'; return { sampleRate: readInt(24, 4), bitsPerSample: readInt(34, 2), samples: wav.subarray(44) }; } function convertUint8ArrayToFloat32Array(u8a){ var f32Buffer = new Float32Array(u8a.length); for (var i = 0; i < u8a.length; i++) { var value = u8a[i<<1] + (u8a[(i<<1)+1]<<8); if (value >= 0x8000) value |= ~0x7FFF; f32Buffer[i] = value / 0x8000; } return f32Buffer; } */