{"version":3,"sources":["jsdelivr-header.js","/npm/speaker-prebuild@0.1.3/index.js"],"names":[],"mappings":"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","file":"/npm/speaker-prebuild@0.1.3/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/speaker-prebuild@0.1.3/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","\n/**\n * Module dependencies.\n */\n\nvar os = require('os');\nvar debug = require('debug')('speaker');\nvar binding = require('bindings')('binding');\nvar inherits = require('util').inherits;\nvar Writable = require('readable-stream/writable');\n\n// determine the native host endianness, the only supported playback endianness\nvar endianness = 'function' == os.endianness ?\n                 os.endianness() :\n                 'LE'; // assume little-endian for older versions of node.js\n\n/**\n * Module exports.\n */\n\nexports = module.exports = Speaker;\n\n/**\n * Export information about the `mpg123_module_t` being used.\n */\n\nexports.api_version = binding.api_version;\nexports.description = binding.description;\nexports.module_name = binding.name;\n\n/**\n * The `Speaker` class accepts raw PCM data written to it, and then sends that data\n * to the default output device of the OS.\n *\n * @param {Object} opts options object\n * @api public\n */\n\nfunction Speaker (opts) {\n  if (!(this instanceof Speaker)) return new Speaker(opts);\n\n  // default lwm and hwm to 0\n  if (!opts) opts = {};\n  if (null == opts.lowWaterMark) opts.lowWaterMark = 0;\n  if (null == opts.highWaterMark) opts.highWaterMark = 0;\n\n  Writable.call(this, opts);\n\n  // chunks are sent over to the backend in \"samplesPerFrame * blockAlign\" size.\n  // this is necessary because if we send too big of chunks at once, then there\n  // won't be any data ready when the audio callback comes (experienced with the\n  // CoreAudio backend)\n  this.samplesPerFrame = 1024;\n\n  // the `audio_output_t` struct pointer Buffer instance\n  this.audio_handle = null;\n\n  // flipped after close() is called, no write() calls allowed after\n  this._closed = false;\n\n  // set PCM format\n  this._format(opts);\n\n  // bind event listeners\n  this._format = this._format.bind(this);\n  this.on('finish', this._flush);\n  this.on('pipe', this._pipe);\n  this.on('unpipe', this._unpipe);\n}\ninherits(Speaker, Writable);\n\n/**\n * Calls the audio backend's `open()` function, and then emits an \"open\" event.\n *\n * @api private\n */\n\nSpeaker.prototype._open = function () {\n  debug('open()');\n  if (this.audio_handle) {\n    throw new Error('_open() called more than once!');\n  }\n  // set default options, if not set\n  if (null == this.channels) {\n    debug('setting default \"channels\": %o', 2);\n    this.channels = 2;\n  }\n  if (null == this.bitDepth) {\n    debug('setting default \"bitDepth\": %o', 16);\n    this.bitDepth = 16;\n  }\n  if (null == this.sampleRate) {\n    debug('setting default \"sampleRate\", %o', 44100);\n    this.sampleRate = 44100;\n  }\n  if (null == this.signed) {\n    debug('setting default \"signed\": %o', this.bitDepth != 8);\n    this.signed = this.bitDepth != 8;\n  }\n\n  // calculate the \"block align\"\n  this.blockAlign = this.bitDepth / 8 * this.channels;\n\n  // initialize the audio handle\n  // TODO: open async?\n  this.audio_handle = new Buffer(binding.sizeof_audio_output_t);\n  var r = binding.open(this.audio_handle, this);\n  if (0 !== r) {\n    throw new Error('open() failed: ' + r);\n  }\n\n  this.emit('open');\n  return this.audio_handle;\n};\n\n/**\n * Set given PCM formatting options. Called during instantiation on the passed in\n * options object, on the stream given to the \"pipe\" event, and a final time if\n * that stream emits a \"format\" event.\n *\n * @param {Object} opts\n * @api private\n */\n\nSpeaker.prototype._format = function (opts) {\n  debug('format(object keys = %o)', Object.keys(opts));\n  if (null != opts.channels) {\n    debug('setting \"channels\": %o', opts.channels);\n    this.channels = opts.channels;\n  }\n  if (null != opts.bitDepth) {\n    debug('setting \"bitDepth\": %o', opts.bitDepth);\n    this.bitDepth = opts.bitDepth;\n  }\n  if (null != opts.sampleRate) {\n    debug('setting \"sampleRate\": %o', opts.sampleRate);\n    this.sampleRate = opts.sampleRate;\n  }\n  if (null != opts.float) {\n    debug('setting \"float\": %o', opts.float);\n    this.float = opts.float;\n  }\n  if (null != opts.signed) {\n    debug('setting \"signed\": %o', opts.signed);\n    this.signed = opts.signed;\n  }\n  if (null != opts.samplesPerFrame) {\n    debug('setting \"samplesPerFrame\": %o', opts.samplesPerFrame);\n    this.samplesPerFrame = opts.samplesPerFrame;\n  }\n  if (null == opts.endianness || endianness == opts.endianness) {\n    // no \"endianness\" specified or explicit native endianness\n    this.endianness = endianness;\n  } else {\n    // only native endianness is supported...\n    this.emit('error', new Error('only native endianness (\"' + endianness + '\") is supported, got \"' + opts.endianness + '\"'));\n  }\n};\n\n/**\n * `_write()` callback for the Writable base class.\n *\n * @param {Buffer} chunk\n * @param {String} encoding\n * @param {Function} done\n * @api private\n */\n\nSpeaker.prototype._write = function (chunk, encoding, done) {\n  debug('_write() (%d bytes)', chunk.length);\n\n  if (this._closed) {\n    // close() has already been called. this should not be called\n    return done(new Error('write() call after close() call'));\n  }\n  var b;\n  var self = this;\n  var left = chunk;\n  var handle = this.audio_handle;\n  if (!handle) {\n    // this is the first time write() is being called; need to _open()\n    try {\n      handle = this._open();\n    } catch (e) {\n      return done(e);\n    }\n  }\n  var chunkSize = this.blockAlign * this.samplesPerFrame;\n\n  function write () {\n    if (self._closed) {\n      debug('aborting remainder of write() call (%d bytes), since speaker is `_closed`', left.length);\n      return done();\n    }\n    b = left;\n    if (b.length > chunkSize) {\n      var t = b;\n      b = t.slice(0, chunkSize);\n      left = t.slice(chunkSize);\n    } else {\n      left = null;\n    }\n    debug('writing %o byte chunk', b.length);\n    binding.write(handle, b, b.length, onwrite);\n  }\n\n  function onwrite (r) {\n    debug('wrote %o bytes', r);\n    if (r != b.length) {\n      done(new Error('write() failed: ' + r));\n    } else if (left) {\n      debug('still %o bytes left in this chunk', left.length);\n      write();\n    } else {\n      debug('done with this chunk');\n      done();\n    }\n  }\n\n  write();\n};\n\n/**\n * Called when this stream is pipe()d to from another readable stream.\n * If the \"sampleRate\", \"channels\", \"bitDepth\", and \"signed\" properties are\n * set, then they will be used over the currently set values.\n *\n * @api private\n */\n\nSpeaker.prototype._pipe = function (source) {\n  debug('_pipe()');\n  this._format(source);\n  source.once('format', this._format);\n};\n\n/**\n * Called when this stream is pipe()d to from another readable stream.\n * If the \"sampleRate\", \"channels\", \"bitDepth\", and \"signed\" properties are\n * set, then they will be used over the currently set values.\n *\n * @api private\n */\n\nSpeaker.prototype._unpipe = function (source) {\n  debug('_unpipe()');\n  source.removeListener('format', this._format);\n};\n\n/**\n * Emits a \"flush\" event and then calls the `.close()` function on\n * this Speaker instance.\n *\n * @api private\n */\n\nSpeaker.prototype._flush = function () {\n  debug('_flush()');\n  this.emit('flush');\n  this.close(false);\n};\n\n/**\n * Closes the audio backend. Normally this function will be called automatically\n * after the audio backend has finished playing the audio buffer through the\n * speakers.\n *\n * @param {Boolean} flush - if `false`, then don't call the `flush()` native binding call. Defaults to `true`.\n * @api public\n */\n\nSpeaker.prototype.close = function (flush) {\n  debug('close(%o)', flush);\n  if (this._closed) return debug('already closed...');\n\n  if (this.audio_handle) {\n    if (false !== flush) {\n      // TODO: async most likely…\n      debug('invoking flush() native binding');\n      binding.flush(this.audio_handle);\n    }\n\n    // TODO: async maybe?\n    debug('invoking close() native binding');\n    binding.close(this.audio_handle);\n    this.audio_handle = null;\n  } else {\n    debug('not invoking flush() or close() bindings since no `audio_handle`');\n  }\n\n  this._closed = true;\n  this.emit('close');\n};\n"]}