mirror of
https://github.com/Tonejs/Tone.js
synced 2024-12-28 12:33:12 +00:00
345 lines
8.8 KiB
TypeScript
345 lines
8.8 KiB
TypeScript
import { expect } from "chai";
|
|
import { Merge } from "Tone/component";
|
|
import { Split } from "Tone/component/channel/Split";
|
|
import { Oscillator } from "Tone/source";
|
|
import { Gain } from "./Gain";
|
|
import { connect, disconnect, fanIn } from "./ToneAudioNode";
|
|
import { PassAudio } from "test/helper/PassAudio";
|
|
import { Offline } from "test/helper/Offline";
|
|
|
|
describe("ToneAudioNode", () => {
|
|
|
|
context("constructor", () => {
|
|
it("can be created and disposed", () => {
|
|
const node = new Gain();
|
|
node.dispose();
|
|
});
|
|
});
|
|
|
|
context("properties", () => {
|
|
|
|
it("reports its inputs and outputs", () => {
|
|
const node = new Gain();
|
|
expect(node.numberOfInputs).to.equal(1);
|
|
expect(node.numberOfOutputs).to.equal(1);
|
|
node.dispose();
|
|
});
|
|
|
|
it("get/set channelCount", () => {
|
|
const node = new Gain();
|
|
expect(node.channelCount).to.equal(2);
|
|
node.channelCount = 1;
|
|
expect(node.channelCount).to.equal(1);
|
|
node.dispose();
|
|
});
|
|
|
|
it("get/set channelCountMode", () => {
|
|
const node = new Gain();
|
|
expect(node.channelCountMode).to.equal("max");
|
|
node.channelCountMode = "explicit";
|
|
expect(node.channelCountMode).to.equal("explicit");
|
|
node.dispose();
|
|
});
|
|
|
|
it("get/set channelInterpretation", () => {
|
|
const node = new Gain();
|
|
expect(node.channelInterpretation).to.equal("speakers");
|
|
node.channelInterpretation = "discrete";
|
|
expect(node.channelInterpretation).to.equal("discrete");
|
|
node.dispose();
|
|
});
|
|
|
|
it("reports its inputs and outputs", () => {
|
|
const node0 = new Merge({
|
|
channels: 4,
|
|
});
|
|
expect(node0.numberOfInputs).to.equal(4);
|
|
expect(node0.numberOfOutputs).to.equal(1);
|
|
node0.dispose();
|
|
|
|
const node1 = new Split(4);
|
|
expect(node1.numberOfInputs).to.equal(1);
|
|
expect(node1.numberOfOutputs).to.equal(4);
|
|
node1.dispose();
|
|
|
|
const node2 = new Oscillator();
|
|
expect(node2.numberOfInputs).to.equal(0);
|
|
expect(node2.numberOfOutputs).to.equal(1);
|
|
node2.dispose();
|
|
});
|
|
|
|
it("is able to get and set the channelCount, channelCountMode and channelInterpretation", () => {
|
|
const gainNode = new Gain();
|
|
|
|
expect(gainNode.channelCount).to.equal(2);
|
|
gainNode.channelCount = 1;
|
|
expect(gainNode.channelCount).to.equal(1);
|
|
|
|
expect(gainNode.channelInterpretation).to.equal("speakers");
|
|
gainNode.channelInterpretation = "discrete";
|
|
expect(gainNode.channelInterpretation).to.equal("discrete");
|
|
|
|
expect(gainNode.channelCountMode).to.equal("max");
|
|
gainNode.channelCountMode = "clamped-max";
|
|
expect(gainNode.channelCountMode).to.equal("clamped-max");
|
|
gainNode.dispose();
|
|
});
|
|
});
|
|
|
|
context("methods", () => {
|
|
it("toDestination()", () => {
|
|
const node = new Gain();
|
|
node.toDestination();
|
|
node.dispose();
|
|
});
|
|
|
|
it("connect()", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
nodeA.connect(nodeB);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("disconnect()", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
nodeA.connect(nodeB);
|
|
nodeA.disconnect(nodeB);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("fan()", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
const nodeC = new Gain();
|
|
nodeA.fan(nodeB, nodeC);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
nodeC.dispose();
|
|
});
|
|
|
|
it("chain()", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
const nodeC = new Gain();
|
|
nodeA.chain(nodeB, nodeC);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
nodeC.dispose();
|
|
});
|
|
});
|
|
|
|
context("connections", () => {
|
|
it("can connect with args", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
nodeA.connect(nodeB, 0, 0);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("can connect with no args", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
nodeA.connect(nodeB);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("can connect with one arg", () => {
|
|
const nodeA = new Split(2);
|
|
const nodeB = new Gain();
|
|
nodeA.connect(nodeB, 1);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("Tone nodes can disconnect from everything with no args", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
nodeA.connect(nodeB);
|
|
nodeA.disconnect();
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("Tone nodes can disconnect from a specific node", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
nodeA.connect(nodeB);
|
|
nodeA.disconnect(nodeB);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("Tone nodes can disconnect from a specific node and input/output", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Merge();
|
|
nodeA.connect(nodeB, 0, 1);
|
|
nodeA.disconnect(nodeB, 0, 1);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
|
|
it("throws an error if they are not connected", () => {
|
|
const nodeA = new Gain();
|
|
const nodeB = new Gain();
|
|
expect(() => {
|
|
nodeA.disconnect(nodeB);
|
|
}).throws(Error);
|
|
nodeA.dispose();
|
|
nodeB.dispose();
|
|
});
|
|
});
|
|
|
|
context("connect native node", () => {
|
|
|
|
it("can create a connection", () => {
|
|
return PassAudio(input => {
|
|
const output = input.context.destination;
|
|
connect(input, output);
|
|
});
|
|
});
|
|
|
|
it("can disconnect two nodes", () => {
|
|
return PassAudio(input => {
|
|
const output = input.context.destination;
|
|
connect(input, output);
|
|
disconnect(input, output);
|
|
}, false);
|
|
});
|
|
|
|
it("can disconnect a node", () => {
|
|
PassAudio(input => {
|
|
const output = input.context.destination;
|
|
connect(input, output);
|
|
disconnect(input);
|
|
}, false);
|
|
});
|
|
|
|
it("can fan in multiple nodes to a destination", () => {
|
|
return PassAudio(input => {
|
|
const context = input.context;
|
|
const gain0 = context.createGain();
|
|
const gain1 = context.createGain();
|
|
const output = context.destination;
|
|
fanIn(gain0, gain1, input, output);
|
|
});
|
|
});
|
|
|
|
it("can connect one channel to another", () => {
|
|
return PassAudio(input => {
|
|
const context = input.context;
|
|
const output = input.context.destination;
|
|
const merge = context.createChannelMerger(2);
|
|
const split = context.createChannelSplitter(2);
|
|
connect(input, merge, 0, 1);
|
|
connect(merge, split, 0, 0);
|
|
connect(split, output, 1, 0);
|
|
});
|
|
});
|
|
|
|
it("can disconnect from an explicit channel", () => {
|
|
return PassAudio(input => {
|
|
const context = input.context;
|
|
const output = input.context.destination;
|
|
const merge = context.createChannelMerger(2);
|
|
const split = context.createChannelSplitter(2);
|
|
connect(input, merge, 0, 1);
|
|
connect(merge, split, 0, 0);
|
|
connect(split, output, 1, 0);
|
|
disconnect(split, output, 1, 0);
|
|
}, false);
|
|
});
|
|
|
|
it("can disconnect from an audio param", () => {
|
|
return Offline((context) => {
|
|
const osc = context.createOscillator();
|
|
const gain = context.createGain();
|
|
connect(gain, osc.frequency);
|
|
disconnect(gain, osc.frequency);
|
|
});
|
|
});
|
|
|
|
it("throws an error if things aren't connected", async () => {
|
|
let threwError = false;
|
|
await PassAudio(input => {
|
|
const output = input.context.destination;
|
|
disconnect(input, output);
|
|
}).catch(() => threwError = true);
|
|
expect(threwError).to.equal(true);
|
|
});
|
|
|
|
it("throws an error if the destination has no input", () => {
|
|
const source = new Oscillator();
|
|
const gain = new Gain();
|
|
expect(() => {
|
|
gain.connect(source);
|
|
}).to.throw(Error);
|
|
gain.dispose();
|
|
source.dispose();
|
|
});
|
|
|
|
it("throws an error if things aren't connected to a specific channel", async () => {
|
|
let threwError = false;
|
|
await PassAudio(input => {
|
|
const context = input.context;
|
|
const output = input.context.destination;
|
|
const merge = context.createChannelMerger(2);
|
|
const split = context.createChannelSplitter(2);
|
|
connect(input, merge, 0, 1);
|
|
connect(merge, split, 0, 0);
|
|
connect(split, output, 1, 0);
|
|
disconnect(split, output, 0, 0);
|
|
}).catch(() => threwError = true);
|
|
expect(threwError).to.equal(true);
|
|
});
|
|
});
|
|
|
|
context("ToneAudioNode", () => {
|
|
it("can create a connection", async () => {
|
|
await Offline(() => {
|
|
const input = new Gain();
|
|
const output = new Gain();
|
|
const gain = new Gain();
|
|
connect(input, gain);
|
|
connect(gain, output);
|
|
});
|
|
});
|
|
|
|
it("can disconnect a node", async () => {
|
|
await Offline(() => {
|
|
const input = new Gain();
|
|
const output = new Gain();
|
|
const gain = new Gain();
|
|
connect(input, gain);
|
|
connect(gain, output);
|
|
disconnect(gain);
|
|
});
|
|
});
|
|
|
|
it("can disconnect a node explicitly", async () => {
|
|
await Offline(() => {
|
|
const input = new Gain();
|
|
const output = new Gain();
|
|
const gain = new Gain();
|
|
connect(input, gain);
|
|
connect(gain, output);
|
|
disconnect(gain, output);
|
|
});
|
|
});
|
|
|
|
it("can fan in multiple nodes to a destination", async () => {
|
|
await Offline(() => {
|
|
const output = new Gain();
|
|
const input0 = new Gain();
|
|
const input1 = new Gain();
|
|
const input2 = new Gain();
|
|
fanIn(input0, input1, input2, output);
|
|
});
|
|
});
|
|
});
|
|
|
|
});
|