UNPKG

flocking

Version:

Creative audio synthesis for the Web

146 lines (115 loc) 4.2 kB
/* * Flocking Audio Converters * https://github.com/continuing-creativity/flocking * * Copyright 2015, Colin Clark * Dual licensed under the MIT and GPL Version 2 licenses. */ /*global require, self, global */ /*jshint white: false, newcap: true, regexp: true, browser: true, forin: false, nomen: true, bitwise: false, maxerr: 100, indent: 4, plusplus: false, curly: true, eqeqeq: true, freeze: true, latedef: true, noarg: true, nonew: true, quotmark: double, undef: true, unused: true, strict: true, asi: false, boss: false, evil: false, expr: false, funcscope: false*/ var fluid = fluid || require("infusion"), flock = fluid.registerNamespace("flock"); (function () { "use strict"; var g = typeof (window) !== "undefined" ? window : typeof (self) !== "undefined" ? self : global; fluid.registerNamespace("flock.audio.convert"); flock.audio.convert.maxFloatValue = function (formatSpec) { return 1 - 1 / formatSpec.scale; }; flock.audio.convert.pcm = { int8: { scale: 128, setter: "setInt8", width: 1 }, int16: { scale: 32768, setter: "setInt16", width: 2 }, int32: { scale: 2147483648, setter: "setInt32", width: 4 }, float32: { scale: 1, setter: "setFloat32", width: 4 } }; // Precompute the maximum representable float value for each format. for (var key in flock.audio.convert.pcm) { var formatSpec = flock.audio.convert.pcm[key]; formatSpec.maxFloatValue = flock.audio.convert.maxFloatValue(formatSpec); } // Unsupported, non-API function. flock.audio.convert.specForPCMType = function (format) { var convertSpec = typeof format === "string" ? flock.audio.convert.pcm[format] : format; if (!convertSpec) { flock.fail("Flocking does not support " + format + " format PCM wave files."); } return convertSpec; }; /** * Converts the value from float to integer format * using the specified format specification. * * @param {Number} value the float to convert * @param {Object} formatSpec a specification of the format conversion * @return {Number} the value converted to int format, constrained to the bounds defined by formatSpec */ flock.audio.convert.floatToInt = function (value, formatSpec) { // Clamp to within bounds. var s = Math.min(formatSpec.maxFloatValue, value); s = Math.max(-1.0, s); // Scale to the output number format. s = s * formatSpec.scale; // Round to the nearest whole sample. // TODO: A dither here would be optimal. s = Math.round(s); return s; }; flock.audio.convert.floatsToInts = function (buf, formatSpec) { if (!buf) { return; } var arrayType = "Int" + (8 * formatSpec.width) + "Array", converted = new g[arrayType](buf.length); for (var i = 0; i < buf.length; i++) { var floatVal = buf[i], intVal = flock.audio.convert.floatToInt(floatVal, formatSpec); converted[i] = intVal; } return converted; }; /** * Converts the value from integer to floating format * using the specified format specification. * * @param {Number} value the integer to convert * @param {Object} formatSpec a specification of the format conversion * @return {Number} the value converted to float format */ flock.audio.convert.intToFloat = function (value, formatSpec) { return value / formatSpec.scale; }; flock.audio.convert.intsToFloats = function (buf, formatSpec) { if (!buf) { return; } var converted = new Float32Array(buf.length); for (var i = 0; i < buf.length; i++) { var intVal = buf[i], floatVal = flock.audio.convert.intToFloat(intVal, formatSpec); converted[i] = floatVal; } return converted; }; }());