diff --git a/Tone/signal/ToneConstantSource.test.ts b/Tone/signal/ToneConstantSource.test.ts index 6e5dc2306..2b0fb4a30 100644 --- a/Tone/signal/ToneConstantSource.test.ts +++ b/Tone/signal/ToneConstantSource.test.ts @@ -215,6 +215,44 @@ describe("ToneConstantSource", () => { source.dispose(); }); + it("schedules a future start when the audio context is resumed", async () => { + const context = new Context(); + expect(context.state).to.equal("suspended"); + + const originalCreateConstantSource = context.createConstantSource; + const nativeSource = context.rawContext.createConstantSource(); + const startTimes: number[] = []; + let source: ToneConstantSource | undefined; + + context.createConstantSource = () => + ({ + connect: () => nativeSource, + disconnect: () => {}, + numberOfOutputs: 1, + offset: nativeSource.offset, + start: (time = 0) => { + startTimes.push(time); + }, + stop: () => {}, + }) as unknown as ConstantSourceNode; + + try { + source = new ToneConstantSource({ + context, + }); + + source.start(1); + + await context.resume(); + + expect(startTimes).to.deep.equal([1]); + } finally { + context.createConstantSource = originalCreateConstantSource; + source?.dispose(); + context.dispose(); + } + }); + it("context can be suspended again", async () => { const context = new Context(); expect(context.state).to.equal("suspended"); diff --git a/Tone/signal/ToneConstantSource.ts b/Tone/signal/ToneConstantSource.ts index 2910896b3..9875d8aa5 100644 --- a/Tone/signal/ToneConstantSource.ts +++ b/Tone/signal/ToneConstantSource.ts @@ -81,8 +81,11 @@ export class ToneConstantSource< this._source = this.context.createConstantSource(); connect(this._source, this._gainNode); this.offset?.setParam(this._source.offset); - if (this.state === "started") { - this._source.start(0); + const isStarted = this._startTime !== -1; + const isStoppedBeforeStart = + this._stopTime !== -1 && this._stopTime < this._startTime; + if (isStarted && !isStoppedBeforeStart) { + this._source.start(this._startTime); } }