Tone.js/Tone/core/Connect.ts
2019-06-23 14:46:59 -04:00

114 lines
3.5 KiB
TypeScript

import { InputNode, OutputNode, ToneAudioNode } from "./context/ToneAudioNode";
import { isArray, isDefined, isNumber } from "./util/TypeCheck";
/**
* connect together all of the arguments in series
* @param nodes
*/
export function connectSeries(...nodes: InputNode[]): void {
const first = nodes.shift();
nodes.reduce((prev, current) => {
if (prev instanceof ToneAudioNode || prev instanceof AudioNode) {
connect(prev, current);
}
return current;
}, first);
}
/**
* Connect two nodes together so that signal flows from the
* first node to the second. Optionally specify the input and output channels.
* @param srcNode The source node
* @param dstNode The destination node
* @param outputNumber The output channel of the srcNode
* @param inputNumber The input channel of the dstNode
*/
export function connect(srcNode: OutputNode, dstNode: InputNode, outputNumber = 0, inputNumber = 0): void {
// resolve the input of the dstNode
while (!(dstNode instanceof AudioNode || dstNode instanceof AudioParam)) {
if (isArray(dstNode.input)) {
this.assert(dstNode.input.length < inputNumber, "the output number is greater than the number of outputs");
dstNode = dstNode.input[inputNumber];
} else if (isDefined(dstNode.input)) {
dstNode = dstNode.input;
}
inputNumber = 0;
}
if (srcNode instanceof ToneAudioNode) {
if (isArray(srcNode.output)) {
this.assert(srcNode.output.length < outputNumber, "the output number is greater than the number of outputs");
srcNode = srcNode.output[outputNumber];
} else if (isDefined(srcNode.output)) {
srcNode = srcNode.output;
}
outputNumber = 0;
}
// make the connection
if (dstNode instanceof AudioParam) {
srcNode.connect(dstNode, outputNumber);
} else {
srcNode.connect(dstNode, outputNumber, inputNumber);
}
}
/**
* Disconnect a node from all nodes or optionally include a destination node and input/output channels.
* @param srcNode The source node
* @param dstNode The destination node
* @param outputNumber The output channel of the srcNode
* @param inputNumber The input channel of the dstNode
*/
export function disconnect(
srcNode: OutputNode,
dstNode?: InputNode,
outputNumber = 0,
inputNumber = 0,
): void {
// resolve the destination node
if (isDefined(dstNode)) {
while (dstNode instanceof ToneAudioNode) {
if (isArray(dstNode.input)) {
if (isNumber(inputNumber)) {
this.assert(dstNode.input.length < inputNumber, "the input number is greater than the number of inputs");
dstNode = dstNode.input[inputNumber];
} else {
// disconnect from all of the nodes
// since we don't know which one was connected
dstNode.input.forEach(dst => {
try {
// catch errors from disconnecting from nodes that are not connected
disconnect(srcNode, dst, outputNumber);
// tslint:disable-next-line: no-empty
} catch (e) { }
});
}
inputNumber = 0;
} else if (dstNode.input) {
dstNode = dstNode.input;
}
}
}
// resolve the src node
while (!(srcNode instanceof AudioNode)) {
if (isArray(srcNode.output)) {
this.assert(srcNode.output.length < outputNumber, "the output number is greater than the number of outputs");
srcNode = srcNode.output[outputNumber];
} else if (isDefined(srcNode.output)) {
srcNode = srcNode.output;
}
outputNumber = 0;
}
if (dstNode instanceof AudioParam) {
srcNode.disconnect(dstNode, outputNumber);
} else if (dstNode instanceof AudioNode) {
srcNode.disconnect(dstNode, outputNumber, inputNumber);
} else {
srcNode.disconnect();
}
}