mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-15 08:17:07 +00:00
Create BaseContext + better DummyContext
- this creates a new abstract BaseContext that DummyContext and Context inherit from - All methods available to Context are now stubbed by DummyContext - BaseContext is now used as the type where Context was originally used
This commit is contained in:
parent
974ee57353
commit
3354b24527
9 changed files with 303 additions and 24 deletions
|
@ -1,4 +1,4 @@
|
|||
import { Context } from "Tone/core";
|
||||
import { BaseContext } from "Tone/core";
|
||||
import { Gain } from "../../core/context/Gain";
|
||||
import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode";
|
||||
import { optionsFromArguments } from "../../core/util/Defaults";
|
||||
|
@ -61,12 +61,12 @@ export class Solo extends ToneAudioNode<SoloOptions> {
|
|||
/**
|
||||
* Hold all of the solo'ed tracks belonging to a specific context
|
||||
*/
|
||||
private static _allSolos: Map<Context, Set<Solo>> = new Map();
|
||||
private static _allSolos: Map<BaseContext, Set<Solo>> = new Map();
|
||||
|
||||
/**
|
||||
* Hold the currently solo'ed instance(s)
|
||||
*/
|
||||
private static _soloed: Map<Context, Set<Solo>> = new Map();
|
||||
private static _soloed: Map<BaseContext, Set<Solo>> = new Map();
|
||||
|
||||
/**
|
||||
* Isolates this instance and mutes all other instances of Solo.
|
||||
|
|
|
@ -1,29 +1,27 @@
|
|||
import { version } from "../version";
|
||||
import { hasAudioContext, theWindow } from "./context/AudioContext";
|
||||
import { AnyAudioContext, hasAudioContext, theWindow } from "./context/AudioContext";
|
||||
import { Context } from "./context/Context";
|
||||
import { DummyContext } from "./context/DummyContext";
|
||||
import { BaseContext } from "./context/BaseContext";
|
||||
import { OfflineContext } from "./context/OfflineContext";
|
||||
import { isAudioContext, isOfflineAudioContext } from "./util/AdvancedTypeCheck";
|
||||
|
||||
/**
|
||||
* This dummy context is used to avoid throwing immediate errors when importing in Node.js
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
|
||||
const dummyContext: Context = {
|
||||
destination: {},
|
||||
transport: {},
|
||||
} as Context;
|
||||
const dummyContext = new DummyContext();
|
||||
|
||||
/**
|
||||
* The global audio context which is getable and assignable through
|
||||
* getContext and setContext
|
||||
*/
|
||||
let globalContext: Context = dummyContext;
|
||||
let globalContext: BaseContext = dummyContext;
|
||||
|
||||
/**
|
||||
* Returns the default system-wide [[Context]]
|
||||
* @category Core
|
||||
*/
|
||||
export function getContext(): Context {
|
||||
export function getContext(): BaseContext {
|
||||
if (globalContext === dummyContext && hasAudioContext) {
|
||||
setContext(new Context());
|
||||
}
|
||||
|
@ -34,7 +32,7 @@ export function getContext(): Context {
|
|||
* Set the default audio context
|
||||
* @category Core
|
||||
*/
|
||||
export function setContext(context: Context | AudioContext | OfflineAudioContext): void {
|
||||
export function setContext(context: BaseContext | AnyAudioContext): void {
|
||||
if (isAudioContext(context)) {
|
||||
globalContext = new Context(context);
|
||||
} else if (isOfflineAudioContext(context)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Context } from "../context/Context";
|
||||
import { BaseContext } from "../context/BaseContext";
|
||||
import { TicksClass } from "../type/Ticks";
|
||||
import { Seconds, Ticks, Time } from "../type/Units";
|
||||
import { TransportEvent, TransportEventOptions } from "./TransportEvent";
|
||||
|
@ -49,7 +49,7 @@ export class TransportRepeatEvent extends TransportEvent {
|
|||
/**
|
||||
* The audio context belonging to this event
|
||||
*/
|
||||
protected context: Context;
|
||||
protected context: BaseContext;
|
||||
|
||||
/**
|
||||
* @param transport The transport object which the event belongs to
|
||||
|
|
103
Tone/core/context/BaseContext.ts
Normal file
103
Tone/core/context/BaseContext.ts
Normal file
|
@ -0,0 +1,103 @@
|
|||
import { Seconds } from "../type/Units";
|
||||
import { Emitter } from "../util/Emitter";
|
||||
import { AnyAudioContext } from "./AudioContext";
|
||||
|
||||
type Draw = import("../util/Draw").Draw;
|
||||
type Destination = import("./Destination").Destination;
|
||||
type Transport = import("../clock/Transport").Transport;
|
||||
type BaseAudioContextSubset = import("./Context").BaseAudioContextSubset;
|
||||
|
||||
export abstract class BaseContext extends Emitter<"statechange" | "tick"> implements BaseAudioContextSubset {
|
||||
|
||||
//---------------------------
|
||||
// BASE AUDIO CONTEXT METHODS
|
||||
//---------------------------
|
||||
abstract createAnalyser(): AnalyserNode
|
||||
|
||||
abstract createOscillator(): OscillatorNode
|
||||
|
||||
abstract createBufferSource(): AudioBufferSourceNode
|
||||
|
||||
abstract createBiquadFilter(): BiquadFilterNode
|
||||
|
||||
abstract createBuffer(_numberOfChannels: number, _length: number, _sampleRate: number): AudioBuffer
|
||||
|
||||
abstract createChannelMerger(_numberOfInputs?: number | undefined): ChannelMergerNode
|
||||
|
||||
abstract createChannelSplitter(_numberOfOutputs?: number | undefined): ChannelSplitterNode
|
||||
|
||||
abstract createConstantSource(): ConstantSourceNode
|
||||
|
||||
abstract createConvolver(): ConvolverNode
|
||||
|
||||
abstract createDelay(_maxDelayTime?: number | undefined): DelayNode
|
||||
|
||||
abstract createDynamicsCompressor(): DynamicsCompressorNode
|
||||
|
||||
abstract createGain(): GainNode
|
||||
|
||||
abstract createIIRFilter(_feedForward: number[] | Float32Array, _feedback: number[] | Float32Array): IIRFilterNode
|
||||
|
||||
abstract createPanner(): PannerNode
|
||||
|
||||
abstract createPeriodicWave(
|
||||
_real: number[] | Float32Array,
|
||||
_imag: number[] | Float32Array,
|
||||
_constraints?: PeriodicWaveConstraints | undefined,
|
||||
): PeriodicWave
|
||||
|
||||
abstract createStereoPanner(): StereoPannerNode
|
||||
|
||||
abstract createWaveShaper(): WaveShaperNode
|
||||
|
||||
abstract createMediaStreamSource(_stream: MediaStream): MediaStreamAudioSourceNode
|
||||
|
||||
abstract decodeAudioData(_audioData: ArrayBuffer): Promise<AudioBuffer>
|
||||
|
||||
//---------------------------
|
||||
// TONE AUDIO CONTEXT METHODS
|
||||
//---------------------------
|
||||
|
||||
abstract createAudioWorkletNode(
|
||||
_name: string,
|
||||
_options?: Partial<AudioWorkletNodeOptions>
|
||||
): AudioWorkletNode
|
||||
|
||||
abstract get rawContext(): AnyAudioContext
|
||||
|
||||
abstract async addAudioWorkletModule(_url: string, _name: string): Promise<void>
|
||||
|
||||
abstract lookAhead: number;
|
||||
|
||||
abstract resume(): Promise<void>
|
||||
|
||||
abstract setTimeout(_fn: (...args: any[]) => void, _timeout: Seconds): number
|
||||
|
||||
abstract clearTimeout(_id: number): this
|
||||
|
||||
abstract setInterval(_fn: (...args: any[]) => void, _interval: Seconds): number
|
||||
|
||||
abstract clearInterval(_id: number): this
|
||||
|
||||
abstract getConstant(_val: number): AudioBufferSourceNode
|
||||
|
||||
abstract get currentTime(): Seconds
|
||||
|
||||
abstract get state(): AudioContextState
|
||||
|
||||
abstract get sampleRate(): number
|
||||
|
||||
abstract get listener(): AudioListener
|
||||
|
||||
abstract get transport(): Transport
|
||||
|
||||
abstract get draw(): Draw
|
||||
|
||||
abstract get destination(): Destination
|
||||
|
||||
abstract now(): Seconds
|
||||
|
||||
abstract immediate(): Seconds
|
||||
|
||||
readonly isOffline: boolean = false;
|
||||
}
|
|
@ -2,12 +2,12 @@ import { Ticker, TickerClockSource } from "../clock/Ticker";
|
|||
import { Seconds } from "../type/Units";
|
||||
import { isAudioContext } from "../util/AdvancedTypeCheck";
|
||||
import { optionsFromArguments } from "../util/Defaults";
|
||||
import { Emitter } from "../util/Emitter";
|
||||
import { Omit } from "../util/Interface";
|
||||
import { Timeline } from "../util/Timeline";
|
||||
import { isDefined, isString } from "../util/TypeCheck";
|
||||
import { AnyAudioContext, createAudioContext, createAudioWorkletNode } from "./AudioContext";
|
||||
import { closeContext, initializeContext } from "./ContextInitialization";
|
||||
import { BaseContext } from "./BaseContext";
|
||||
|
||||
type Transport = import("../clock/Transport").Transport;
|
||||
type Destination = import("./Destination").Destination;
|
||||
|
@ -42,7 +42,7 @@ export interface ContextTimeoutEvent {
|
|||
* Wrapper around the native AudioContext.
|
||||
* @category Core
|
||||
*/
|
||||
export class Context extends Emitter<"statechange" | "tick"> implements BaseAudioContextSubset {
|
||||
export class Context extends BaseContext {
|
||||
|
||||
readonly name: string = "Context";
|
||||
|
||||
|
|
177
Tone/core/context/DummyContext.ts
Normal file
177
Tone/core/context/DummyContext.ts
Normal file
|
@ -0,0 +1,177 @@
|
|||
import { BaseContext } from "./BaseContext";
|
||||
import { Seconds } from "../type/Units";
|
||||
import { AnyAudioContext } from "./AudioContext";
|
||||
|
||||
type Draw = import("../util/Draw").Draw;
|
||||
type Destination = import("./Destination").Destination;
|
||||
type Transport = import("../clock/Transport").Transport;
|
||||
|
||||
export class DummyContext extends BaseContext {
|
||||
//---------------------------
|
||||
// BASE AUDIO CONTEXT METHODS
|
||||
//---------------------------
|
||||
createAnalyser(): AnalyserNode {
|
||||
return {} as AnalyserNode;
|
||||
}
|
||||
|
||||
createOscillator(): OscillatorNode {
|
||||
return {} as OscillatorNode;
|
||||
}
|
||||
|
||||
createBufferSource() {
|
||||
return {} as AudioBufferSourceNode;
|
||||
}
|
||||
|
||||
createBiquadFilter(): BiquadFilterNode {
|
||||
return {} as BiquadFilterNode;
|
||||
}
|
||||
|
||||
createBuffer(_numberOfChannels: number, _length: number, _sampleRate: number): AudioBuffer {
|
||||
return {} as AudioBuffer;
|
||||
}
|
||||
|
||||
createChannelMerger(_numberOfInputs?: number | undefined): ChannelMergerNode {
|
||||
return {} as ChannelMergerNode;
|
||||
}
|
||||
|
||||
createChannelSplitter(_numberOfOutputs?: number | undefined): ChannelSplitterNode {
|
||||
return {} as ChannelSplitterNode;
|
||||
}
|
||||
|
||||
createConstantSource(): ConstantSourceNode {
|
||||
return {} as ConstantSourceNode;
|
||||
}
|
||||
|
||||
createConvolver(): ConvolverNode {
|
||||
return {} as ConvolverNode;
|
||||
}
|
||||
|
||||
createDelay(_maxDelayTime?: number | undefined): DelayNode {
|
||||
return {} as DelayNode;
|
||||
}
|
||||
|
||||
createDynamicsCompressor(): DynamicsCompressorNode {
|
||||
return {} as DynamicsCompressorNode;
|
||||
}
|
||||
|
||||
createGain(): GainNode {
|
||||
return {} as GainNode;
|
||||
}
|
||||
|
||||
createIIRFilter(_feedForward: number[] | Float32Array, _feedback: number[] | Float32Array): IIRFilterNode {
|
||||
return {} as IIRFilterNode;
|
||||
}
|
||||
|
||||
createPanner(): PannerNode {
|
||||
return {} as PannerNode;
|
||||
}
|
||||
|
||||
createPeriodicWave(
|
||||
_real: number[] | Float32Array,
|
||||
_imag: number[] | Float32Array,
|
||||
_constraints?: PeriodicWaveConstraints | undefined,
|
||||
): PeriodicWave {
|
||||
return {} as PeriodicWave;
|
||||
}
|
||||
|
||||
createStereoPanner(): StereoPannerNode {
|
||||
return {} as StereoPannerNode;
|
||||
}
|
||||
|
||||
createWaveShaper(): WaveShaperNode {
|
||||
return {} as WaveShaperNode;
|
||||
}
|
||||
|
||||
createMediaStreamSource(_stream: MediaStream): MediaStreamAudioSourceNode {
|
||||
return {} as MediaStreamAudioSourceNode;
|
||||
}
|
||||
|
||||
decodeAudioData(_audioData: ArrayBuffer): Promise<AudioBuffer> {
|
||||
return Promise.resolve({} as AudioBuffer);
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
// TONE AUDIO CONTEXT METHODS
|
||||
//---------------------------
|
||||
|
||||
createAudioWorkletNode(
|
||||
_name: string,
|
||||
_options?: Partial<AudioWorkletNodeOptions>
|
||||
): AudioWorkletNode {
|
||||
return {} as AudioWorkletNode;
|
||||
}
|
||||
|
||||
get rawContext(): AnyAudioContext {
|
||||
return {} as AnyAudioContext;
|
||||
}
|
||||
|
||||
async addAudioWorkletModule(_url: string, _name: string): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
lookAhead = 0;
|
||||
|
||||
resume(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
setTimeout(_fn: (...args: any[]) => void, _timeout: Seconds): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
clearTimeout(_id: number): this {
|
||||
return this;
|
||||
}
|
||||
|
||||
setInterval(_fn: (...args: any[]) => void, _interval: Seconds): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
clearInterval(_id: number): this {
|
||||
return this;
|
||||
}
|
||||
|
||||
getConstant(_val: number): AudioBufferSourceNode {
|
||||
return {} as AudioBufferSourceNode;
|
||||
}
|
||||
|
||||
get currentTime(): Seconds {
|
||||
return 0;
|
||||
}
|
||||
|
||||
get state(): AudioContextState {
|
||||
return {} as AudioContextState;
|
||||
}
|
||||
|
||||
get sampleRate(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
get listener(): AudioListener {
|
||||
return {} as AudioListener;
|
||||
}
|
||||
|
||||
get transport(): Transport {
|
||||
return {} as Transport;
|
||||
}
|
||||
|
||||
get draw(): Draw {
|
||||
return {} as Draw;
|
||||
}
|
||||
set draw(_d) { }
|
||||
|
||||
get destination(): Destination {
|
||||
return {} as Destination;
|
||||
}
|
||||
set destination(_d: Destination) { }
|
||||
|
||||
now() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
immediate() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
readonly isOffline: boolean = false;
|
||||
}
|
|
@ -7,13 +7,13 @@ import { Frequency, Hertz, Seconds, Ticks, Time } from "../type/Units";
|
|||
import { getDefaultsFromInstance, optionsFromArguments } from "../util/Defaults";
|
||||
import { RecursivePartial } from "../util/Interface";
|
||||
import { isArray, isBoolean, isDefined, isNumber, isString, isUndef } from "../util/TypeCheck";
|
||||
import { Context } from "./Context";
|
||||
import { BaseContext } from "./BaseContext";
|
||||
|
||||
/**
|
||||
* A unit which process audio
|
||||
*/
|
||||
export interface ToneWithContextOptions {
|
||||
context: Context;
|
||||
context: BaseContext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,19 +24,19 @@ export abstract class ToneWithContext<Options extends ToneWithContextOptions> ex
|
|||
/**
|
||||
* The context belonging to the node.
|
||||
*/
|
||||
readonly context: Context;
|
||||
readonly context: BaseContext;
|
||||
|
||||
/**
|
||||
* The default context to use if no AudioContext is passed in to the constructor.
|
||||
* Probably should not be set manually. Used internally.
|
||||
* @hidden
|
||||
*/
|
||||
readonly defaultContext?: Context;
|
||||
readonly defaultContext?: BaseContext;
|
||||
|
||||
/**
|
||||
* Pass in a constructor as the first argument
|
||||
*/
|
||||
constructor(context?: Context)
|
||||
constructor(context?: BaseContext)
|
||||
constructor(options?: Partial<ToneWithContextOptions>);
|
||||
constructor() {
|
||||
super();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * from "./context/Context";
|
||||
export * from "./context/BaseContext";
|
||||
export * from "./context/Destination";
|
||||
export * from "./context/Delay";
|
||||
export * from "./context/Gain";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Context } from "../context/Context";
|
||||
import { BaseContext } from "../context/BaseContext";
|
||||
import { Tone } from "../Tone";
|
||||
import { isDefined, isObject, isString, isUndef } from "../util/TypeCheck";
|
||||
import { BPM, Hertz, MidiNote, Milliseconds, Samples, Seconds, Ticks, Time } from "./Units";
|
||||
|
@ -27,7 +27,7 @@ export interface TimeExpression<Type extends number> {
|
|||
*/
|
||||
export abstract class TimeBaseClass<Type extends number, Unit extends string> extends Tone {
|
||||
|
||||
readonly context: Context;
|
||||
readonly context: BaseContext;
|
||||
|
||||
/**
|
||||
* The value of the units
|
||||
|
@ -55,7 +55,7 @@ export abstract class TimeBaseClass<Type extends number, Unit extends string> ex
|
|||
* @param value The time value as a number, string or object
|
||||
* @param units Unit values
|
||||
*/
|
||||
constructor(context: Context, value?: TimeValue, units?: Unit) {
|
||||
constructor(context: BaseContext, value?: TimeValue, units?: Unit) {
|
||||
super();
|
||||
|
||||
this._val = value;
|
||||
|
|
Loading…
Reference in a new issue