Skip to content

Commit d92ea99

Browse files
committed
tweaking pulse
1 parent 0d7494f commit d92ea99

File tree

3 files changed

+126
-27
lines changed

3 files changed

+126
-27
lines changed

lib/p5.sound.js

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2865,14 +2865,34 @@ pulse = function () {
28652865
* Pulse Width Modulation.
28662866
* The pulse is created with two oscillators.
28672867
* Accepts a parameter for frequency, and to set the
2868-
* width between the pulses. See <code>Oscillator</code>
2869-
* for a full list of methods.
2868+
* width between the pulses. See <a href="
2869+
* http://localhost:8888/p5js.org/reference/#/p5.Oscillator">
2870+
* <code>p5.Oscillator</code> for a full list of methods.
28702871
*
28712872
* @class p5.Pulse
28722873
* @constructor
28732874
* @param {Number} [freq] Frequency in oscillations per second (Hz)
28742875
* @param {Number} [w] Width between the pulses (0 to 1.0,
28752876
* defaults to 0)
2877+
* @example
2878+
* <div><code>
2879+
* var pulse;
2880+
* function setup() {
2881+
* background(0);
2882+
*
2883+
* // Create and start the pulse wave oscillator
2884+
* pulse = new p5.Pulse();
2885+
* pulse.amp(0.5);
2886+
* pulse.freq(220);
2887+
* pulse.start();
2888+
* }
2889+
*
2890+
* function draw() {
2891+
* var w = map(mouseX, 0, width, 0, 1);
2892+
* w = constrain(w, 0, 1);
2893+
* pulse.width(w)
2894+
* }
2895+
* </code></div>
28762896
*/
28772897
p5.Pulse = function (freq, w) {
28782898
p5.Oscillator.call(this, freq, 'sawtooth');
@@ -2882,12 +2902,29 @@ pulse = function () {
28822902
this.osc2 = new p5.SawOsc(freq);
28832903
// create a delay node
28842904
this.dNode = p5sound.audiocontext.createDelay();
2905+
// dc offset
2906+
this.dcOffset = createDCOffset();
2907+
this.dcGain = p5sound.audiocontext.createGain();
2908+
this.dcOffset.connect(this.dcGain);
2909+
this.dcGain.connect(this.output);
28852910
// set delay time based on PWM width
2886-
this.dNode.delayTime.value = map(this.w, 0, 1, 0, 1 / this.oscillator.frequency.value);
2911+
var mW = this.w / this.oscillator.frequency.value;
2912+
this.dNode.delayTime.setValueAtTime(mW, p5sound.audiocontext.currentTime);
2913+
this.dcGain.gain.value = 1.7 * (0.5 - this.w);
2914+
this.oscillator.disconnect();
2915+
this.newGain = p5sound.audiocontext.createGain();
2916+
this.newGain.gain.value = 1;
2917+
this.oscillator.connect(this.newGain);
2918+
this.newGain.connect(this.output);
28872919
// disconnect osc2 and connect it to delay, which is connected to output
28882920
this.osc2.disconnect();
2921+
this.osc2.output.gain.minValue = -10;
2922+
this.osc2.output.gain.maxValue = 10;
2923+
this.osc2.output.gain.value = -1;
2924+
// inverted amplitude
28892925
this.osc2.panner.connect(this.dNode);
28902926
this.dNode.connect(this.output);
2927+
this.output.connect(this.panner);
28912928
};
28922929
p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);
28932930
/**
@@ -2902,8 +2939,10 @@ pulse = function () {
29022939
if (w <= 1 && w >= 0) {
29032940
this.w = w;
29042941
// set delay time based on PWM width
2905-
this.dNode.delayTime.value = map(this.w, 0, 1, 0, 1 / this.oscillator.frequency.value);
2942+
var mW = this.w / this.oscillator.frequency.value;
2943+
this.dNode.delayTime.setValueAtTime(mW, p5sound.audiocontext.currentTime);
29062944
}
2945+
this.dcGain.gain.value = 1.7 * (0.5 - this.w);
29072946
};
29082947
p5.Pulse.prototype.start = function (f, time) {
29092948
var now = p5sound.audiocontext.currentTime;
@@ -2916,7 +2955,7 @@ pulse = function () {
29162955
this.oscillator.frequency.setValueAtTime(freq, now);
29172956
this.oscillator.type = type;
29182957
// this.oscillator.detune.value = detune;
2919-
this.oscillator.connect(this.output);
2958+
this.oscillator.connect(this.newGain);
29202959
this.oscillator.start(t + now);
29212960
// set up osc2
29222961
this.osc2.oscillator = p5sound.audiocontext.createOscillator();
@@ -2927,6 +2966,8 @@ pulse = function () {
29272966
this.oscillator.frequency,
29282967
this.osc2.oscillator.frequency
29292968
];
2969+
// start dcOffset, too
2970+
this.dcOffset.start(t + now);
29302971
// if LFO connections depend on these oscillators
29312972
if (this.mods !== undefined && this.mods.frequency !== undefined) {
29322973
this.mods.frequency.connect(this.freqNode[0]);
@@ -2942,6 +2983,7 @@ pulse = function () {
29422983
var now = p5sound.audiocontext.currentTime;
29432984
this.oscillator.stop(t + now);
29442985
this.osc2.oscillator.stop(t + now);
2986+
this.dcOffset.stop(t + now);
29452987
this.started = false;
29462988
this.osc2.started = false;
29472989
}
@@ -2959,12 +3001,6 @@ pulse = function () {
29593001
this.osc2.oscillator.frequency.cancelScheduledValues(now);
29603002
this.osc2.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);
29613003
this.osc2.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);
2962-
// disconnect if frequencies are too low or high, otherwise connect
2963-
// if (val < 20 || val > 20000) {
2964-
// this.panner.disconnect();
2965-
// } else {
2966-
// this.connect(this.connection);
2967-
// }
29683004
if (this.freqMod) {
29693005
this.freqMod.output.disconnect();
29703006
this.freqMod = null;
@@ -2976,6 +3012,18 @@ pulse = function () {
29763012
this.freqMod = val;
29773013
}
29783014
};
3015+
// inspiration: http://webaudiodemos.appspot.com/oscilloscope/
3016+
function createDCOffset() {
3017+
var ac = p5sound.audiocontext;
3018+
var buffer = ac.createBuffer(1, 1024, ac.sampleRate);
3019+
var data = buffer.getChannelData(0);
3020+
for (var i = 0; i < 1024; i++)
3021+
data[i] = 1;
3022+
var bufferSource = ac.createBufferSource();
3023+
bufferSource.buffer = buffer;
3024+
bufferSource.loop = true;
3025+
return bufferSource;
3026+
}
29793027
}(master, oscillator);
29803028
var noise;
29813029
noise = function () {

0 commit comments

Comments
 (0)