UNPKG

lamejs

Version:

Pure JavaScript MP3 Encoder

197 lines (173 loc) 5.27 kB
var common = require('./common.js'); var System = common.System; var VbrMode = common.VbrMode; var Float = common.Float; var ShortBlock = common.ShortBlock; var Util = common.Util; var Arrays = common.Arrays; var new_array_n = common.new_array_n; var new_byte = common.new_byte; var new_double = common.new_double; var new_float = common.new_float; var new_float_n = common.new_float_n; var new_int = common.new_int; var new_int_n = common.new_int_n; var assert = common.assert; var Lame = require('./Lame.js'); var Presets = require('./Presets.js'); var GainAnalysis = require('./GainAnalysis.js'); var QuantizePVT = require('./QuantizePVT.js'); var Quantize = require('./Quantize.js'); var Takehiro = require('./Takehiro.js'); var Reservoir = require('./Reservoir.js'); var MPEGMode = require('./MPEGMode.js'); var BitStream = require('./BitStream.js'); var Encoder = require('./Encoder.js'); var Version = require('./Version.js'); var VBRTag = require('./VBRTag.js'); function GetAudio() { var parse; var mpg; this.setModules = function (parse2, mpg2) { parse = parse2; mpg = mpg2; } } function Parse() { var ver; var id3; var pre; this.setModules = function (ver2, id32, pre2) { ver = ver2; id3 = id32; pre = pre2; } } function MPGLib() { } function ID3Tag() { var bits; var ver; this.setModules = function (_bits, _ver) { bits = _bits; ver = _ver; } } function Mp3Encoder(channels, samplerate, kbps) { if (arguments.length != 3) { console.error('WARN: Mp3Encoder(channels, samplerate, kbps) not specified'); channels = 1; samplerate = 44100; kbps = 128; } var lame = new Lame(); var gaud = new GetAudio(); var ga = new GainAnalysis(); var bs = new BitStream(); var p = new Presets(); var qupvt = new QuantizePVT(); var qu = new Quantize(); var vbr = new VBRTag(); var ver = new Version(); var id3 = new ID3Tag(); var rv = new Reservoir(); var tak = new Takehiro(); var parse = new Parse(); var mpg = new MPGLib(); lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); bs.setModules(ga, mpg, ver, vbr); id3.setModules(bs, ver); p.setModules(lame); qu.setModules(bs, rv, qupvt, tak); qupvt.setModules(tak, rv, lame.enc.psy); rv.setModules(bs); tak.setModules(qupvt); vbr.setModules(lame, bs, ver); gaud.setModules(parse, mpg); parse.setModules(ver, id3, p); var gfp = lame.lame_init(); gfp.num_channels = channels; gfp.in_samplerate = samplerate; gfp.brate = kbps; gfp.mode = MPEGMode.STEREO; gfp.quality = 3; gfp.bWriteVbrTag = false; gfp.disable_reservoir = true; gfp.write_id3tag_automatic = false; var retcode = lame.lame_init_params(gfp); assert(0 == retcode); var maxSamples = 1152; var mp3buf_size = 0 | (1.25 * maxSamples + 7200); var mp3buf = new_byte(mp3buf_size); this.encodeBuffer = function (left, right) { if (channels == 1) { right = left; } assert(left.length == right.length); if (left.length > maxSamples) { maxSamples = left.length; mp3buf_size = 0 | (1.25 * maxSamples + 7200); mp3buf = new_byte(mp3buf_size); } var _sz = lame.lame_encode_buffer(gfp, left, right, left.length, mp3buf, 0, mp3buf_size); return new Int8Array(mp3buf.subarray(0, _sz)); }; this.flush = function () { var _sz = lame.lame_encode_flush(gfp, mp3buf, 0, mp3buf_size); return new Int8Array(mp3buf.subarray(0, _sz)); }; } function WavHeader() { this.dataOffset = 0; this.dataLen = 0; this.channels = 0; this.sampleRate = 0; } function fourccToInt(fourcc) { return fourcc.charCodeAt(0) << 24 | fourcc.charCodeAt(1) << 16 | fourcc.charCodeAt(2) << 8 | fourcc.charCodeAt(3); } WavHeader.RIFF = fourccToInt("RIFF"); WavHeader.WAVE = fourccToInt("WAVE"); WavHeader.fmt_ = fourccToInt("fmt "); WavHeader.data = fourccToInt("data"); WavHeader.readHeader = function (dataView) { var w = new WavHeader(); var header = dataView.getUint32(0, false); if (WavHeader.RIFF != header) { return; } var fileLen = dataView.getUint32(4, true); if (WavHeader.WAVE != dataView.getUint32(8, false)) { return; } if (WavHeader.fmt_ != dataView.getUint32(12, false)) { return; } var fmtLen = dataView.getUint32(16, true); var pos = 16 + 4; switch (fmtLen) { case 16: case 18: w.channels = dataView.getUint16(pos + 2, true); w.sampleRate = dataView.getUint32(pos + 4, true); break; default: throw 'extended fmt chunk not implemented'; } pos += fmtLen; var data = WavHeader.data; var len = 0; while (data != header) { header = dataView.getUint32(pos, false); len = dataView.getUint32(pos + 4, true); if (data == header) { break; } pos += (len + 8); } w.dataLen = len; w.dataOffset = pos + 8; return w; }; module.exports.Mp3Encoder = Mp3Encoder; module.exports.WavHeader = WavHeader;