musictime
Version:
Convert musical timings (bars, beats, 16ths) from and to seconds.
319 lines (256 loc) • 7.56 kB
JavaScript
"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;