UNPKG

musictime

Version:

Convert musical timings (bars, beats, 16ths) from and to seconds.

319 lines (256 loc) 7.56 kB
"use strict"; exports.__esModule = true; exports.default = exports.stringIsValid = void 0; /** * Holds sixteenthsPerBeat and beatsPerBar values. */ /** * Defines the place on the bars, beats, sixteenths grid. */ /** * Creates the default values for sixteenthsPerBeat (4) and beatsPerBar (4). */ function getDefaultTimeConfig() { return { sixteenthsPerBeat: 4, beatsPerBar: 4 }; } /** * Checks * @param {string} value * @returns {boolean} */ var stringIsValid = function stringIsValid(value) { var split = value.split('.'); if (split.length !== 3) { return false; } for (var i = 0; i < split.length; i++) { var entry = split[i]; // check if every character is a number (otherwise '10test1.0.0' is valid) for (var char = 0; char < entry.length; char++) { if (!Number.isInteger(parseInt(entry.charAt(char), 10))) { return false; } } var parsedInt = parseInt(split[i], 10); if (!Number.isInteger(parsedInt) || parsedInt < 0) { return false; } } return true; }; exports.stringIsValid = stringIsValid; var MusicTime = /*#__PURE__*/ function () { function MusicTime(bars, beats, sixteenths, timeConfig) { if (bars === void 0) { bars = 0; } if (beats === void 0) { beats = 0; } if (sixteenths === void 0) { sixteenths = 0; } Object.defineProperty(this, "_beats", { configurable: true, enumerable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_timeConfig", { configurable: true, enumerable: true, writable: true, value: void 0 }); this._timeConfig = timeConfig || getDefaultTimeConfig(); this._beats = bars * this._timeConfig.beatsPerBar + beats + sixteenths / this._timeConfig.sixteenthsPerBeat; } /** * Returns an object with bars, beats & sixteenths, based on the current timeConfig. * @returns {IBarsBeatsSixteenths} */ var _proto = MusicTime.prototype; _proto.getBarsBeatsSixteenths = function getBarsBeatsSixteenths() { var totalSixteenths = this._beats * this._timeConfig.sixteenthsPerBeat; var flooredSixteenths = Math.floor(totalSixteenths); var sixteenthsPerBar = this._timeConfig.sixteenthsPerBeat * this._timeConfig.beatsPerBar; var bars = Math.floor(flooredSixteenths / sixteenthsPerBar); var beats = Math.floor((flooredSixteenths - bars * sixteenthsPerBar) / this._timeConfig.sixteenthsPerBeat); return { bars: bars, beats: beats, sixteenths: flooredSixteenths - bars * sixteenthsPerBar - beats * this._timeConfig.sixteenthsPerBeat, remainingSixteenths: totalSixteenths - flooredSixteenths }; }; /** * Returns the current timeConfig (beatsPerBar and sixteenthsPerBeat). * @returns {ITimeConfig} */ _proto.getTimeConfig = function getTimeConfig() { return { sixteenthsPerBeat: this._timeConfig.sixteenthsPerBeat, beatsPerBar: this._timeConfig.beatsPerBar }; }; /** * Sets the timeConfig. * @param {ITimeConfig} value */ _proto.setTimeConfig = function setTimeConfig(value) { if (!value) { throw new Error('No TimeConfig'); } this._timeConfig = value; }; /** * Convert to time in seconds, based on a given amount of beats per minute. * @param bpm * @returns {number} */ _proto.toTime = function toTime(bpm) { return this._beats * 60 / bpm; }; /** * Adds a musicTime to the instance. * @param {MusicTime} time * @returns {MusicTime} */ _proto.add = function add(time) { return MusicTime.add(this, time); }; /** * Subtracts a musicTime from the instance. * @param {MusicTime} time * @returns {MusicTime} */ _proto.subtract = function subtract(time) { return MusicTime.subtract(this, time); }; /** * Multiplies a musicTime with a scalar. * @param {number} value * @returns {MusicTime} */ _proto.multiply = function multiply(value) { return MusicTime.multiply(this, value); }; /** * Check if two instances are equal. * @param {MusicTime} time * @returns {MusicTime} */ _proto.equals = function equals(time) { return MusicTime.equals(this, time); }; /** * Create a clone of the instance. * @returns {MusicTime} */ _proto.clone = function clone() { return new MusicTime(0, this._beats); }; /** * Returns the total amount of bars (can be a float). * @returns {number} */ _proto.getTotalBars = function getTotalBars() { return this._beats / this._timeConfig.beatsPerBar; }; /** * Returns the total amount of beats (can be a float). * @returns {number} */ _proto.getTotalBeats = function getTotalBeats() { return this._beats; }; /** * Returns the total amount of sixteenths (can be a float). * @returns {number} */ _proto.getTotalSixteenths = function getTotalSixteenths() { return this._beats * this._timeConfig.sixteenthsPerBeat; }; /** * Returns a readable string. * @returns {string} */ _proto.toString = function toString() { var bbs = this.getBarsBeatsSixteenths(); // if (bbs.remainingSixteenths > 0) { // return `${bbs.bars}.${bbs.beats}.${bbs.sixteenths} [${bbs.remainingSixteenths.toFixed(2)}]`; // } return bbs.bars + "." + bbs.beats + "." + bbs.sixteenths; }; /** * Returns the amount of beats. * @returns {number} */ _proto.valueOf = function valueOf() { return this._beats; }; /** * Subtracts two MusicTimes. The timeConfig of the first time will be used in the result. * @param {MusicTime} time1 * @param {MusicTime} time2 * @returns {MusicTime} */ MusicTime.subtract = function subtract(time1, time2) { return new MusicTime(0, time1._beats - time2._beats, 0, time1.getTimeConfig()); }; /** * Returns the sum of two times. The timeConfig of the first time will be used in the result. * @param {MusicTime} time1 * @param {MusicTime} time2 * @returns {MusicTime} */ MusicTime.add = function add(time1, time2) { return new MusicTime(0, time1._beats + time2._beats, 0, time1.getTimeConfig()); }; /** * Multiplies the time with a value. The time's timeConfig will be used in the result. * @param {MusicTime} time * @param {number} value * @returns {MusicTime} */ MusicTime.multiply = function multiply(time, value) { return new MusicTime(0, time._beats * value, 0, time.getTimeConfig()); }; /** * Creates an instance from a string. * @param value * @param timeConfig * @returns {MusicTime} */ MusicTime.fromString = function fromString(value, timeConfig) { if (!stringIsValid(value)) { throw new Error('Invalid string'); } var split = value.split('.'); return new MusicTime(parseInt(split[0], 10), parseInt(split[1], 10), parseInt(split[2], 10), timeConfig); }; /** * Check if two times are equal. * @param {MusicTime} time1 * @param {MusicTime} time2 * @returns {boolean} */ MusicTime.equals = function equals(time1, time2) { return time1._beats === time2._beats; }; /** * Creates a MusicTime instance from an amount of seconds. * @param {number} seconds * @param {number} bpm * @param {ITimeConfig} timeConfig * @returns {MusicTime} */ MusicTime.fromTime = function fromTime(seconds, bpm, timeConfig) { return new MusicTime(0, seconds * bpm / 60, 0, timeConfig); }; return MusicTime; }(); exports.default = MusicTime;