mirror of
https://github.com/Tonejs/Tone.js
synced 2025-01-14 04:43:54 +00:00
all tests run on puppeteer, no need for testing guards
This commit is contained in:
parent
c6ae01aace
commit
129e20872f
16 changed files with 770 additions and 871 deletions
|
@ -1,7 +1,6 @@
|
|||
import { expect } from "chai";
|
||||
import { BasicTests, warns } from "../../../test/helper/Basic.js";
|
||||
import { PassAudio } from "../../../test/helper/PassAudio.js";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { Signal } from "../../signal/Signal.js";
|
||||
import { DCMeter } from "./DCMeter.js";
|
||||
|
||||
|
@ -16,17 +15,15 @@ describe("DCMeter", () => {
|
|||
});
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("can get the rms level of the incoming signal", (done) => {
|
||||
const meter = new DCMeter();
|
||||
const osc = new Signal(2).connect(meter);
|
||||
setTimeout(() => {
|
||||
expect(meter.getValue()).to.be.closeTo(2, 0.1);
|
||||
meter.dispose();
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
});
|
||||
}
|
||||
it("can get the rms level of the incoming signal", (done) => {
|
||||
const meter = new DCMeter();
|
||||
const osc = new Signal(2).connect(meter);
|
||||
setTimeout(() => {
|
||||
expect(meter.getValue()).to.be.closeTo(2, 0.1);
|
||||
meter.dispose();
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { expect } from "chai";
|
||||
import { BasicTests } from "../../../test/helper/Basic.js";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { Noise } from "../../source/Noise.js";
|
||||
import { FFT } from "./FFT.js";
|
||||
|
||||
|
@ -62,24 +61,22 @@ describe("FFT", () => {
|
|||
}, 300);
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("outputs a normal range", (done) => {
|
||||
const noise = new Noise();
|
||||
const fft = new FFT({
|
||||
normalRange: true,
|
||||
});
|
||||
noise.connect(fft);
|
||||
noise.start();
|
||||
|
||||
setTimeout(() => {
|
||||
const analysis = fft.getValue();
|
||||
analysis.forEach((value) => {
|
||||
expect(value).is.within(0, 1);
|
||||
});
|
||||
fft.dispose();
|
||||
noise.dispose();
|
||||
done();
|
||||
}, 300);
|
||||
it("outputs a normal range", (done) => {
|
||||
const noise = new Noise();
|
||||
const fft = new FFT({
|
||||
normalRange: true,
|
||||
});
|
||||
}
|
||||
noise.connect(fft);
|
||||
noise.start();
|
||||
|
||||
setTimeout(() => {
|
||||
const analysis = fft.getValue();
|
||||
analysis.forEach((value) => {
|
||||
expect(value).is.within(0, 1);
|
||||
});
|
||||
fft.dispose();
|
||||
noise.dispose();
|
||||
done();
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { expect } from "chai";
|
||||
import { BasicTests, warns } from "../../../test/helper/Basic.js";
|
||||
import { PassAudio } from "../../../test/helper/PassAudio.js";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { Signal } from "../../signal/Signal.js";
|
||||
import { Oscillator } from "../../source/oscillator/Oscillator.js";
|
||||
import { Meter } from "./Meter.js";
|
||||
|
@ -59,55 +58,53 @@ describe("Meter", () => {
|
|||
});
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("can get the rms level of the incoming signal", (done) => {
|
||||
const meter = new Meter();
|
||||
const osc = new Oscillator().connect(meter).start();
|
||||
osc.volume.value = -6;
|
||||
setTimeout(() => {
|
||||
expect(meter.getValue()).to.be.closeTo(-9, 1);
|
||||
meter.dispose();
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
});
|
||||
it("can get the rms level of the incoming signal", (done) => {
|
||||
const meter = new Meter();
|
||||
const osc = new Oscillator().connect(meter).start();
|
||||
osc.volume.value = -6;
|
||||
setTimeout(() => {
|
||||
expect(meter.getValue()).to.be.closeTo(-9, 1);
|
||||
meter.dispose();
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
});
|
||||
|
||||
it("can get the values in normal range", (done) => {
|
||||
const meter = new Meter({
|
||||
normalRange: true,
|
||||
});
|
||||
const osc = new Oscillator().connect(meter).start();
|
||||
osc.volume.value = -6;
|
||||
setTimeout(() => {
|
||||
expect(meter.getValue()).to.be.closeTo(0.35, 0.15);
|
||||
meter.dispose();
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
it("can get the values in normal range", (done) => {
|
||||
const meter = new Meter({
|
||||
normalRange: true,
|
||||
});
|
||||
const osc = new Oscillator().connect(meter).start();
|
||||
osc.volume.value = -6;
|
||||
setTimeout(() => {
|
||||
expect(meter.getValue()).to.be.closeTo(0.35, 0.15);
|
||||
meter.dispose();
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
});
|
||||
|
||||
it("can get the rms levels for multiple channels", (done) => {
|
||||
const meter = new Meter({
|
||||
channelCount: 2,
|
||||
smoothing: 0.5,
|
||||
});
|
||||
const merge = new Merge().connect(meter);
|
||||
const osc0 = new Oscillator().connect(merge, 0, 0).start();
|
||||
const osc1 = new Oscillator().connect(merge, 0, 1).start();
|
||||
osc0.volume.value = -6;
|
||||
osc1.volume.value = -18;
|
||||
setTimeout(() => {
|
||||
const values = meter.getValue();
|
||||
expect(values).to.have.lengthOf(2);
|
||||
expect(values[0]).to.be.closeTo(-9, 1);
|
||||
expect(values[1]).to.be.closeTo(-21, 1);
|
||||
meter.dispose();
|
||||
merge.dispose();
|
||||
osc0.dispose();
|
||||
osc1.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
it("can get the rms levels for multiple channels", (done) => {
|
||||
const meter = new Meter({
|
||||
channelCount: 2,
|
||||
smoothing: 0.5,
|
||||
});
|
||||
}
|
||||
const merge = new Merge().connect(meter);
|
||||
const osc0 = new Oscillator().connect(merge, 0, 0).start();
|
||||
const osc1 = new Oscillator().connect(merge, 0, 1).start();
|
||||
osc0.volume.value = -6;
|
||||
osc1.volume.value = -18;
|
||||
setTimeout(() => {
|
||||
const values = meter.getValue();
|
||||
expect(values).to.have.lengthOf(2);
|
||||
expect(values[0]).to.be.closeTo(-9, 1);
|
||||
expect(values[1]).to.be.closeTo(-21, 1);
|
||||
meter.dispose();
|
||||
merge.dispose();
|
||||
osc0.dispose();
|
||||
osc1.dispose();
|
||||
done();
|
||||
}, 400);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { expect } from "chai";
|
||||
import { BasicTests } from "../../../test/helper/Basic.js";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { Noise } from "../../source/Noise.js";
|
||||
import { Waveform } from "./Waveform.js";
|
||||
|
||||
|
@ -25,23 +24,21 @@ describe("Waveform", () => {
|
|||
anl.dispose();
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("can run waveform analysis", (done) => {
|
||||
const noise = new Noise();
|
||||
const anl = new Waveform(256);
|
||||
noise.connect(anl);
|
||||
noise.start();
|
||||
it("can run waveform analysis", (done) => {
|
||||
const noise = new Noise();
|
||||
const anl = new Waveform(256);
|
||||
noise.connect(anl);
|
||||
noise.start();
|
||||
|
||||
setTimeout(() => {
|
||||
const analysis = anl.getValue();
|
||||
expect(analysis.length).to.equal(256);
|
||||
analysis.forEach((value) => {
|
||||
expect(value).is.within(-1, 1);
|
||||
});
|
||||
anl.dispose();
|
||||
noise.dispose();
|
||||
done();
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
const analysis = anl.getValue();
|
||||
expect(analysis.length).to.equal(256);
|
||||
analysis.forEach((value) => {
|
||||
expect(value).is.within(-1, 1);
|
||||
});
|
||||
anl.dispose();
|
||||
noise.dispose();
|
||||
done();
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { expect } from "chai";
|
||||
import { BasicTests } from "../../../test/helper/Basic.js";
|
||||
import { atTime, Offline, whenBetween } from "../../../test/helper/Offline.js";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { noOp } from "../util/Interface.js";
|
||||
import { Clock } from "./Clock.js";
|
||||
|
||||
|
@ -17,25 +16,23 @@ describe("Clock", () => {
|
|||
clock.dispose();
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("invokes the callback when started", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
it("invokes the callback when started", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
clock.dispose();
|
||||
done();
|
||||
}, 10).start();
|
||||
});
|
||||
|
||||
it("can be constructed with an options object", (done) => {
|
||||
const clock = new Clock({
|
||||
callback(): void {
|
||||
clock.dispose();
|
||||
done();
|
||||
}, 10).start();
|
||||
});
|
||||
|
||||
it("can be constructed with an options object", (done) => {
|
||||
const clock = new Clock({
|
||||
callback(): void {
|
||||
clock.dispose();
|
||||
done();
|
||||
},
|
||||
frequency: 8,
|
||||
}).start();
|
||||
expect(clock.frequency.value).to.equal(8);
|
||||
});
|
||||
}
|
||||
},
|
||||
frequency: 8,
|
||||
}).start();
|
||||
expect(clock.frequency.value).to.equal(8);
|
||||
});
|
||||
|
||||
it("can get and set it's values with the set/get", () => {
|
||||
const clock = new Clock();
|
||||
|
@ -136,36 +133,34 @@ describe("Clock", () => {
|
|||
});
|
||||
|
||||
context("Scheduling", () => {
|
||||
if (ONLINE_TESTING) {
|
||||
it("passes a time to the callback", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
expect(time).to.be.a("number");
|
||||
clock.dispose();
|
||||
done();
|
||||
}, 10).start();
|
||||
});
|
||||
it("passes a time to the callback", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
expect(time).to.be.a("number");
|
||||
clock.dispose();
|
||||
done();
|
||||
}, 10).start();
|
||||
});
|
||||
|
||||
it("invokes the callback with a time great than now", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
clock.dispose();
|
||||
expect(time).to.be.greaterThan(now);
|
||||
done();
|
||||
}, 10);
|
||||
const now = clock.now();
|
||||
const startTime = now + 0.1;
|
||||
clock.start(startTime);
|
||||
});
|
||||
it("invokes the callback with a time great than now", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
clock.dispose();
|
||||
expect(time).to.be.greaterThan(now);
|
||||
done();
|
||||
}, 10);
|
||||
const now = clock.now();
|
||||
const startTime = now + 0.1;
|
||||
clock.start(startTime);
|
||||
});
|
||||
|
||||
it("invokes the first callback at the given start time", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
clock.dispose();
|
||||
expect(time).to.be.closeTo(startTime, 0.01);
|
||||
done();
|
||||
}, 10);
|
||||
const startTime = clock.now() + 0.1;
|
||||
clock.start(startTime);
|
||||
});
|
||||
}
|
||||
it("invokes the first callback at the given start time", (done) => {
|
||||
const clock = new Clock((time) => {
|
||||
clock.dispose();
|
||||
expect(time).to.be.closeTo(startTime, 0.01);
|
||||
done();
|
||||
}, 10);
|
||||
const startTime = clock.now() + 0.1;
|
||||
clock.start(startTime);
|
||||
});
|
||||
|
||||
it("can be scheduled to start in the future", () => {
|
||||
let invokations = 0;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { expect } from "chai";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { Ticker } from "./Ticker.js";
|
||||
|
||||
describe("Ticker", () => {
|
||||
|
@ -30,32 +29,30 @@ describe("Ticker", () => {
|
|||
ticker.dispose();
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
context("timeout", () => {
|
||||
it("provides a callback when set to timeout", (done) => {
|
||||
const ticker = new Ticker(
|
||||
() => {
|
||||
ticker.dispose();
|
||||
done();
|
||||
},
|
||||
"timeout",
|
||||
0.01
|
||||
);
|
||||
});
|
||||
|
||||
it("can adjust the interval when set to timeout", (done) => {
|
||||
const ticker = new Ticker(
|
||||
() => {
|
||||
ticker.dispose();
|
||||
done();
|
||||
},
|
||||
"timeout",
|
||||
0.01
|
||||
);
|
||||
ticker.updateInterval = 0.1;
|
||||
});
|
||||
context("timeout", () => {
|
||||
it("provides a callback when set to timeout", (done) => {
|
||||
const ticker = new Ticker(
|
||||
() => {
|
||||
ticker.dispose();
|
||||
done();
|
||||
},
|
||||
"timeout",
|
||||
0.01
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
it("can adjust the interval when set to timeout", (done) => {
|
||||
const ticker = new Ticker(
|
||||
() => {
|
||||
ticker.dispose();
|
||||
done();
|
||||
},
|
||||
"timeout",
|
||||
0.01
|
||||
);
|
||||
ticker.updateInterval = 0.1;
|
||||
});
|
||||
});
|
||||
|
||||
context("worker", () => {
|
||||
it("provides a callback when set to worker", (done) => {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { expect } from "chai";
|
||||
import { ConstantOutput } from "../../../test/helper/ConstantOutput.js";
|
||||
import { Offline } from "../../../test/helper/Offline.js";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { TransportClass } from "../clock/Transport.js";
|
||||
import { getContext } from "../Global.js";
|
||||
import { createAudioContext } from "./AudioContext.js";
|
||||
|
@ -51,16 +50,14 @@ describe("Context", () => {
|
|||
return ctx.close();
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("clock is running", (done) => {
|
||||
const interval = setInterval(() => {
|
||||
if (getContext().currentTime > 0.5) {
|
||||
clearInterval(interval);
|
||||
done();
|
||||
}
|
||||
}, 20);
|
||||
});
|
||||
}
|
||||
it("clock is running", (done) => {
|
||||
const interval = setInterval(() => {
|
||||
if (getContext().currentTime > 0.5) {
|
||||
clearInterval(interval);
|
||||
done();
|
||||
}
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it("has a rawContext", () => {
|
||||
const ctx = new Context(createAudioContext());
|
||||
|
@ -124,97 +121,93 @@ describe("Context", () => {
|
|||
});
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
context("clockSource", () => {
|
||||
let ctx;
|
||||
beforeEach(() => {
|
||||
ctx = new Context();
|
||||
return ctx.resume();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
ctx.dispose();
|
||||
return ctx.close();
|
||||
});
|
||||
|
||||
it("defaults to 'worker'", () => {
|
||||
expect(ctx.clockSource).to.equal("worker");
|
||||
});
|
||||
|
||||
it("provides callback", (done) => {
|
||||
expect(ctx.clockSource).to.equal("worker");
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
|
||||
it("can be set to 'timeout'", (done) => {
|
||||
ctx.clockSource = "timeout";
|
||||
expect(ctx.clockSource).to.equal("timeout");
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
|
||||
it("can be set to 'offline'", (done) => {
|
||||
ctx.clockSource = "offline";
|
||||
expect(ctx.clockSource).to.equal("offline");
|
||||
// provides no callback
|
||||
ctx.setTimeout(() => {
|
||||
throw new Error("shouldn't be called");
|
||||
}, 0.1);
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
context("clockSource", () => {
|
||||
let ctx;
|
||||
beforeEach(() => {
|
||||
ctx = new Context();
|
||||
return ctx.resume();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
ctx.dispose();
|
||||
return ctx.close();
|
||||
});
|
||||
|
||||
it("defaults to 'worker'", () => {
|
||||
expect(ctx.clockSource).to.equal("worker");
|
||||
});
|
||||
|
||||
it("provides callback", (done) => {
|
||||
expect(ctx.clockSource).to.equal("worker");
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
|
||||
it("can be set to 'timeout'", (done) => {
|
||||
ctx.clockSource = "timeout";
|
||||
expect(ctx.clockSource).to.equal("timeout");
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
|
||||
it("can be set to 'offline'", (done) => {
|
||||
ctx.clockSource = "offline";
|
||||
expect(ctx.clockSource).to.equal("offline");
|
||||
// provides no callback
|
||||
ctx.setTimeout(() => {
|
||||
throw new Error("shouldn't be called");
|
||||
}, 0.1);
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
context("setTimeout", () => {
|
||||
if (ONLINE_TESTING) {
|
||||
let ctx;
|
||||
beforeEach(() => {
|
||||
ctx = new Context();
|
||||
return ctx.resume();
|
||||
});
|
||||
let ctx;
|
||||
beforeEach(() => {
|
||||
ctx = new Context();
|
||||
return ctx.resume();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
ctx.dispose();
|
||||
return ctx.close();
|
||||
});
|
||||
afterEach(() => {
|
||||
ctx.dispose();
|
||||
return ctx.close();
|
||||
});
|
||||
|
||||
it("can set a timeout", (done) => {
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
it("can set a timeout", (done) => {
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
|
||||
it("returns an id", () => {
|
||||
expect(ctx.setTimeout(() => {}, 0.1)).to.be.a("number");
|
||||
// try clearing a random ID, shouldn't cause any errors
|
||||
ctx.clearTimeout(-2);
|
||||
});
|
||||
it("returns an id", () => {
|
||||
expect(ctx.setTimeout(() => {}, 0.1)).to.be.a("number");
|
||||
// try clearing a random ID, shouldn't cause any errors
|
||||
ctx.clearTimeout(-2);
|
||||
});
|
||||
|
||||
it("timeout is not invoked when cancelled", (done) => {
|
||||
const id = ctx.setTimeout(() => {
|
||||
throw new Error("shouldn't be invoked");
|
||||
}, 0.01);
|
||||
ctx.clearTimeout(id);
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.02);
|
||||
});
|
||||
it("timeout is not invoked when cancelled", (done) => {
|
||||
const id = ctx.setTimeout(() => {
|
||||
throw new Error("shouldn't be invoked");
|
||||
}, 0.01);
|
||||
ctx.clearTimeout(id);
|
||||
ctx.setTimeout(() => {
|
||||
done();
|
||||
}, 0.02);
|
||||
});
|
||||
|
||||
it("order is maintained", (done) => {
|
||||
let wasInvoked = false;
|
||||
ctx.setTimeout(() => {
|
||||
expect(wasInvoked).to.equal(true);
|
||||
done();
|
||||
}, 0.02);
|
||||
ctx.setTimeout(() => {
|
||||
wasInvoked = true;
|
||||
}, 0.01);
|
||||
});
|
||||
}
|
||||
it("order is maintained", (done) => {
|
||||
let wasInvoked = false;
|
||||
ctx.setTimeout(() => {
|
||||
expect(wasInvoked).to.equal(true);
|
||||
done();
|
||||
}, 0.02);
|
||||
ctx.setTimeout(() => {
|
||||
wasInvoked = true;
|
||||
}, 0.01);
|
||||
});
|
||||
|
||||
it("is invoked in the offline context", () => {
|
||||
return Offline((context) => {
|
||||
|
@ -227,51 +220,49 @@ describe("Context", () => {
|
|||
});
|
||||
|
||||
context("setInterval", () => {
|
||||
if (ONLINE_TESTING) {
|
||||
let ctx;
|
||||
beforeEach(() => {
|
||||
ctx = new Context();
|
||||
return ctx.resume();
|
||||
});
|
||||
let ctx;
|
||||
beforeEach(() => {
|
||||
ctx = new Context();
|
||||
return ctx.resume();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
ctx.dispose();
|
||||
return ctx.close();
|
||||
});
|
||||
afterEach(() => {
|
||||
ctx.dispose();
|
||||
return ctx.close();
|
||||
});
|
||||
|
||||
it("can set an interval", (done) => {
|
||||
ctx.setInterval(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
it("can set an interval", (done) => {
|
||||
ctx.setInterval(() => {
|
||||
done();
|
||||
}, 0.1);
|
||||
});
|
||||
|
||||
it("returns an id", () => {
|
||||
expect(ctx.setInterval(() => {}, 0.1)).to.be.a("number");
|
||||
// try clearing a random ID, shouldn't cause any errors
|
||||
ctx.clearInterval(-2);
|
||||
});
|
||||
it("returns an id", () => {
|
||||
expect(ctx.setInterval(() => {}, 0.1)).to.be.a("number");
|
||||
// try clearing a random ID, shouldn't cause any errors
|
||||
ctx.clearInterval(-2);
|
||||
});
|
||||
|
||||
it("timeout is not invoked when cancelled", (done) => {
|
||||
const id = ctx.setInterval(() => {
|
||||
throw new Error("shouldn't be invoked");
|
||||
}, 0.01);
|
||||
ctx.clearInterval(id);
|
||||
ctx.setInterval(() => {
|
||||
done();
|
||||
}, 0.02);
|
||||
});
|
||||
it("timeout is not invoked when cancelled", (done) => {
|
||||
const id = ctx.setInterval(() => {
|
||||
throw new Error("shouldn't be invoked");
|
||||
}, 0.01);
|
||||
ctx.clearInterval(id);
|
||||
ctx.setInterval(() => {
|
||||
done();
|
||||
}, 0.02);
|
||||
});
|
||||
|
||||
it("order is maintained", (done) => {
|
||||
let wasInvoked = false;
|
||||
ctx.setInterval(() => {
|
||||
expect(wasInvoked).to.equal(true);
|
||||
done();
|
||||
}, 0.02);
|
||||
ctx.setInterval(() => {
|
||||
wasInvoked = true;
|
||||
}, 0.01);
|
||||
});
|
||||
}
|
||||
it("order is maintained", (done) => {
|
||||
let wasInvoked = false;
|
||||
ctx.setInterval(() => {
|
||||
expect(wasInvoked).to.equal(true);
|
||||
done();
|
||||
}, 0.02);
|
||||
ctx.setInterval(() => {
|
||||
wasInvoked = true;
|
||||
}, 0.01);
|
||||
});
|
||||
|
||||
it("is invoked in the offline context", () => {
|
||||
let invocationCount = 0;
|
||||
|
|
|
@ -2,7 +2,6 @@ import { Compare, Plot } from "../../../test/helper/compare/index.js";
|
|||
import { expect } from "chai";
|
||||
import { BasicTests, testAudioContext } from "../../../test/helper/Basic.js";
|
||||
import { atTime, Offline } from "../../../test/helper/Offline.js";
|
||||
import { SCHEDULE_RAMP_AFTER_SET_TARGET } from "../../../test/helper/Supports.js";
|
||||
import {
|
||||
BPM,
|
||||
Decibels,
|
||||
|
@ -74,176 +73,162 @@ describe("Param", () => {
|
|||
});
|
||||
}
|
||||
|
||||
if (SCHEDULE_RAMP_AFTER_SET_TARGET) {
|
||||
it("correctly handles setTargetAtTime followed by a ramp", async () => {
|
||||
let param;
|
||||
// this fails on FF
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
});
|
||||
param.setTargetAtTime(2, 0.5, 0.1);
|
||||
expect(param.getValueAtTime(0.6)).to.be.closeTo(
|
||||
1.6,
|
||||
0.1
|
||||
);
|
||||
param.linearRampToValueAtTime(0.5, 0.7);
|
||||
expect(param.getValueAtTime(0.6)).to.be.closeTo(
|
||||
0.75,
|
||||
0.1
|
||||
);
|
||||
},
|
||||
1.5,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
document.body.appendChild(await Plot.signal(testBuffer));
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
});
|
||||
it("correctly handles setTargetAtTime followed by a ramp", async () => {
|
||||
let param;
|
||||
// this fails on FF
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
});
|
||||
param.setTargetAtTime(2, 0.5, 0.1);
|
||||
expect(param.getValueAtTime(0.6)).to.be.closeTo(1.6, 0.1);
|
||||
param.linearRampToValueAtTime(0.5, 0.7);
|
||||
expect(param.getValueAtTime(0.6)).to.be.closeTo(0.75, 0.1);
|
||||
},
|
||||
1.5,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
document.body.appendChild(await Plot.signal(testBuffer));
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
});
|
||||
|
||||
it("schedules a value curve", async () => {
|
||||
let param;
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
units: "number",
|
||||
value: 0,
|
||||
});
|
||||
param.setValueCurveAtTime(
|
||||
[0, 0.5, 0, 1, 1.5],
|
||||
0.1,
|
||||
0.8,
|
||||
0.5
|
||||
);
|
||||
expect(param.getValueAtTime(0.91)).to.be.closeTo(
|
||||
0.75,
|
||||
0.01
|
||||
);
|
||||
},
|
||||
1,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
// document.body.appendChild(await Plot.signal(testBuffer));
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
});
|
||||
it("schedules a value curve", async () => {
|
||||
let param;
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
units: "number",
|
||||
value: 0,
|
||||
});
|
||||
param.setValueCurveAtTime(
|
||||
[0, 0.5, 0, 1, 1.5],
|
||||
0.1,
|
||||
0.8,
|
||||
0.5
|
||||
);
|
||||
expect(param.getValueAtTime(0.91)).to.be.closeTo(
|
||||
0.75,
|
||||
0.01
|
||||
);
|
||||
},
|
||||
1,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
// document.body.appendChild(await Plot.signal(testBuffer));
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
});
|
||||
|
||||
it("a mixture of scheduling curves", async () => {
|
||||
let param;
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
value: 0.1,
|
||||
});
|
||||
param.setValueAtTime(0, 0);
|
||||
param.setValueAtTime(1, 0.1);
|
||||
param.linearRampToValueAtTime(3, 0.2);
|
||||
param.exponentialRampToValueAtTime(0.01, 0.3);
|
||||
param.setTargetAtTime(-1, 0.35, 0.2);
|
||||
param.cancelAndHoldAtTime(0.6);
|
||||
param.rampTo(1.1, 0.2, 0.7);
|
||||
param.exponentialRampTo(0, 0.1, 0.85);
|
||||
param.setValueAtTime(0, 1);
|
||||
param.linearRampTo(1, 0.2, 1);
|
||||
param.targetRampTo(0, 0.1, 1.1);
|
||||
param.setValueAtTime(4, 1.2);
|
||||
param.cancelScheduledValues(1.2);
|
||||
param.linearRampToValueAtTime(1, 1.3);
|
||||
},
|
||||
1.5,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
// document.body.appendChild(await Plot.signal(testBuffer));
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
});
|
||||
it("a mixture of scheduling curves", async () => {
|
||||
let param;
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
value: 0.1,
|
||||
});
|
||||
param.setValueAtTime(0, 0);
|
||||
param.setValueAtTime(1, 0.1);
|
||||
param.linearRampToValueAtTime(3, 0.2);
|
||||
param.exponentialRampToValueAtTime(0.01, 0.3);
|
||||
param.setTargetAtTime(-1, 0.35, 0.2);
|
||||
param.cancelAndHoldAtTime(0.6);
|
||||
param.rampTo(1.1, 0.2, 0.7);
|
||||
param.exponentialRampTo(0, 0.1, 0.85);
|
||||
param.setValueAtTime(0, 1);
|
||||
param.linearRampTo(1, 0.2, 1);
|
||||
param.targetRampTo(0, 0.1, 1.1);
|
||||
param.setValueAtTime(4, 1.2);
|
||||
param.cancelScheduledValues(1.2);
|
||||
param.linearRampToValueAtTime(1, 1.3);
|
||||
},
|
||||
1.5,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
// document.body.appendChild(await Plot.signal(testBuffer));
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
});
|
||||
|
||||
it.skip("can cancel and hold", async () => {
|
||||
let param;
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
value: 0.1,
|
||||
});
|
||||
param.setValueAtTime(0, 0);
|
||||
param.setValueAtTime(1, 0.2);
|
||||
param.cancelAndHoldAtTime(0.1);
|
||||
param.linearRampToValueAtTime(1, 0.3);
|
||||
param.cancelAndHoldAtTime(0.2);
|
||||
expect(param.getValueAtTime(0.2)).to.be.closeTo(
|
||||
0.5,
|
||||
0.001
|
||||
);
|
||||
param.exponentialRampToValueAtTime(0, 0.4);
|
||||
param.cancelAndHoldAtTime(0.25);
|
||||
expect(param.getValueAtTime(0.25)).to.be.closeTo(
|
||||
0.033,
|
||||
0.001
|
||||
);
|
||||
param.setTargetAtTime(1, 0.3, 0.1);
|
||||
param.cancelAndHoldAtTime(0.4);
|
||||
expect(param.getValueAtTime(0.4)).to.be.closeTo(
|
||||
0.644,
|
||||
0.001
|
||||
);
|
||||
param.setValueAtTime(0, 0.45);
|
||||
param.setValueAtTime(1, 0.48);
|
||||
param.cancelAndHoldAtTime(0.45);
|
||||
expect(param.getValueAtTime(0.45)).to.be.closeTo(
|
||||
0,
|
||||
0.001
|
||||
);
|
||||
},
|
||||
0.5,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
// document.body.appendChild(await Plot.signal(testBuffer));
|
||||
});
|
||||
it.skip("can cancel and hold", async () => {
|
||||
let param;
|
||||
const testBuffer = await Offline(
|
||||
(context) => {
|
||||
const source = context.createConstantSource();
|
||||
source.connect(context.rawContext.destination);
|
||||
source.start(0);
|
||||
param = new Param({
|
||||
context,
|
||||
param: source.offset,
|
||||
value: 0.1,
|
||||
});
|
||||
param.setValueAtTime(0, 0);
|
||||
param.setValueAtTime(1, 0.2);
|
||||
param.cancelAndHoldAtTime(0.1);
|
||||
param.linearRampToValueAtTime(1, 0.3);
|
||||
param.cancelAndHoldAtTime(0.2);
|
||||
expect(param.getValueAtTime(0.2)).to.be.closeTo(0.5, 0.001);
|
||||
param.exponentialRampToValueAtTime(0, 0.4);
|
||||
param.cancelAndHoldAtTime(0.25);
|
||||
expect(param.getValueAtTime(0.25)).to.be.closeTo(
|
||||
0.033,
|
||||
0.001
|
||||
);
|
||||
param.setTargetAtTime(1, 0.3, 0.1);
|
||||
param.cancelAndHoldAtTime(0.4);
|
||||
expect(param.getValueAtTime(0.4)).to.be.closeTo(
|
||||
0.644,
|
||||
0.001
|
||||
);
|
||||
param.setValueAtTime(0, 0.45);
|
||||
param.setValueAtTime(1, 0.48);
|
||||
param.cancelAndHoldAtTime(0.45);
|
||||
expect(param.getValueAtTime(0.45)).to.be.closeTo(0, 0.001);
|
||||
},
|
||||
0.5,
|
||||
1,
|
||||
sampleRate
|
||||
);
|
||||
matchesOutputCurve(param, testBuffer);
|
||||
// document.body.appendChild(await Plot.signal(testBuffer));
|
||||
});
|
||||
|
||||
// it ("matches known values", async () => {
|
||||
// await Compare.toFile(context => {
|
||||
// const source = context.createConstantSource();
|
||||
// source.connect(context.rawContext.destination);
|
||||
// source.start(0);
|
||||
// const param = new Param({
|
||||
// context,
|
||||
// param: source.offset,
|
||||
// value: 0.1,
|
||||
// });
|
||||
// param.setValueAtTime(0, 0);
|
||||
// param.setValueAtTime(1, 0.2);
|
||||
// param.cancelAndHoldAtTime(0.1);
|
||||
// param.linearRampToValueAtTime(1, 0.3);
|
||||
// param.cancelAndHoldAtTime(0.2);
|
||||
// param.exponentialRampToValueAtTime(0, 0.4);
|
||||
// param.cancelAndHoldAtTime(0.25);
|
||||
// param.setTargetAtTime(1, 0.3, 0.1);
|
||||
// param.cancelAndHoldAtTime(0.4);
|
||||
// }, "/base/test/audio/param/curve_0.wav", 0.01, 0.5, 1, 11025);
|
||||
// });
|
||||
}
|
||||
// it ("matches known values", async () => {
|
||||
// await Compare.toFile(context => {
|
||||
// const source = context.createConstantSource();
|
||||
// source.connect(context.rawContext.destination);
|
||||
// source.start(0);
|
||||
// const param = new Param({
|
||||
// context,
|
||||
// param: source.offset,
|
||||
// value: 0.1,
|
||||
// });
|
||||
// param.setValueAtTime(0, 0);
|
||||
// param.setValueAtTime(1, 0.2);
|
||||
// param.cancelAndHoldAtTime(0.1);
|
||||
// param.linearRampToValueAtTime(1, 0.3);
|
||||
// param.cancelAndHoldAtTime(0.2);
|
||||
// param.exponentialRampToValueAtTime(0, 0.4);
|
||||
// param.cancelAndHoldAtTime(0.25);
|
||||
// param.setTargetAtTime(1, 0.3, 0.1);
|
||||
// param.cancelAndHoldAtTime(0.4);
|
||||
// }, "/base/test/audio/param/curve_0.wav", 0.01, 0.5, 1, 11025);
|
||||
// });
|
||||
});
|
||||
|
||||
context("Units", () => {
|
||||
|
|
|
@ -1,81 +1,66 @@
|
|||
import { expect } from "chai";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { DrawClass } from "./Draw.js";
|
||||
|
||||
describe("Draw", () => {
|
||||
if (ONLINE_TESTING) {
|
||||
const draw = new DrawClass();
|
||||
const draw = new DrawClass();
|
||||
|
||||
after(() => {
|
||||
draw.dispose();
|
||||
});
|
||||
after(() => {
|
||||
draw.dispose();
|
||||
});
|
||||
|
||||
it("can schedule a callback at a AudioContext time", (done) => {
|
||||
const scheduledTime = draw.now() + 0.2;
|
||||
draw.schedule(() => {
|
||||
expect(draw.context.currentTime).to.be.closeTo(
|
||||
scheduledTime,
|
||||
0.05
|
||||
);
|
||||
done();
|
||||
}, scheduledTime);
|
||||
});
|
||||
it("can schedule a callback at a AudioContext time", (done) => {
|
||||
const scheduledTime = draw.now() + 0.2;
|
||||
draw.schedule(() => {
|
||||
expect(draw.context.currentTime).to.be.closeTo(scheduledTime, 0.05);
|
||||
done();
|
||||
}, scheduledTime);
|
||||
});
|
||||
|
||||
it("can schedule multiple callbacks", (done) => {
|
||||
let callbackCount = 0;
|
||||
const firstEvent = draw.now() + 0.1;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(draw.context.currentTime).to.be.closeTo(
|
||||
firstEvent,
|
||||
0.05
|
||||
);
|
||||
}, firstEvent);
|
||||
it("can schedule multiple callbacks", (done) => {
|
||||
let callbackCount = 0;
|
||||
const firstEvent = draw.now() + 0.1;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(draw.context.currentTime).to.be.closeTo(firstEvent, 0.05);
|
||||
}, firstEvent);
|
||||
|
||||
const thirdEvent = draw.now() + 0.3;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(draw.context.currentTime).to.be.closeTo(
|
||||
thirdEvent,
|
||||
0.05
|
||||
);
|
||||
expect(callbackCount).to.equal(3);
|
||||
done();
|
||||
}, thirdEvent);
|
||||
const thirdEvent = draw.now() + 0.3;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(draw.context.currentTime).to.be.closeTo(thirdEvent, 0.05);
|
||||
expect(callbackCount).to.equal(3);
|
||||
done();
|
||||
}, thirdEvent);
|
||||
|
||||
const secondEvent = draw.now() + 0.2;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(draw.context.currentTime).to.be.closeTo(
|
||||
secondEvent,
|
||||
0.05
|
||||
);
|
||||
}, secondEvent);
|
||||
});
|
||||
const secondEvent = draw.now() + 0.2;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(draw.context.currentTime).to.be.closeTo(secondEvent, 0.05);
|
||||
}, secondEvent);
|
||||
});
|
||||
|
||||
it("can cancel scheduled events", (done) => {
|
||||
let callbackCount = 0;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
}, draw.now() + 0.1);
|
||||
it("can cancel scheduled events", (done) => {
|
||||
let callbackCount = 0;
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
}, draw.now() + 0.1);
|
||||
|
||||
draw.schedule(() => {
|
||||
throw new Error("should not call this method");
|
||||
}, draw.now() + 0.2);
|
||||
draw.schedule(() => {
|
||||
throw new Error("should not call this method");
|
||||
}, draw.now() + 0.2);
|
||||
|
||||
draw.schedule(() => {
|
||||
throw new Error("should not call this method");
|
||||
}, draw.now() + 0.25);
|
||||
draw.schedule(() => {
|
||||
throw new Error("should not call this method");
|
||||
}, draw.now() + 0.25);
|
||||
|
||||
// cancel the second and third events
|
||||
draw.cancel(draw.now() + 0.15);
|
||||
// cancel the second and third events
|
||||
draw.cancel(draw.now() + 0.15);
|
||||
|
||||
// schedule another one after
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(callbackCount).to.equal(2);
|
||||
done();
|
||||
}, draw.now() + 0.3);
|
||||
});
|
||||
}
|
||||
// schedule another one after
|
||||
draw.schedule(() => {
|
||||
callbackCount++;
|
||||
expect(callbackCount).to.equal(2);
|
||||
done();
|
||||
}, draw.now() + 0.3);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,6 @@ import { expect } from "chai";
|
|||
import { BasicTests } from "../../test/helper/Basic.js";
|
||||
import { CompareToFile } from "../../test/helper/CompareToFile.js";
|
||||
import { Offline, whenBetween } from "../../test/helper/Offline.js";
|
||||
import { ONLINE_TESTING } from "../../test/helper/Supports.js";
|
||||
import { ToneConstantSource } from "./ToneConstantSource.js";
|
||||
|
||||
describe("ToneConstantSource", () => {
|
||||
|
@ -31,33 +30,31 @@ describe("ToneConstantSource", () => {
|
|||
});
|
||||
|
||||
context("onended", () => {
|
||||
if (ONLINE_TESTING) {
|
||||
it("invokes the onended callback in the online context", (done) => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start();
|
||||
source.stop("+0.3");
|
||||
const now = source.now();
|
||||
source.onended = () => {
|
||||
expect(source.now() - now).to.be.within(0.25, 0.5);
|
||||
source.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
it("invokes the onended callback in the online context", (done) => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start();
|
||||
source.stop("+0.3");
|
||||
const now = source.now();
|
||||
source.onended = () => {
|
||||
expect(source.now() - now).to.be.within(0.25, 0.5);
|
||||
source.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it("invokes the onended callback only once in the online context", (done) => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start();
|
||||
source.stop("+0.1");
|
||||
source.stop("+0.2");
|
||||
source.stop("+0.3");
|
||||
const now = source.now();
|
||||
source.onended = () => {
|
||||
expect(source.now() - now).to.be.within(0.25, 0.5);
|
||||
source.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
}
|
||||
it("invokes the onended callback only once in the online context", (done) => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start();
|
||||
source.stop("+0.1");
|
||||
source.stop("+0.2");
|
||||
source.stop("+0.3");
|
||||
const now = source.now();
|
||||
source.onended = () => {
|
||||
expect(source.now() - now).to.be.within(0.25, 0.5);
|
||||
source.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it("invokes the onended callback in the offline context", () => {
|
||||
let wasInvoked = false;
|
||||
|
@ -128,33 +125,31 @@ describe("ToneConstantSource", () => {
|
|||
});
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("clamps start time to the currentTime", () => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start(0);
|
||||
const currentTime = source.context.currentTime;
|
||||
expect(source.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(source.getStateAtTime(currentTime)).to.equal("started");
|
||||
source.dispose();
|
||||
});
|
||||
it("clamps start time to the currentTime", () => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start(0);
|
||||
const currentTime = source.context.currentTime;
|
||||
expect(source.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(source.getStateAtTime(currentTime)).to.equal("started");
|
||||
source.dispose();
|
||||
});
|
||||
|
||||
it("clamps stop time to the currentTime", (done) => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start(0);
|
||||
let currentTime = source.context.currentTime;
|
||||
expect(source.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(source.getStateAtTime(currentTime)).to.equal("started");
|
||||
setTimeout(() => {
|
||||
currentTime = source.now();
|
||||
source.stop(0);
|
||||
expect(source.getStateAtTime(currentTime + 0.01)).to.equal(
|
||||
"stopped"
|
||||
);
|
||||
source.dispose();
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
it("clamps stop time to the currentTime", (done) => {
|
||||
const source = new ToneConstantSource();
|
||||
source.start(0);
|
||||
let currentTime = source.context.currentTime;
|
||||
expect(source.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(source.getStateAtTime(currentTime)).to.equal("started");
|
||||
setTimeout(() => {
|
||||
currentTime = source.now();
|
||||
source.stop(0);
|
||||
expect(source.getStateAtTime(currentTime + 0.01)).to.equal(
|
||||
"stopped"
|
||||
);
|
||||
source.dispose();
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
context("State", () => {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { expect } from "chai";
|
||||
import { atTime, Offline } from "../../test/helper/Offline.js";
|
||||
import { ONLINE_TESTING } from "../../test/helper/Supports.js";
|
||||
import { ToneAudioBuffer } from "../core/context/ToneAudioBuffer.js";
|
||||
import { getContext } from "../core/Global.js";
|
||||
import { Player } from "./buffer/Player.js";
|
||||
|
@ -98,33 +97,31 @@ describe("Source", () => {
|
|||
}, 2);
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("clamps start time to the currentTime", (done) => {
|
||||
const source = new Oscillator();
|
||||
expect(source.state).to.equal("stopped");
|
||||
source.start(0);
|
||||
it("clamps start time to the currentTime", (done) => {
|
||||
const source = new Oscillator();
|
||||
expect(source.state).to.equal("stopped");
|
||||
source.start(0);
|
||||
setTimeout(() => {
|
||||
expect(source.state).to.equal("started");
|
||||
source.dispose();
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it("clamps stop time to the currentTime", (done) => {
|
||||
const source = new Oscillator();
|
||||
expect(source.state).to.equal("stopped");
|
||||
source.start(0);
|
||||
setTimeout(() => {
|
||||
expect(source.state).to.equal("started");
|
||||
source.stop(0);
|
||||
setTimeout(() => {
|
||||
expect(source.state).to.equal("started");
|
||||
expect(source.state).to.equal("stopped");
|
||||
source.dispose();
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it("clamps stop time to the currentTime", (done) => {
|
||||
const source = new Oscillator();
|
||||
expect(source.state).to.equal("stopped");
|
||||
source.start(0);
|
||||
setTimeout(() => {
|
||||
expect(source.state).to.equal("started");
|
||||
source.stop(0);
|
||||
setTimeout(() => {
|
||||
expect(source.state).to.equal("stopped");
|
||||
source.dispose();
|
||||
done();
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it("correctly returns the scheduled play state", () => {
|
||||
return Offline(() => {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { BasicTests } from "../../test/helper/Basic.js";
|
||||
import { UserMedia } from "./UserMedia.js";
|
||||
import { GET_USER_MEDIA } from "../../test/helper/Supports.js";
|
||||
import { expect } from "chai";
|
||||
import { OfflineContext } from "../core/index.js";
|
||||
|
||||
|
@ -37,144 +36,141 @@ describe("UserMedia", () => {
|
|||
});
|
||||
});
|
||||
|
||||
// if it is a manual test (i.e. there is a person to 'allow' the microphone)
|
||||
if (GET_USER_MEDIA && UserMedia.supported) {
|
||||
context("Opening and closing", function () {
|
||||
// long timeout to give testers time to allow the microphone
|
||||
this.timeout(100000);
|
||||
context("Opening and closing", function () {
|
||||
// long timeout to give testers time to allow the microphone
|
||||
this.timeout(100000);
|
||||
|
||||
let HAS_USER_MEDIA_INPUTS = false;
|
||||
let HAS_USER_MEDIA_INPUTS = false;
|
||||
|
||||
before(() => {
|
||||
return UserMedia.enumerateDevices().then((devices) => {
|
||||
HAS_USER_MEDIA_INPUTS = devices.length > 0;
|
||||
});
|
||||
});
|
||||
|
||||
it("open returns a promise", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
const promise = extIn.open();
|
||||
expect(promise).to.have.property("then");
|
||||
return promise.then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can open an input", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open().then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can open an input by name", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
let name: string;
|
||||
return UserMedia.enumerateDevices()
|
||||
.then((devices) => {
|
||||
name = devices[0].deviceId;
|
||||
return extIn.open(name);
|
||||
})
|
||||
.then(() => {
|
||||
expect(extIn.deviceId).to.equal(name);
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can open an input by index", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open(0).then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("throws an error if it cant find the device name", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn
|
||||
.open("doesn't exist")
|
||||
.then(() => {
|
||||
// shouldn't call 'then'
|
||||
throw new Error("shouldnt call 'then'");
|
||||
})
|
||||
.catch(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("is 'started' after media is open and 'stopped' otherwise", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
expect(extIn.state).to.equal("stopped");
|
||||
return extIn.open().then(() => {
|
||||
expect(extIn.state).to.equal("started");
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("has a label, group and device id when open", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open().then(() => {
|
||||
expect(extIn.deviceId).to.be.a("string");
|
||||
expect(extIn.groupId).to.be.a("string");
|
||||
expect(extIn.label).to.be.a("string");
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can reopen an input", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn
|
||||
.open()
|
||||
.then(() => {
|
||||
return extIn.open();
|
||||
})
|
||||
.then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can close an input", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open().then(() => {
|
||||
extIn.close();
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can enumerate devices", () => {
|
||||
return UserMedia.enumerateDevices().then((devices) => {
|
||||
expect(devices).to.be.instanceOf(Array);
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't work in OfflineContext", (done) => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const context = new OfflineContext(2, 2, 44100);
|
||||
const extIn = new UserMedia({ context });
|
||||
extIn.open().catch(() => {
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
before(() => {
|
||||
return UserMedia.enumerateDevices().then((devices) => {
|
||||
HAS_USER_MEDIA_INPUTS = devices.length > 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
it("open returns a promise", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
const promise = extIn.open();
|
||||
expect(promise).to.have.property("then");
|
||||
return promise.then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can open an input", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open().then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can open an input by name", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
let name: string;
|
||||
return UserMedia.enumerateDevices()
|
||||
.then((devices) => {
|
||||
name = devices[0].deviceId;
|
||||
return extIn.open(name);
|
||||
})
|
||||
.then(() => {
|
||||
expect(extIn.deviceId).to.equal(name);
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can open an input by index", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open(0).then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("throws an error if it cant find the device name", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn
|
||||
.open("doesn't exist")
|
||||
.then(() => {
|
||||
// shouldn't call 'then'
|
||||
throw new Error("shouldnt call 'then'");
|
||||
})
|
||||
.catch(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("is 'started' after media is open and 'stopped' otherwise", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
expect(extIn.state).to.equal("stopped");
|
||||
return extIn.open().then(() => {
|
||||
expect(extIn.state).to.equal("started");
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("has a label, group and device id when open", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open().then(() => {
|
||||
expect(extIn.deviceId).to.be.a("string");
|
||||
expect(extIn.groupId).to.be.a("string");
|
||||
expect(extIn.label).to.be.a("string");
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can reopen an input", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn
|
||||
.open()
|
||||
.then(() => {
|
||||
return extIn.open();
|
||||
})
|
||||
.then(() => {
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can close an input", () => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const extIn = new UserMedia();
|
||||
return extIn.open().then(() => {
|
||||
extIn.close();
|
||||
extIn.dispose();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("can enumerate devices", () => {
|
||||
return UserMedia.enumerateDevices().then((devices) => {
|
||||
expect(devices).to.be.instanceOf(Array);
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't work in OfflineContext", (done) => {
|
||||
if (HAS_USER_MEDIA_INPUTS) {
|
||||
const context = new OfflineContext(2, 2, 44100);
|
||||
const extIn = new UserMedia({ context });
|
||||
extIn.open().catch(() => {
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,10 +2,6 @@ import { expect } from "chai";
|
|||
import { BasicTests } from "../../../test/helper/Basic.js";
|
||||
import { CompareToFile } from "../../../test/helper/CompareToFile.js";
|
||||
import { Offline } from "../../../test/helper/Offline.js";
|
||||
import {
|
||||
OFFLINE_BUFFERSOURCE_ONENDED,
|
||||
ONLINE_TESTING,
|
||||
} from "../../../test/helper/Supports.js";
|
||||
import { ToneAudioBuffer } from "../../core/context/ToneAudioBuffer.js";
|
||||
import { getContext } from "../../core/Global.js";
|
||||
import { ToneBufferSource } from "./ToneBufferSource.js";
|
||||
|
@ -241,17 +237,15 @@ describe("ToneBufferSource", () => {
|
|||
return buffer.load("./test/audio/sine.wav");
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it.skip("schedules the onended callback in online context", (done) => {
|
||||
const player = new ToneBufferSource(buffer);
|
||||
player.start().stop("+0.1");
|
||||
player.onended = () => {
|
||||
expect(player.state).to.equal("stopped");
|
||||
player.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
}
|
||||
it.skip("schedules the onended callback in online context", (done) => {
|
||||
const player = new ToneBufferSource(buffer);
|
||||
player.start().stop("+0.1");
|
||||
player.onended = () => {
|
||||
expect(player.state).to.equal("stopped");
|
||||
player.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it("schedules the onended callback when offline", () => {
|
||||
let wasInvoked = false;
|
||||
|
@ -278,20 +272,18 @@ describe("ToneBufferSource", () => {
|
|||
});
|
||||
});
|
||||
|
||||
if (OFFLINE_BUFFERSOURCE_ONENDED) {
|
||||
it("schedules the onended callback when the buffer is done without scheduling stop", () => {
|
||||
let wasInvoked = false;
|
||||
return Offline(() => {
|
||||
const player = new ToneBufferSource(buffer).toDestination();
|
||||
player.start(0);
|
||||
player.onended = () => {
|
||||
wasInvoked = true;
|
||||
};
|
||||
}, buffer.duration * 1.1).then(() => {
|
||||
expect(wasInvoked).to.equal(true);
|
||||
});
|
||||
it("schedules the onended callback when the buffer is done without scheduling stop", () => {
|
||||
let wasInvoked = false;
|
||||
return Offline(() => {
|
||||
const player = new ToneBufferSource(buffer).toDestination();
|
||||
player.start(0);
|
||||
player.onended = () => {
|
||||
wasInvoked = true;
|
||||
};
|
||||
}, buffer.duration * 1.1).then(() => {
|
||||
expect(wasInvoked).to.equal(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
context("state", () => {
|
||||
|
|
|
@ -2,7 +2,6 @@ import { expect } from "chai";
|
|||
import { BasicTests } from "../../../test/helper/Basic.js";
|
||||
import { CompareToFile } from "../../../test/helper/CompareToFile.js";
|
||||
import { Offline, whenBetween } from "../../../test/helper/Offline.js";
|
||||
import { ONLINE_TESTING } from "../../../test/helper/Supports.js";
|
||||
import { Frequency } from "../../core/type/Frequency.js";
|
||||
import { ToneOscillatorNode } from "./ToneOscillatorNode.js";
|
||||
|
||||
|
@ -74,33 +73,31 @@ describe("ToneOscillatorNode", () => {
|
|||
});
|
||||
|
||||
context("onended", () => {
|
||||
if (ONLINE_TESTING) {
|
||||
it("invokes the onended callback in the online context", (done) => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start();
|
||||
osc.stop("+0.3");
|
||||
const now = osc.now();
|
||||
osc.onended = () => {
|
||||
expect(osc.now() - now).to.be.within(0.25, 0.5);
|
||||
osc.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
it("invokes the onended callback in the online context", (done) => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start();
|
||||
osc.stop("+0.3");
|
||||
const now = osc.now();
|
||||
osc.onended = () => {
|
||||
expect(osc.now() - now).to.be.within(0.25, 0.5);
|
||||
osc.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it("invokes the onended callback only once in the online context", (done) => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start();
|
||||
osc.stop("+0.1");
|
||||
osc.stop("+0.2");
|
||||
osc.stop("+0.3");
|
||||
const now = osc.now();
|
||||
osc.onended = () => {
|
||||
expect(osc.now() - now).to.be.within(0.25, 0.5);
|
||||
osc.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
}
|
||||
it("invokes the onended callback only once in the online context", (done) => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start();
|
||||
osc.stop("+0.1");
|
||||
osc.stop("+0.2");
|
||||
osc.stop("+0.3");
|
||||
const now = osc.now();
|
||||
osc.onended = () => {
|
||||
expect(osc.now() - now).to.be.within(0.25, 0.5);
|
||||
osc.dispose();
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it("invokes the onended callback in the offline context", () => {
|
||||
let wasInvoked = false;
|
||||
|
@ -171,33 +168,31 @@ describe("ToneOscillatorNode", () => {
|
|||
});
|
||||
});
|
||||
|
||||
if (ONLINE_TESTING) {
|
||||
it("clamps start time to the currentTime", () => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start(0);
|
||||
const currentTime = osc.context.currentTime;
|
||||
expect(osc.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(osc.getStateAtTime(currentTime)).to.equal("started");
|
||||
osc.dispose();
|
||||
});
|
||||
it("clamps start time to the currentTime", () => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start(0);
|
||||
const currentTime = osc.context.currentTime;
|
||||
expect(osc.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(osc.getStateAtTime(currentTime)).to.equal("started");
|
||||
osc.dispose();
|
||||
});
|
||||
|
||||
it("clamps stop time to the currentTime", (done) => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start(0);
|
||||
let currentTime = osc.context.currentTime;
|
||||
expect(osc.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(osc.getStateAtTime(currentTime)).to.equal("started");
|
||||
setTimeout(() => {
|
||||
currentTime = osc.now();
|
||||
osc.stop(0);
|
||||
expect(osc.getStateAtTime(currentTime + 0.01)).to.equal(
|
||||
"stopped"
|
||||
);
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
it("clamps stop time to the currentTime", (done) => {
|
||||
const osc = new ToneOscillatorNode();
|
||||
osc.start(0);
|
||||
let currentTime = osc.context.currentTime;
|
||||
expect(osc.getStateAtTime(0)).to.equal("stopped");
|
||||
expect(osc.getStateAtTime(currentTime)).to.equal("started");
|
||||
setTimeout(() => {
|
||||
currentTime = osc.now();
|
||||
osc.stop(0);
|
||||
expect(osc.getStateAtTime(currentTime + 0.01)).to.equal(
|
||||
"stopped"
|
||||
);
|
||||
osc.dispose();
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
context("State", () => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Compare, TestAudioBuffer } from "./compare/index.js";
|
||||
import "./ToneAudioBuffer.js";
|
||||
import { ToneAudioBuffer } from "../../Tone/core/context/ToneAudioBuffer.js";
|
||||
import { Offline } from "../../Tone/core/context/Offline.js";
|
||||
import { Context } from "../../Tone/core/context/Context.js";
|
||||
|
|
|
@ -1,44 +1,28 @@
|
|||
// import { UAParser } from "ua-parser-js";
|
||||
// // import { UAParser } from "ua-parser-js";
|
||||
|
||||
// const parsed = new UAParser().getBrowser();
|
||||
// // const parsed = new UAParser().getBrowser();
|
||||
|
||||
const name = "Chrome" as string;
|
||||
// const name = "Chrome" as string;
|
||||
|
||||
const version = 121;
|
||||
// const version = 121;
|
||||
|
||||
function is(browser, above?): boolean {
|
||||
return false;
|
||||
// above = above || 0;
|
||||
// return name.includes(browser) && version >= above;
|
||||
}
|
||||
// function is(browser, above?): boolean {
|
||||
// return false;
|
||||
// // above = above || 0;
|
||||
// // return name.includes(browser) && version >= above;
|
||||
// }
|
||||
|
||||
function isnt(browser, below?): boolean {
|
||||
below = below || Infinity;
|
||||
return !(name.includes(browser) && version <= below);
|
||||
}
|
||||
// function isnt(browser, below?): boolean {
|
||||
// below = below || Infinity;
|
||||
// return !(name.includes(browser) && version <= below);
|
||||
// }
|
||||
|
||||
function isntVersion(browser, browserVersion?): boolean {
|
||||
return name.includes(browser) && version !== browserVersion;
|
||||
}
|
||||
// function isntVersion(browser, browserVersion?): boolean {
|
||||
// return name.includes(browser) && version !== browserVersion;
|
||||
// }
|
||||
|
||||
// can disconnect from a specific node
|
||||
export const NODE_DISCONNECT = is("Chrome", 50);
|
||||
// // if the tests run in focus
|
||||
// // export const ONLINE_TESTING = isntVersion("Chrome", 71);
|
||||
|
||||
// offline rendering matches Chrome closely
|
||||
// chrome is the platform the files were rendered on
|
||||
// so it is the default for continuity testing
|
||||
export const CHROME_AUDIO_RENDERING = is("Chrome");
|
||||
|
||||
// firefox does not correctly handle the situation where
|
||||
// a linear/exponential ramp is scheduled after setTargetValueAtTime
|
||||
export const SCHEDULE_RAMP_AFTER_SET_TARGET = is("Chrome");
|
||||
|
||||
// if the tests run in focus
|
||||
export const ONLINE_TESTING = isntVersion("Chrome", 71);
|
||||
// the close method resolves a promise
|
||||
export const AUDIO_CONTEXT_CLOSE_RESOLVES =
|
||||
isnt("Firefox") && isnt("Safari", 10);
|
||||
// if it supports gUM testing
|
||||
export const GET_USER_MEDIA = isnt("Safari");
|
||||
// firefox does not invoke AudioBufferSourceNode.onended in the offline context
|
||||
export const OFFLINE_BUFFERSOURCE_ONENDED = isnt("Firefox");
|
||||
// // firefox does not invoke AudioBufferSourceNode.onended in the offline context
|
||||
// // export const OFFLINE_BUFFERSOURCE_ONENDED = isnt("Firefox");
|
||||
|
|
Loading…
Reference in a new issue