Skip to content

Commit

Permalink
replacement of es5 functions to es6 classes feat p5.Pulse (#534)
Browse files Browse the repository at this point in the history
  • Loading branch information
endurance21 authored Aug 29, 2020
1 parent 838f3ac commit 2896d6e
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 132 deletions.
5 changes: 4 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ p5.FFT = FFT;
import './signal';
import './oscillator';
import './envelope';
import './pulse';
import Pulse from './pulse';
p5.Pulse = Pulse;
import './noise';

import AudioIn from './audioin';
Expand Down Expand Up @@ -71,9 +72,11 @@ import Compressor from './compressor';
p5.Compressor = Compressor;



import peakDetect from './peakDetect';
p5.peakDetect = peakDetect;


import SoundRecorder from './soundRecorder';
p5.SoundRecorder = SoundRecorder;

Expand Down
270 changes: 139 additions & 131 deletions src/pulse.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import p5sound from './master';
import './oscillator';
import Oscillator, { SawOsc } from './oscillator';

/**
* Creates a Pulse object, an oscillator that implements
Expand Down Expand Up @@ -45,150 +45,156 @@ import './oscillator';
* }
* </code></div>
*/
p5.Pulse = function (freq, w) {
p5.Oscillator.call(this, freq, 'sawtooth');

// width of PWM, should be betw 0 to 1.0
this.w = w || 0;

// create a second oscillator with inverse frequency
this.osc2 = new p5.SawOsc(freq);

// create a delay node
this.dNode = p5sound.audiocontext.createDelay();

// dc offset
this.dcOffset = createDCOffset();
this.dcGain = p5sound.audiocontext.createGain();
this.dcOffset.connect(this.dcGain);
this.dcGain.connect(this.output);
// set delay time based on PWM width
this.f = freq || 440;
var mW = this.w / this.oscillator.frequency.value;
this.dNode.delayTime.value = mW;
this.dcGain.gain.value = 1.7 * (0.5 - this.w);

// disconnect osc2 and connect it to delay, which is connected to output
this.osc2.disconnect();
this.osc2.panner.disconnect();
this.osc2.amp(-1); // inverted amplitude
this.osc2.output.connect(this.dNode);
this.dNode.connect(this.output);

this.output.gain.value = 1;
this.output.connect(this.panner);
};

p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);
class Pulse extends Oscillator {
constructor(freq, w) {
super(freq, 'sawtooth');

/**
* Set the width of a Pulse object (an oscillator that implements
* Pulse Width Modulation).
*
* @method width
* @param {Number} [width] Width between the pulses (0 to 1.0,
* defaults to 0)
*/
p5.Pulse.prototype.width = function (w) {
if (typeof w === 'number') {
if (w <= 1.0 && w >= 0.0) {
this.w = w;
// set delay time based on PWM width

// var mW = map(this.w, 0, 1.0, 0, 1/this.f);
var mW = this.w / this.oscillator.frequency.value;
this.dNode.delayTime.value = mW;
}
// width of PWM, should be betw 0 to 1.0
this.w = w || 0;

this.dcGain.gain.value = 1.7 * (0.5 - this.w);
} else {
w.connect(this.dNode.delayTime);
var sig = new p5.SignalAdd(-0.5);
sig.setInput(w);
sig = sig.mult(-1);
sig = sig.mult(1.7);
sig.connect(this.dcGain.gain);
}
};

p5.Pulse.prototype.start = function (f, time) {
var now = p5sound.audiocontext.currentTime;
var t = time || 0;
if (!this.started) {
var freq = f || this.f;
var type = this.oscillator.type;
this.oscillator = p5sound.audiocontext.createOscillator();
this.oscillator.frequency.setValueAtTime(freq, now);
this.oscillator.type = type;
this.oscillator.connect(this.output);
this.oscillator.start(t + now);

// set up osc2
this.osc2.oscillator = p5sound.audiocontext.createOscillator();
this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);
this.osc2.oscillator.type = type;
this.osc2.oscillator.connect(this.osc2.output);
this.osc2.start(t + now);
this.freqNode = [this.oscillator.frequency, this.osc2.oscillator.frequency];

// start dcOffset, too
// create a second oscillator with inverse frequency
this.osc2 = new SawOsc(freq);

// create a delay node
this.dNode = p5sound.audiocontext.createDelay();

// dc offset
this.dcOffset = createDCOffset();
this.dcGain = p5sound.audiocontext.createGain();
this.dcOffset.connect(this.dcGain);
this.dcOffset.start(t + now);
this.dcGain.connect(this.output);
// set delay time based on PWM width
this.f = freq || 440;
var mW = this.w / this.oscillator.frequency.value;
this.dNode.delayTime.value = mW;
this.dcGain.gain.value = 1.7 * (0.5 - this.w);

// disconnect osc2 and connect it to delay, which is connected to output
this.osc2.disconnect();
this.osc2.panner.disconnect();
this.osc2.amp(-1); // inverted amplitude
this.osc2.output.connect(this.dNode);
this.dNode.connect(this.output);

// if LFO connections depend on these oscillators
if (this.mods !== undefined && this.mods.frequency !== undefined) {
this.mods.frequency.connect(this.freqNode[0]);
this.mods.frequency.connect(this.freqNode[1]);
this.output.gain.value = 1;
this.output.connect(this.panner);
}

/**
* Set the width of a Pulse object (an oscillator that implements
* Pulse Width Modulation).
*
* @method width
* @param {Number} [width] Width between the pulses (0 to 1.0,
* defaults to 0)
*/
width(w) {
if (typeof w === 'number') {
if (w <= 1.0 && w >= 0.0) {
this.w = w;
// set delay time based on PWM width

// var mW = map(this.w, 0, 1.0, 0, 1/this.f);
var mW = this.w / this.oscillator.frequency.value;
this.dNode.delayTime.value = mW;
}

this.dcGain.gain.value = 1.7 * (0.5 - this.w);
} else {
w.connect(this.dNode.delayTime);
var sig = new p5.SignalAdd(-0.5); //repalce it with tones Signals Method
sig.setInput(w);
sig = sig.mult(-1);
sig = sig.mult(1.7);
sig.connect(this.dcGain.gain);
}
this.started = true;
this.osc2.started = true;
}
};

p5.Pulse.prototype.stop = function (time) {
if (this.started) {
var t = time || 0;
start(f, time) {
var now = p5sound.audiocontext.currentTime;
this.oscillator.stop(t + now);
if (this.osc2.oscillator) {
this.osc2.oscillator.stop(t + now);
var t = time || 0;
if (!this.started) {
var freq = f || this.f;
var type = this.oscillator.type;
this.oscillator = p5sound.audiocontext.createOscillator();
this.oscillator.frequency.setValueAtTime(freq, now);
this.oscillator.type = type;
this.oscillator.connect(this.output);
this.oscillator.start(t + now);

// set up osc2
this.osc2.oscillator = p5sound.audiocontext.createOscillator();
this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);
this.osc2.oscillator.type = type;
this.osc2.oscillator.connect(this.osc2.output);
this.osc2.start(t + now);
this.freqNode = [
this.oscillator.frequency,
this.osc2.oscillator.frequency,
];

// start dcOffset, too
this.dcOffset = createDCOffset();
this.dcOffset.connect(this.dcGain);
this.dcOffset.start(t + now);

// if LFO connections depend on these oscillators
if (this.mods !== undefined && this.mods.frequency !== undefined) {
this.mods.frequency.connect(this.freqNode[0]);
this.mods.frequency.connect(this.freqNode[1]);
}
this.started = true;
this.osc2.started = true;
}
this.dcOffset.stop(t + now);
this.started = false;
this.osc2.started = false;
}
};

p5.Pulse.prototype.freq = function (val, rampTime = 0, tFromNow = 0) {
if (typeof val === 'number') {
this.f = val;
var now = p5sound.audiocontext.currentTime;
var currentFreq = this.oscillator.frequency.value;
this.oscillator.frequency.cancelScheduledValues(now);
this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);
this.oscillator.frequency.exponentialRampToValueAtTime(
val,
tFromNow + rampTime + now
);
this.osc2.oscillator.frequency.cancelScheduledValues(now);
this.osc2.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);
this.osc2.oscillator.frequency.exponentialRampToValueAtTime(
val,
tFromNow + rampTime + now
);

if (this.freqMod) {
this.freqMod.output.disconnect();
this.freqMod = null;
stop(time) {
if (this.started) {
var t = time || 0;
var now = p5sound.audiocontext.currentTime;
this.oscillator.stop(t + now);
if (this.osc2.oscillator) {
this.osc2.oscillator.stop(t + now);
}
this.dcOffset.stop(t + now);
this.started = false;
this.osc2.started = false;
}
} else if (val.output) {
val.output.disconnect();
val.output.connect(this.oscillator.frequency);
val.output.connect(this.osc2.oscillator.frequency);
this.freqMod = val;
}
};

freq(val, rampTime = 0, tFromNow = 0) {
if (typeof val === 'number') {
this.f = val;
var now = p5sound.audiocontext.currentTime;
var currentFreq = this.oscillator.frequency.value;
this.oscillator.frequency.cancelScheduledValues(now);
this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);
this.oscillator.frequency.exponentialRampToValueAtTime(
val,
tFromNow + rampTime + now
);
this.osc2.oscillator.frequency.cancelScheduledValues(now);
this.osc2.oscillator.frequency.setValueAtTime(
currentFreq,
now + tFromNow
);
this.osc2.oscillator.frequency.exponentialRampToValueAtTime(
val,
tFromNow + rampTime + now
);

if (this.freqMod) {
this.freqMod.output.disconnect();
this.freqMod = null;
}
} else if (val.output) {
val.output.disconnect();
val.output.connect(this.oscillator.frequency);
val.output.connect(this.osc2.oscillator.frequency);
this.freqMod = val;
}
}
}

// inspiration: http://webaudiodemos.appspot.com/oscilloscope/
function createDCOffset() {
Expand All @@ -201,3 +207,5 @@ function createDCOffset() {
bufferSource.loop = true;
return bufferSource;
}

export default Pulse;

0 comments on commit 2896d6e

Please sign in to comment.