Beispiel #1
0
module.exports = function (source, options, cb) {
  if (options instanceof Function) {
    cb = options
    options = {}
  }
  options = options || {}
  options.ready = cb || function () {}
  var ac = options && options.context ? options.context : context()
  var defaults = { decode: getAudioDecoder(ac), fetch: fetch }
  var opts = Object.assign(defaults, options)
  return load(source, opts)
}
Beispiel #2
0
function decode (buffer, opts, cb) {
	if (opts instanceof Function) {
		cb = opts;
		opts = {};
	}

	if (!opts) opts = {};

	let ctx = opts.context || getContext();

	//blob/file cases
	if (buffer instanceof Blob) buffer = new File([buffer], 'decode')
	if (buffer instanceof File) {
		return new Promise((resolve, reject) => {
			try {
				let reader = new FileReader()
				reader.readAsArrayBuffer(buffer)
				reader.onload = () => {
					return resolve(decode(reader.result, opts, cb))
				}
			} catch (e) {
				reject(e)
			}
		})
	}

	if (!(buffer instanceof ArrayBuffer)) {
		buffer = toAB(buffer)
	}

	// decodeAudioData spoils the initial buffer, so we have to copy that
	return ctx.decodeAudioData(buffer.slice(), (buf) => {
		cb && cb(null, buf);
	}, (err) => {
		cb && cb(err);
	});
}
Beispiel #3
0
module.exports = function createBuffer (source, options) {
	var length, data, channels, sampleRate, format, c, l

	//src, channels
	if (typeof options === 'number') {
		options = {channels: options}
	}
	else if (typeof options === 'string') {
		options = {format: options}
	}
	//{}
	else if (options === undefined) {
		if (isObj(source)) {
			options = source
			source = undefined
		}
		else {
			options = {}
		}
	}

	options = pick(options, {
		format: 'format type dtype dataType',
		channels: 'channel channels numberOfChannels channelCount',
		sampleRate: 'sampleRate rate',
		length: 'length size',
		duration: 'duration time'
	})

	//detect options
	channels = options.channels
	sampleRate = options.sampleRate
	if (options.format) format = getFormat(options.format)

	if (format) {
		if (channels && !format.channels) format.channels = channels
		else if (format.channels && !channels) channels = format.channels
		if (!sampleRate && format.sampleRate) sampleRate = format.sampleRate
	}

	//empty buffer
	if (source == null) {
		if (options.duration != null) {
			if (!sampleRate) sampleRate = 44100
			length = sampleRate * options.duration
		}
		else length = options.length
	}

	//if audio buffer passed - create fast clone of it
	else if (isAudioBuffer(source)) {
		length = source.length
		if (channels == null) channels = source.numberOfChannels
		if (sampleRate == null) sampleRate = source.sampleRate

		if (source._channelData) {
			data = source._channelData.slice(0, channels)
		}
		else {
			data = []

			for (c = 0, l = channels; c < l; c++) {
				data[c] = source.getChannelData(c)
			}
		}
	}

	//if create(number, channels? rate?) = create new array
	//this is the default WAA-compatible case
	else if (typeof source === 'number') {
		length = source
	}

	//if array with channels - parse channeled data
	else if (Array.isArray(source) && (Array.isArray(source[0]) || ArrayBuffer.isView(source[0]))) {
		length = source[0].length;
		data = []
		if (!channels) channels = source.length
		for (c = 0; c < channels; c++) {
			data[c] = source[c] instanceof Float32Array ? source[c] : new Float32Array(source[c])
		}
	}

	//if ndarray, ndsamples, or anything with data
	else if (source.shape && source.data) {
		if (source.shape) channels = source.shape[1]
		if (!sampleRate && source.format) sampleRate = source.format.sampleRate

		return createBuffer(source.data, {
			channels: channels,
			sampleRate: sampleRate
		})
	}

	//TypedArray, Buffer, DataView etc, ArrayBuffer, Array etc.
	//NOTE: node 4.x+ detects Buffer as ArrayBuffer view
	else {
		if (typeof source === 'string') {
			source = str2ab(source)
		}

		if (!format) format = getFormat(source)
		if (!channels) channels = format.channels || 1
		source = convert(source, format, 'float32 planar')

		length = Math.floor(source.length / channels);
		data = []
		for (c = 0; c < channels; c++) {
			data[c] = source.subarray(c * length, (c + 1) * length);
		}
	}

	//create buffer of proper length
	var audioBuffer = new AudioBuffer((options.context === null || length === 0) ? null : options.context || getContext(), {
		length: length == null ? 1 : length,
		numberOfChannels: channels || 1,
		sampleRate: sampleRate || 44100
	})

	//fill channels
	if (data) {
		for (c = 0, l = data.length; c < l; c++) {
			audioBuffer.getChannelData(c).set(data[c]);
		}
	}


	return audioBuffer
}