Skip to content

Commit d4a5dba

Browse files
authored
Merge branch 'main' into panner-fallback
2 parents 40d4a3c + 65e4824 commit d4a5dba

File tree

2 files changed

+57
-41
lines changed

2 files changed

+57
-41
lines changed

src/oscillator.js

+36-39
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,35 @@ import Panner from './panner';
77
// SIGNAL MATH FOR MODULATION //
88
// ========================== //
99

10-
// return sigChain(this, scale, thisChain, nextChain, Scale);
11-
function sigChain(o, mathObj, thisChain, nextChain, type) {
12-
var chainSource = o.oscillator;
13-
// if this type of math already exists in the chain, replace it
14-
for (var i in o.mathOps) {
15-
if (o.mathOps[i] instanceof type) {
16-
chainSource.disconnect();
17-
o.mathOps[i].dispose();
18-
thisChain = i;
19-
// assume nextChain is output gain node unless...
20-
if (thisChain < o.mathOps.length - 2) {
21-
nextChain = o.mathOps[i + 1];
22-
}
10+
function sigChain(nodes, newNode, nodeType, input, output) {
11+
var prevNode = null;
12+
var nextNode = null;
13+
var replacedNode = null;
14+
// If nodes already contains an node of type nodeType, replace that node
15+
// with newNode.
16+
for (var i = 0; i < nodes.length; i++) {
17+
if (nodes[i] instanceof nodeType) {
18+
prevNode = i === 0 ? input : nodes[i - 1];
19+
nextNode = i === nodes.length - 1 ? output : nodes[i + 1];
20+
replacedNode = nodes[i];
21+
nodes[i] = newNode;
22+
break;
2323
}
2424
}
25-
if (thisChain === o.mathOps.length - 1) {
26-
o.mathOps.push(nextChain);
25+
// Otherwise, add newMathOp to the end of mathOps.
26+
if (replacedNode === null) {
27+
prevNode = nodes.length === 0 ? input : nodes[nodes.length - 1];
28+
nextNode = output;
29+
nodes.push(newNode);
2730
}
28-
// assume source is the oscillator unless i > 0
29-
if (i > 0) {
30-
chainSource = o.mathOps[i - 1];
31+
// Connect the newMathOp to the previous and next nodes.
32+
prevNode.disconnect();
33+
if (replacedNode !== null) {
34+
replacedNode.disconnect();
35+
replacedNode.dispose();
3136
}
32-
chainSource.disconnect();
33-
chainSource.connect(mathObj);
34-
mathObj.connect(nextChain);
35-
o.mathOps[thisChain] = mathObj;
36-
return o;
37+
prevNode.connect(newNode);
38+
newNode.connect(nextNode);
3739
}
3840

3941
/**
@@ -137,8 +139,9 @@ class Oscillator {
137139

138140
this.panner = new Panner();
139141
this.output.connect(this.panner);
140-
//array of math operation signal chaining
141-
this.mathOps = [this.output];
142+
143+
// array of math operation signal chaining
144+
this.mathOps = [];
142145

143146
// add to the soundArray so we can dispose of the osc later
144147
p5sound.soundArray.push(this);
@@ -496,9 +499,8 @@ class Oscillator {
496499
*/
497500
add(num) {
498501
var add = new Add(num);
499-
var thisChain = this.mathOps.length - 1;
500-
var nextChain = this.output;
501-
return sigChain(this, add, thisChain, nextChain, Add);
502+
sigChain(this.mathOps, add, Add, this.oscillator, this.output);
503+
return this;
502504
}
503505
/**
504506
* Multiply the p5.Oscillator's output amplitude
@@ -513,9 +515,8 @@ class Oscillator {
513515
*/
514516
mult(num) {
515517
var mult = new Mult(num);
516-
var thisChain = this.mathOps.length - 1;
517-
var nextChain = this.output;
518-
return sigChain(this, mult, thisChain, nextChain, Mult);
518+
sigChain(this.mathOps, mult, Mult, this.oscillator, this.output);
519+
return this;
519520
}
520521

521522
/**
@@ -535,19 +536,15 @@ class Oscillator {
535536
scale(inMin, inMax, outMin, outMax) {
536537
var mapOutMin, mapOutMax;
537538
if (arguments.length === 4) {
538-
mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5; //find a way to get rid of p5.prototype ?
539-
mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5; //find a way to get rid of p5.prototype ?
539+
mapOutMin = p5.prototype.map(0, inMin, inMax, outMin, outMax);
540+
mapOutMax = p5.prototype.map(1, inMin, inMax, outMin, outMax);
540541
} else {
541542
mapOutMin = arguments[0];
542543
mapOutMax = arguments[1];
543544
}
544545
var scale = new Scale(mapOutMin, mapOutMax);
545-
var thisChain = this.mathOps.length - 1;
546-
var nextChain = this.output;
547-
return sigChain(this, scale, thisChain, nextChain, Scale);
548-
549-
// this.output.disconnect();
550-
// this.output.connect(scale)
546+
sigChain(this.mathOps, scale, Scale, this.oscillator, this.output);
547+
return this;
551548
}
552549
}
553550

test/tests/p5.Oscillator.js

+21-2
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,28 @@ describe('p5.Oscillator', function () {
289289
osc.amp(1);
290290
osc.freq(4);
291291
osc.start();
292-
osc.add(3).mult(5);
293-
osc.scale(0, 1, 0, 4);
292+
osc.add(3).mult(5).scale(0, 1, 0, 4);
293+
expect(osc.mathOps).to.be.an('array').of.length(3);
294+
expect(osc.mathOps[0].toString()).to.include('Add');
295+
expect(osc.mathOps[0]).to.have.property('value', 3);
296+
expect(osc.mathOps[1].toString()).to.include('Mult');
297+
expect(osc.mathOps[1]).to.have.property('value', 5);
298+
expect(osc.mathOps[2].toString()).to.include('Scale');
299+
expect(osc.mathOps[2]).to.have.property('min', 0);
300+
expect(osc.mathOps[2]).to.have.property('max', 4);
301+
osc.scale(-0.5, 1.5, 2, 6).mult(6).add(4);
302+
expect(osc.mathOps).to.be.an('array').of.length(3);
303+
expect(osc.mathOps[0].toString()).to.include('Add');
304+
expect(osc.mathOps[0]).to.have.property('value', 4);
305+
expect(osc.mathOps[1].toString()).to.include('Mult');
306+
expect(osc.mathOps[1]).to.have.property('value', 6);
307+
expect(osc.mathOps[2].toString()).to.include('Scale');
308+
expect(osc.mathOps[2]).to.have.property('min', 3);
309+
expect(osc.mathOps[2]).to.have.property('max', 5);
310+
// TODO: Assert using the name property rather than using toString
311+
// after upgrading Tone.js.
294312
});
313+
295314
it('can execute _onNewInput() hook on connected unit', function (done) {
296315
let osc = new p5.Oscillator();
297316
const gain = new p5.Gain();

0 commit comments

Comments
 (0)