Global now only manages global Context

global AudioContext was moved to AudioContext.ts
This commit is contained in:
tambien 2019-06-23 15:02:38 -04:00
parent 88e000179c
commit 8b4f1cfa19
17 changed files with 73 additions and 110 deletions

View file

@ -1,22 +1,21 @@
import { version } from "../version";
import { Context } from "./context/Context";
/**
* The global audio context which is getable and assignable through
* getContext and setContext
*/
let globalContext: BaseAudioContext;
let globalContext: Context;
// @ts-ignore
globalContext = window.TONE_AUDIO_CONTEXT;
globalContext = window.TONE_CONTEXT;
/**
* Returns the default system-wide AudioContext
*/
export function getContext(): BaseAudioContext {
export function getContext(): Context {
if (!globalContext) {
globalContext = new AudioContext();
// @ts-ignore
window.TONE_AUDIO_CONTEXT = globalContext;
setContext(new Context());
}
return globalContext;
}
@ -24,10 +23,11 @@ export function getContext(): BaseAudioContext {
/**
* Set the default audio context
*/
export function setContext(context: BaseAudioContext): void {
export function setContext(context: Context): void {
globalContext = context;
context.initialize();
// @ts-ignore
window.TONE_AUDIO_CONTEXT = globalContext;
window.TONE_CONTEXT = context;
}
/**
@ -40,11 +40,7 @@ export function setContext(context: BaseAudioContext): void {
* document.querySelector('#playbutton').addEventListener('click', () => Tone.start())
*/
export function start(): Promise <void> {
if (globalContext instanceof AudioContext) {
return globalContext.resume();
} else {
return Promise.resolve();
}
return globalContext.resume();
}
/**

View file

@ -6,6 +6,7 @@
*/
import { version } from "../version";
import { Context } from "./context/Context";
import { getContext } from "./Global";
import "./type/Units";
///////////////////////////////////////////////////////////////////////////
@ -151,7 +152,7 @@ export abstract class Tone {
///////////////////////////////////////////////////////////////////////////
static get context(): Context {
return Context.getGlobal();
return getContext();
}
static now(): Seconds {

View file

@ -1,6 +1,7 @@
import { Time, TimeClass } from "Tone/core/type/Time";
import { PlaybackState } from "Tone/core/util/StateTimeline";
import { Signal } from "Tone/signal/Signal";
import { Context } from "../context/Context";
import { Gain } from "../context/Gain";
import { Param } from "../context/Param";
import { ToneWithContext, ToneWithContextOptions } from "../context/ToneWithContext";
@ -149,16 +150,17 @@ export class Transport extends ToneWithContext<TransportOptions> implements Emit
*/
private _swingAmount: NormalRange = 0;
constructor(options: Partial<TransportOptions>);
constructor(options?: Partial<TransportOptions>);
constructor() {
super(optionsFromArguments(Transport.getDefaults(), arguments, []));
const options = optionsFromArguments(Transport.getDefaults(), arguments, []);
super(optionsFromArguments(Transport.getDefaults(), arguments));
const options = optionsFromArguments(Transport.getDefaults(), arguments);
// CLOCK/TEMPO
this._ppq = options.ppq;
this._clock = new Clock({
callback : this._processTick.bind(this),
context: this.context,
frequency : 0,
units: "bpm",
});
@ -685,21 +687,6 @@ Emitter.mixin(Transport);
// INITIALIZATION
///////////////////////////////////////////////////////////////////////////////
// var TransportConstructor = Transport;
// Transport = new TransportConstructor();
// Tone.Context.on("init", function(context) {
// if (context.transport && context.transport.isTransport) {
// Transport = context.transport;
// } else {
// Transport = new TransportConstructor();
// }
// });
// Tone.Context.on("close", function(context) {
// if (context.transport && context.transport.isTransport) {
// context.transport.dispose();
// }
// });
// export default Transport;
Context.onInit(context => {
context.transport = new Transport({ context });
});

View file

@ -1,4 +1,4 @@
import { Context } from "./Context"
import { getContext, setContext } from "../Global";
import { OfflineContext } from "./OfflineContext";
import { ToneAudioBuffer } from "./ToneAudioBuffer";
@ -39,13 +39,13 @@ export async function Offline(
callback: (context: OfflineContext) => Promise<void> | void,
duration: Seconds,
channels: number = 2,
sampleRate: number = Context.getGlobal().sampleRate,
sampleRate: number = getContext().sampleRate,
): Promise<ToneAudioBuffer> {
// set the OfflineAudioContext based on the current context
const originalContext = Context.getGlobal();
const originalContext = getContext();
const context = new OfflineContext(channels, duration, sampleRate);
Context.setGlobal(context);
setContext(context);
// invoke the callback/scheduling
await callback(context);
@ -54,7 +54,7 @@ export async function Offline(
const buffer = await context.render();
// return the original AudioContext
Context.setGlobal(originalContext);
setContext(originalContext);
// return the audio
return new ToneAudioBuffer(buffer);

View file

@ -3,10 +3,10 @@ import { expect } from "chai";
import { BasicTests, testAudioContext } from "test/helper/Basic";
import { Offline } from "test/helper/Offline";
import { SCHEDULE_RAMP_AFTER_SET_TARGET } from "test/helper/Supports";
import { Context } from "./Context";
import { getContext } from "../Global";
import { Param } from "./Param";
const audioContext = Context.getGlobal();
const audioContext = getContext();
describe("Param", () => {
@ -69,7 +69,7 @@ describe("Param", () => {
// this fails on FF
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
param = new Param({
context,
@ -88,7 +88,7 @@ describe("Param", () => {
let param;
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
param = new Param({
context,
@ -107,7 +107,7 @@ describe("Param", () => {
let param;
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
param = new Param({
context,
@ -137,7 +137,7 @@ describe("Param", () => {
let param;
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
param = new Param({
context,
@ -168,7 +168,7 @@ describe("Param", () => {
// it ("matches known values", async () => {
// await Compare.toFile(context => {
// const source = context.createConstantSource();
// source.connect(context.destination);
// source.connect(context.rawContext.destination);
// source.start(0);
// const param = new Param({
// context,
@ -218,7 +218,7 @@ describe("Param", () => {
it("can be forced to not convert", async () => {
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
const param = new Param({
context,
@ -239,7 +239,7 @@ describe("Param", () => {
it(`converts to ${units}`, async () => {
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
const param = new Param({
context,
@ -276,7 +276,7 @@ describe("Param", () => {
function testMinMaxValue(units: Unit, min, max): void {
it(`has proper min/max for ${units}`, () => {
const source = audioContext.createConstantSource();
source.connect(audioContext.destination);
source.connect(audioContext.rawContext.destination);
const param = new Param({
context : audioContext,
param: source.offset,
@ -312,7 +312,7 @@ describe("Param", () => {
it(`can schedule value with units ${units}`, async () => {
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
const param = new Param({
context,
@ -353,7 +353,7 @@ describe("Param", () => {
it(`can schedule value with units ${units}`, async () => {
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
const param = new Param({
context,
@ -395,7 +395,7 @@ describe("Param", () => {
it(`can schedule value with units ${units}`, async () => {
const testBuffer = await Offline(context => {
const source = context.createConstantSource();
source.connect(context.destination);
source.connect(context.rawContext.destination);
source.start(0);
const param = new Param({
context,

View file

@ -2,6 +2,7 @@ import { expect } from "chai";
import "test/helper/ToneAudioBuffer";
import { Context } from "../context/Context";
import { ToneAudioBuffer } from "./ToneAudioBuffer";
import { getContext } from "../Global";
const testFile = "./audio/sine.wav";
@ -253,7 +254,7 @@ describe("ToneAudioBuffer", () => {
});
it("can create a buffer from an array using the static method", () => {
const arr = new Float32Array(0.5 * Context.getGlobal().sampleRate);
const arr = new Float32Array(0.5 * getContext().sampleRate);
arr[0] = 0.5;
const buffer = ToneAudioBuffer.fromArray(arr);
expect(buffer.duration).to.equal(0.5);

View file

@ -3,7 +3,6 @@ import { Tone } from "../Tone";
import { optionsFromArguments } from "../util/Defaults";
import { noOp } from "../util/Interface";
import { isArray, isNumber, isString } from "../util/TypeCheck";
import { Context } from "./Context";
interface ToneAudioBufferOptions {
url?: string | AudioBuffer | ToneAudioBuffer;
@ -92,7 +91,7 @@ export class ToneAudioBuffer extends Tone {
if (this._buffer) {
return this._buffer.sampleRate;
} else {
return Context.getGlobal().sampleRate;
return getContext().sampleRate;
}
}
@ -168,7 +167,7 @@ export class ToneAudioBuffer extends Tone {
const isMultidimensional = isArray(array) && array[0].length > 0;
const channels = isMultidimensional ? array.length : 1;
const len = isMultidimensional ? (array[0] as Float32Array).length : array.length;
const context = Context.getGlobal();
const context = getContext();
const buffer = context.createBuffer(channels, len, context.sampleRate);
const multiChannelArray: Float32Array[] = !isMultidimensional && channels === 1 ?
[array as Float32Array] : array as Float32Array[];

View file

@ -1,3 +1,4 @@
import { getContext } from "../Global";
import { Tone } from "../Tone";
import { FrequencyClass } from "../type/Frequency";
import { TimeClass } from "../type/Time";
@ -41,7 +42,7 @@ export abstract class ToneWithContext<Options extends ToneWithContextOptions> ex
static getDefaults(): ToneWithContextOptions {
return {
context: Context.getGlobal(),
context: getContext(),
};
}
@ -149,7 +150,7 @@ export abstract class ToneWithContext<Options extends ToneWithContextOptions> ex
* "type" : "highpass"
* });
*/
set(props: Partial<Options>): ToneWithContext<Options> {
set(props: Partial<Options>): this {
Object.keys(props).forEach(attribute => {
if (Reflect.has(this, attribute)) {
if (isDefined(this[attribute]) && isDefined(this[attribute].value)) {

View file

@ -1,7 +1,7 @@
import { Context } from "../context/Context";
import { TypeBaseExpression } from "./TypeBase";
import { getContext } from "../Global";
import { intervalToFrequencyRatio } from "./Conversions";
import { TimeClass } from "./Time";
import { TypeBaseExpression } from "./TypeBase";
/**
* Frequency is a primitive type for encoding Frequency values.
@ -233,5 +233,5 @@ const noteToScaleIndex = {
const scaleIndexToNote = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
export function Frequency(value, units?): FrequencyClass {
return new FrequencyClass(Context.getGlobal(), value, units);
return new FrequencyClass(getContext(), value, units);
}

View file

@ -1,4 +1,5 @@
import { Context } from "../context/Context";
import { getContext } from "../Global";
import { TransportTimeClass } from "./TransportTime";
import { TypeBaseUnits } from "./TypeBase";
@ -19,11 +20,7 @@ export class TicksClass extends TransportTimeClass<Ticks> {
* Get the current time in the given units
*/
protected _now(): Ticks {
if (this.context.transport) {
return this.context.transport.ticks;
} else {
return 0;
}
return this.context.transport.ticks;
}
/**
@ -63,5 +60,5 @@ export class TicksClass extends TransportTimeClass<Ticks> {
}
export function Ticks(value: Time, units?: TypeBaseUnits): TicksClass {
return new TicksClass(Context.getGlobal(), value, units);
return new TicksClass(getContext(), value, units);
}

View file

@ -3,7 +3,7 @@ import { BasicTests } from "test/helper/Basic";
import { Offline } from "test/helper/Offline";
import { Tone } from "../Tone";
import { Time, TimeClass } from "./Time";
import { Context } from "../context/Context";
import { getContext } from "../Global";
describe("TimeClass", () => {
@ -15,7 +15,7 @@ describe("TimeClass", () => {
const t0 = Time();
expect(t0).to.be.instanceOf(TimeClass);
t0.dispose();
const t1 = new TimeClass(Context.getGlobal());
const t1 = new TimeClass(getContext());
expect(t1).to.be.instanceOf(TimeClass);
t1.dispose();
});

View file

@ -1,4 +1,4 @@
import { Context } from "../context/Context";
import { getContext } from "../Global";
import { FrequencyClass } from "./Frequency";
import { TypeBaseClass, TypeBaseExpression, TypeBaseUnits } from "./TypeBase";
@ -26,11 +26,7 @@ export class TimeClass<Type extends Seconds | Ticks = Seconds> extends TypeBaseC
regexp: /^@(.+)/,
method: (capture: string): Type => {
const quantTo = new TimeClass(this.context, capture).valueOf();
if (this.context.transport) {
return this._secondsToUnits(this.context.transport.nextSubdivision(quantTo));
} else {
return 0 as Type;
}
return this._secondsToUnits(this.context.transport.nextSubdivision(quantTo));
},
},
});
@ -137,5 +133,5 @@ export class TimeClass<Type extends Seconds | Ticks = Seconds> extends TypeBaseC
}
export function Time(value?: Time, units?: TypeBaseUnits): TimeClass {
return new TimeClass(Context.getGlobal(), value, units);
return new TimeClass(getContext(), value, units);
}

View file

@ -1,4 +1,5 @@
import { Context } from "../context/Context";
import { getContext } from "../Global";
import { TimeClass } from "./Time";
import { TypeBaseUnits } from "./TypeBase";
@ -16,14 +17,10 @@ export class TransportTimeClass<Type extends Seconds | Ticks = Seconds> extends
* Return the current time in whichever context is relevant
*/
protected _now(): Type {
if (this.context.transport) {
return this.context.transport.seconds as Type;
} else {
return 0 as Type;
}
return this.context.transport.seconds as Type;
}
}
export function TransportTime(value: Time, units?: TypeBaseUnits): TransportTimeClass {
return new TransportTimeClass(Context.getGlobal(), value, units);
return new TransportTimeClass(getContext(), value, units);
}

View file

@ -231,36 +231,24 @@ export abstract class TypeBaseClass<Type extends Seconds | Hertz | Ticks> extend
///////////////////////////////////////////////////////////////////////////
/**
* Return the bpm, or 120 if Transport is not available
* Return the bpm
*/
protected _getBpm(): BPM {
if (this.context.transport) {
return this.context.transport.bpm.value;
} else {
return 120;
}
return this.context.transport.bpm.value;
}
/**
* Return the timeSignature or 4 if Transport is not available
* Return the timeSignature
*/
protected _getTimeSignature(): number {
if (this.context.transport) {
return this.context.transport.timeSignature as number;
} else {
return 4;
}
return this.context.transport.timeSignature as number;
}
/**
* Return the PPQ or 192 if Transport is not available
*/
protected _getPPQ(): number {
if (this.context.transport) {
return this.context.transport.PPQ;
} else {
return 192;
}
return this.context.transport.PPQ;
}
/**

View file

@ -9,11 +9,11 @@ import { BasicTests } from "test/helper/Basic";
import { CompareToFile } from "test/helper/CompareToFile";
import { Offline } from "test/helper/Offline";
import { ONLINE_TESTING } from "test/helper/Supports";
import { Context } from "Tone/core/context/Context";
import { ToneAudioBuffer } from "Tone/core/context/ToneAudioBuffer";
import { getContext } from "Tone/core/Global";
import { ToneBufferSource } from "./BufferSource";
const sampleRate = Context.getGlobal().sampleRate;
const sampleRate = getContext().sampleRate;
describe("ToneBufferSource", () => {

View file

@ -1,7 +1,7 @@
// import {Offline} from "./Offline";
import { Compare } from "@tonejs/plot";
import { Context } from "Tone/core/context/Context";
import { OfflineContext } from "Tone/core/context/OfflineContext";
import { getContext, setContext } from "Tone/core/Global";
import "./ToneAudioBuffer";
export async function CompareToFile(
@ -12,14 +12,14 @@ export async function CompareToFile(
): Promise<void> {
// @ts-ignore
const prefix = window.__karma__ ? "/base/test/" : "../test/";
const origContext = Context.getGlobal();
const origContext = getContext();
try {
await Compare.toFile(context => {
const offlineContext = new OfflineContext(context, duration, 11025);
Context.setGlobal(offlineContext);
setContext(offlineContext);
callback(offlineContext);
}, prefix + "audio/compare/" + url, threshold, RENDER_NEW, duration, channels, 11025);
} finally {
Context.setGlobal(origContext);
setContext(origContext);
}
}

View file

@ -1,7 +1,7 @@
import { TestAudioBuffer } from "@tonejs/plot";
import { Context } from "Tone/core/context/Context";
import { OfflineContext } from "Tone/core/context/OfflineContext";
import { isFunction } from "Tone/core/util/TypeCheck";
import { setContext, getContext } from "Tone/core/Global";
type ReturnFunction = (time: Seconds) => void;
@ -9,9 +9,9 @@ export async function Offline(
callback: (context: OfflineContext) => void | ReturnFunction | Promise<void | ReturnFunction> | void,
duration = 0.1, channels = 1, sampleRate: number = 44100,
) {
const originalContext = Context.getGlobal();
const originalContext = getContext();
const offline = new OfflineContext(channels, duration + 1 / sampleRate, sampleRate);
Context.setGlobal(offline);
setContext(offline);
let retFunction = callback(offline);
if (retFunction instanceof Promise) {
retFunction = await retFunction;
@ -20,7 +20,7 @@ export async function Offline(
const fn = retFunction;
offline.on("tick", () => fn(offline.now()));
}
Context.setGlobal(originalContext);
setContext(originalContext);
const buffer = await offline.render();
return new TestAudioBuffer(buffer);
}