2019-04-12 14:37:47 +00:00
|
|
|
/**
|
2019-09-14 20:39:18 +00:00
|
|
|
* Tone.js
|
2019-08-30 16:06:38 +00:00
|
|
|
* @author Yotam Mann
|
|
|
|
* @license http://opensource.org/licenses/MIT MIT License
|
|
|
|
* @copyright 2014-2019 Yotam Mann
|
2019-04-12 14:37:47 +00:00
|
|
|
*/
|
|
|
|
import { version } from "../version";
|
2019-08-08 21:00:42 +00:00
|
|
|
import { theWindow } from "./context/AudioContext";
|
2019-08-10 22:07:02 +00:00
|
|
|
import { assert, log } from "./util/Debug";
|
2019-04-12 14:37:47 +00:00
|
|
|
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-04-12 14:37:47 +00:00
|
|
|
// TONE
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-04-12 14:37:47 +00:00
|
|
|
|
2019-09-14 22:06:46 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
2019-04-12 14:37:47 +00:00
|
|
|
export interface BaseToneOptions {}
|
|
|
|
|
|
|
|
/**
|
2019-08-30 16:06:38 +00:00
|
|
|
* @class Tone is the base class of all other classes.
|
|
|
|
* @constructor
|
2019-04-12 14:37:47 +00:00
|
|
|
*/
|
|
|
|
export abstract class Tone {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The version number semver
|
|
|
|
*/
|
|
|
|
static version: string = version;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The name of the class
|
|
|
|
*/
|
|
|
|
protected abstract name: string;
|
|
|
|
|
|
|
|
/**
|
2019-09-12 19:52:38 +00:00
|
|
|
* Returns all of the default options belonging to the class.
|
2019-04-12 14:37:47 +00:00
|
|
|
*/
|
|
|
|
static getDefaults(): BaseToneOptions {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-04-12 14:37:47 +00:00
|
|
|
// DEBUGGING
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-04-12 14:37:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set this debug flag to log all events that happen in this class.
|
|
|
|
*/
|
2019-07-23 15:24:38 +00:00
|
|
|
debug: boolean = false;
|
2019-04-12 14:37:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Prints the outputs to the console log for debugging purposes.
|
|
|
|
* Prints the contents only if either the object has a property
|
|
|
|
* called `debug` set to true, or a variable called TONE_DEBUG_CLASS
|
|
|
|
* is set to the name of the class.
|
2019-08-10 22:07:02 +00:00
|
|
|
* @example
|
2019-04-12 14:37:47 +00:00
|
|
|
* //prints all logs originating from Tone.OscillatorNode
|
|
|
|
* Tone.global.TONE_DEBUG_CLASS = "OscillatorNode"
|
|
|
|
*/
|
2019-08-08 21:00:42 +00:00
|
|
|
protected log(...args: any[]): void {
|
2019-04-12 14:37:47 +00:00
|
|
|
// if the object is either set to debug = true
|
|
|
|
// or if there is a string on the Tone.global.with the class name
|
2019-08-08 21:00:42 +00:00
|
|
|
if (this.debug || (theWindow && this.toString() === theWindow.TONE_DEBUG_CLASS)) {
|
2019-07-23 15:24:38 +00:00
|
|
|
args.unshift(this.toString() + ":");
|
2019-08-10 22:07:02 +00:00
|
|
|
log(...args);
|
2019-07-23 15:24:38 +00:00
|
|
|
}
|
2019-04-12 14:37:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-09-14 20:39:18 +00:00
|
|
|
* Assert that the statement is true, otherwise invoke the error.
|
2019-08-30 16:08:29 +00:00
|
|
|
* @param statement
|
|
|
|
* @param error The message which is passed into an Error
|
2019-04-12 14:37:47 +00:00
|
|
|
*/
|
|
|
|
protected assert(statement: boolean, error: string): void {
|
2019-08-10 22:07:02 +00:00
|
|
|
assert(statement, error);
|
2019-04-12 14:37:47 +00:00
|
|
|
}
|
|
|
|
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-07-23 16:11:57 +00:00
|
|
|
// DISPOSING
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-07-23 16:11:57 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates if the instance was disposed
|
|
|
|
*/
|
|
|
|
private _wasDisposed: boolean = false;
|
|
|
|
|
|
|
|
/**
|
2019-09-14 20:39:18 +00:00
|
|
|
* disconnect and dispose.
|
2019-07-23 16:11:57 +00:00
|
|
|
*/
|
|
|
|
dispose(): this {
|
|
|
|
this._wasDisposed = true;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates if the instance was disposed. 'Disposing' an
|
|
|
|
* instance means that all of the Web Audio nodes that were
|
|
|
|
* created for the instance are disconnected and freed for garbage collection.
|
|
|
|
*/
|
|
|
|
get disposed(): boolean {
|
|
|
|
return this._wasDisposed;
|
|
|
|
}
|
|
|
|
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-04-12 14:37:47 +00:00
|
|
|
// DEFAULTS
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-04-12 14:37:47 +00:00
|
|
|
|
|
|
|
/**
|
2019-09-14 20:39:18 +00:00
|
|
|
* If the `given` parameter is undefined, use the `fallback`.
|
|
|
|
* If both `given` and `fallback` are object literals, it will
|
|
|
|
* return a deep copy which includes all of the parameters from both
|
|
|
|
* objects. If a parameter is undefined in given, it will return
|
|
|
|
* the fallback property.
|
|
|
|
* <br><br>
|
|
|
|
* WARNING: if object is self referential, it will go into an an
|
|
|
|
* infinite recursive loop.
|
2019-08-30 16:06:38 +00:00
|
|
|
* @memberOf Tone
|
|
|
|
* @param {*} given
|
|
|
|
* @param {*} fallback
|
|
|
|
* @return {*}
|
2019-04-12 14:37:47 +00:00
|
|
|
*/
|
|
|
|
// static defaultArg(given, fallback) {
|
2019-09-14 22:12:44 +00:00
|
|
|
// if (isObject(given) && isObject(fallback)) {
|
|
|
|
// const ret = {};
|
|
|
|
// // make a deep copy of the given object
|
|
|
|
// for (const givenProp in given) {
|
|
|
|
// ret[givenProp] = Tone.defaultArg(fallback[givenProp], given[givenProp]);
|
|
|
|
// }
|
|
|
|
// for (const fallbackProp in fallback) {
|
|
|
|
// ret[fallbackProp] = Tone.defaultArg(given[fallbackProp], fallback[fallbackProp]);
|
|
|
|
// }
|
|
|
|
// return ret;
|
|
|
|
// } else {
|
|
|
|
// return isUndef(given) ? fallback : given;
|
|
|
|
// }
|
2019-04-12 14:37:47 +00:00
|
|
|
// }
|
|
|
|
|
|
|
|
// protected options(argsArray: IArguments, keys: string[]): object {
|
|
|
|
// let options: any = {};
|
|
|
|
// const args = Array.from(argsArray);
|
|
|
|
// if (args[0] instanceof BaseAudioContext) {
|
|
|
|
// options.context = args.shift();
|
|
|
|
// }
|
|
|
|
// if (args.length === 1 && isObject(args[0])) {
|
|
|
|
// options = Object.assign(options, args[0]);
|
|
|
|
// } else {
|
|
|
|
// for (let i = 0; i < keys.length; i++) {
|
|
|
|
// if (isDefined(args[i])) {
|
|
|
|
// options[keys[i]] = args[i];
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// return deepMerge(this.getDefaults(), options);
|
|
|
|
// }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert the class to a string
|
|
|
|
* @example
|
|
|
|
* const osc = new Oscillator()
|
|
|
|
* osc.toString() // "Oscillator"
|
|
|
|
*/
|
|
|
|
toString(): string {
|
|
|
|
return this.name;
|
|
|
|
}
|
2019-05-23 18:00:49 +00:00
|
|
|
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-05-23 18:00:49 +00:00
|
|
|
// STATIC
|
2019-09-14 22:06:46 +00:00
|
|
|
//-------------------------------------
|
2019-05-23 18:00:49 +00:00
|
|
|
|
2019-07-11 13:57:06 +00:00
|
|
|
// static get context(): import("./context/Context").Context {
|
|
|
|
// return getContext();
|
|
|
|
// }
|
2019-05-23 18:00:49 +00:00
|
|
|
|
2019-07-11 13:57:06 +00:00
|
|
|
// static now(): Seconds {
|
|
|
|
// return Tone.context.now();
|
|
|
|
// }
|
2019-04-12 14:37:47 +00:00
|
|
|
}
|