@@ -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 ) ;
29803028var noise ;
29813029noise = function ( ) {
0 commit comments