@@ -19,21 +19,39 @@ define(function (require) {
1919 * @param {Number } [synthVoice] A monophonic synth voice inheriting
2020 * the AudioVoice class. Defaults to p5.MonoSynth
2121 * @param {Number } [maxVoices] Number of voices, defaults to 8;
22- *
23- *
2422 * @example
2523 * <div><code>
26- * var polysynth;
24+ * var polySynth;
25+ *
2726 * function setup() {
28- * polysynth = new p5.PolySynth();
29- * polysynth.play(53,1,0,3);
30- * polysynth.play(60,1,0,2.9);
31- * polysynth.play(69,1,0,3);
32- * polysynth.play(71,1,0,3);
33- * polysynth.play(74,1,0,3);
27+ * var cnv = createCanvas(100, 100);
28+ * cnv.mousePressed(playSynth);
29+ *
30+ * polySynth = new p5.PolySynth();
31+ *
32+ * textAlign(CENTER);
33+ * text('click to play', width/2, height/2);
3434 * }
35- * </code></div>
3635 *
36+ * function playSynth() {
37+ * // note duration (in seconds)
38+ * var dur = 1.5;
39+ *
40+ * // time from now (in seconds)
41+ * var time = 0;
42+ *
43+ * // velocity (volume, from 0 to 1)
44+ * var vel = 0.1;
45+ *
46+ * // notes can overlap with each other
47+ * polySynth.play("G2", vel, 0, dur);
48+ * polySynth.play("C3", vel, time += 1/3, dur);
49+ * polySynth.play("G3", vel, time += 1/3, dur);
50+ *
51+ * background(random(255), random(255), 255);
52+ * text('click to play', width/2, height/2);
53+ * }
54+ * </code></div>
3755 **/
3856 p5 . PolySynth = function ( audioVoice , maxVoices ) {
3957 //audiovoices will contain maxVoices many monophonic synths
@@ -103,6 +121,38 @@ define(function (require) {
103121 * @param {Number } [velocity] velocity of the note to play (ranging from 0 to 1)
104122 * @param {Number } [secondsFromNow] time from now (in seconds) at which to play
105123 * @param {Number } [sustainTime] time to sustain before releasing the envelope
124+ * @example
125+ * <div><code>
126+ * var polySynth;
127+ *
128+ * function setup() {
129+ * var cnv = createCanvas(100, 100);
130+ * cnv.mousePressed(playSynth);
131+ *
132+ * polySynth = new p5.PolySynth();
133+ *
134+ * textAlign(CENTER);
135+ * text('click to play', width/2, height/2);
136+ * }
137+ *
138+ * function playSynth() {
139+ * // note duration (in seconds)
140+ * var dur = 0.1;
141+ *
142+ * // time from now (in seconds)
143+ * var time = 0;
144+ *
145+ * // velocity (volume, from 0 to 1)
146+ * var vel = 0.1;
147+ *
148+ * polySynth.play("G2", vel, 0, dur);
149+ * polySynth.play("C3", vel, 0, dur);
150+ * polySynth.play("G3", vel, 0, dur);
151+ *
152+ * background(random(255), random(255), 255);
153+ * text('click to play', width/2, height/2);
154+ * }
155+ * </code></div>
106156 */
107157 p5 . PolySynth . prototype . play = function ( note , velocity , secondsFromNow , susTime ) {
108158 var susTime = susTime || 1 ;
@@ -177,7 +227,25 @@ define(function (require) {
177227 * @param {Number } [note] midi note on which attack should be triggered.
178228 * @param {Number } [velocity] velocity of the note to play (ranging from 0 to 1)/
179229 * @param {Number } [secondsFromNow] time from now (in seconds)
230+ * @example
231+ * <div><code>
232+ * var polySynth = new p5.PolySynth();
233+ * var pitches = ["G", "D", "G", "C"];
234+ * var octaves = [2, 3, 4];
235+ *
236+ * function mousePressed() {
237+ * // play a chord: multiple notes at the same time
238+ * for (var i = 0; i < 4; i++) {
239+ * var note = random(pitches) + random(octaves);
240+ * polySynth.noteAttack(note, 0.1);
241+ * }
242+ * }
180243 *
244+ * function mouseReleased() {
245+ * // release all voices
246+ * polySynth.noteRelease();
247+ * }
248+ * </code></div>
181249 */
182250 p5 . PolySynth . prototype . noteAttack = function ( _note , _velocity , secondsFromNow ) {
183251 var now = p5sound . audiocontext . currentTime ;
@@ -266,25 +334,53 @@ define(function (require) {
266334 *
267335 * @method noteRelease
268336 * @param {Number } [note] midi note on which attack should be triggered.
337+ * If no value is provided, all notes will be released.
269338 * @param {Number } [secondsFromNow] time to trigger the release
339+ * @example
340+ * <div><code>
341+ * var pitches = ["G", "D", "G", "C"];
342+ * var octaves = [2, 3, 4];
343+ * var polySynth = new p5.PolySynth();
344+ *
345+ * function mousePressed() {
346+ * // play a chord: multiple notes at the same time
347+ * for (var i = 0; i < 4; i++) {
348+ * var note = random(pitches) + random(octaves);
349+ * polySynth.noteAttack(note, 0.1);
350+ * }
351+ * }
352+ *
353+ * function mouseReleased() {
354+ * // release all voices
355+ * polySynth.noteRelease();
356+ * }
357+ * </code></div>
270358 *
271359 */
272-
273360 p5 . PolySynth . prototype . noteRelease = function ( _note , secondsFromNow ) {
361+ var now = p5sound . audiocontext . currentTime ;
362+ var tFromNow = secondsFromNow || 0 ;
363+ var t = now + tFromNow ;
364+
365+ // if a note value is not provided, release all voices
366+ if ( ! _note ) {
367+ this . audiovoices . forEach ( function ( voice ) {
368+ voice . triggerRelease ( tFromNow )
369+ } ) ;
370+ this . _voicesInUse . setValueAtTime ( 0 , t ) ;
371+ for ( var n in this . notes ) {
372+ this . notes [ n ] . setValueAtTime ( null , t )
373+ }
374+ return ;
375+ }
376+
274377 //Make sure note is in frequency inorder to query the this.notes object
275378 var note = typeof _note === 'string' ? this . AudioVoice . prototype . _setNote ( _note )
276379 : typeof _note === 'number' ? _note : this . audiovoices [ this . _newest ] . oscillator . freq ( ) . value ;
277380
278- var now = p5sound . audiocontext . currentTime ;
279- var tFromNow = secondsFromNow || 0 ;
280- var t = now + tFromNow ;
281-
282-
283381 if ( this . notes [ note ] . getValueAtTime ( t ) === null ) {
284382 console . warn ( 'Cannot release a note that is not already playing' ) ;
285383 } else {
286-
287-
288384 //Find the scheduled change in this._voicesInUse that will be previous to this new note
289385 //subtract 1 and schedule this value at time 't', when this note will stop playing
290386 var previousVal = Math . max ( ~ ~ this . _voicesInUse . getValueAtTime ( t ) . value , 1 ) ;
0 commit comments