Skip to content

Commit f0f92fc

Browse files
committed
update synth examples
update monosynth inline examples to use note strings remove loadPreset from monosynth inline docs example update polysynth inline examples to use note strings add triggerAttack/Release examples update synth examples - click to play
1 parent 940f6fa commit f0f92fc

File tree

2 files changed

+208
-44
lines changed

2 files changed

+208
-44
lines changed

src/monosynth.js

Lines changed: 94 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,40 @@ define(function (require) {
55
var AudioVoice = require('audioVoice');
66

77
/**
8-
* An MonoSynth is used as a single voice for sound synthesis.
9-
* This is a class to be used in conjonction with the PolySynth
8+
* A MonoSynth is used as a single voice for sound synthesis.
9+
* This is a class to be used in conjunction with the PolySynth
1010
* class. Custom synthetisers should be built inheriting from
1111
* this class.
1212
*
1313
* @class p5.MonoSynth
1414
* @constructor
1515
* @example
1616
* <div><code>
17-
* var monosynth;
18-
* var x;
17+
* var monoSynth;
1918
*
2019
* function setup() {
21-
* monosynth = new p5.MonoSynth();
22-
* monosynth.play(45,1,x=0,1);
23-
* monosynth.play(49,1,x+=1,0.25);
24-
* monosynth.play(50,1,x+=0.25,0.25);
25-
* monosynth.play(49,1,x+=0.5,0.25);
26-
* monosynth.play(50,1,x+=0.25,0.25);
20+
* var cnv = createCanvas(100, 100);
21+
* cnv.mousePressed(playSynth);
22+
*
23+
* monoSynth = new p5.MonoSynth();
24+
*
25+
* textAlign(CENTER);
26+
* text('click to play', width/2, height/2);
27+
* }
28+
*
29+
* function playSynth() {
30+
* // time from now (in seconds)
31+
* var time = 0;
32+
* // note duration (in seconds)
33+
* var dur = 0.25;
34+
* // velocity (volume, from 0 to 1)
35+
* var v = 0.2;
36+
*
37+
* monoSynth.play("G3", v, time, dur);
38+
* monoSynth.play("C4", v, time += dur, dur);
39+
*
40+
* background(random(255), random(255), 255);
41+
* text('click to play', width/2, height/2);
2742
* }
2843
* </code></div>
2944
**/
@@ -66,20 +81,49 @@ define(function (require) {
6681
p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);
6782

6883
/**
69-
* Play tells the MonoSynth to start playing a note. This method schedules
70-
* the calling of .triggerAttack and .triggerRelease.
71-
*
72-
* @method play
73-
* @param {String | Number} note the note you want to play, specified as a
74-
* frequency in Hertz (Number) or as a midi
75-
* value in Note/Octave format ("C4", "Eb3"...etc")
76-
* See <a href = "https://github.com/Tonejs/Tone.js/wiki/Instruments">
77-
* Tone</a>. Defaults to 440 hz.
78-
* @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)
79-
* @param {Number} [secondsFromNow] time from now (in seconds) at which to play
80-
* @param {Number} [sustainTime] time to sustain before releasing the envelope
81-
*
82-
*/
84+
* Play tells the MonoSynth to start playing a note. This method schedules
85+
* the calling of .triggerAttack and .triggerRelease.
86+
*
87+
* @method play
88+
* @param {String | Number} note the note you want to play, specified as a
89+
* frequency in Hertz (Number) or as a midi
90+
* value in Note/Octave format ("C4", "Eb3"...etc")
91+
* See <a href = "https://github.com/Tonejs/Tone.js/wiki/Instruments">
92+
* Tone</a>. Defaults to 440 hz.
93+
* @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)
94+
* @param {Number} [secondsFromNow] time from now (in seconds) at which to play
95+
* @param {Number} [sustainTime] time to sustain before releasing the envelope
96+
* @example
97+
* <div><code>
98+
* var monoSynth;
99+
*
100+
* function setup() {
101+
* var cnv = createCanvas(100, 100);
102+
* cnv.mousePressed(playSynth);
103+
*
104+
* monoSynth = new p5.MonoSynth();
105+
*
106+
* textAlign(CENTER);
107+
* text('click to play', width/2, height/2);
108+
* }
109+
*
110+
* function playSynth() {
111+
* // time from now (in seconds)
112+
* var time = 0;
113+
* // note duration (in seconds)
114+
* var dur = 1/6;
115+
* // note velocity (volume, from 0 to 1)
116+
* var v = random();
117+
*
118+
* monoSynth.play("Fb3", v, 0, dur);
119+
* monoSynth.play("Gb3", v, time += dur, dur);
120+
*
121+
* background(random(255), random(255), 255);
122+
* text('click to play', width/2, height/2);
123+
* }
124+
* </code></div>
125+
*
126+
*/
83127
p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {
84128
// set range of env (TO DO: allow this to be scheduled in advance)
85129
var susTime = susTime || this.sustain;
@@ -93,14 +137,26 @@ define(function (require) {
93137
* Similar to holding down a key on a piano, but it will
94138
* hold the sustain level until you let go.
95139
*
96-
* @param {String | Number} note the note you want to play, specified as a
97-
* frequency in Hertz (Number) or as a midi
140+
* @param {String | Number} note the note you want to play, specified as a
141+
* frequency in Hertz (Number) or as a midi
98142
* value in Note/Octave format ("C4", "Eb3"...etc")
99143
* See <a href = "https://github.com/Tonejs/Tone.js/wiki/Instruments">
100144
* Tone</a>. Defaults to 440 hz
101145
* @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)
102146
* @param {Number} [secondsFromNow] time from now (in seconds) at which to play
103147
* @method triggerAttack
148+
* @example
149+
* <div><code>
150+
* var monoSynth = new p5.MonoSynth();
151+
*
152+
* function mousePressed() {
153+
* monoSynth.triggerAttack("E3");
154+
* }
155+
*
156+
* function mouseReleased() {
157+
* monoSynth.triggerRelease();
158+
* }
159+
* </code></div>
104160
*/
105161
p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {
106162
var secondsFromNow = secondsFromNow || 0;
@@ -121,6 +177,18 @@ define(function (require) {
121177
*
122178
* @param {Number} secondsFromNow time to trigger the release
123179
* @method triggerRelease
180+
* @example
181+
* <div><code>
182+
* var monoSynth = new p5.MonoSynth();
183+
*
184+
* function mousePressed() {
185+
* monoSynth.triggerAttack("E3");
186+
* }
187+
*
188+
* function mouseReleased() {
189+
* monoSynth.triggerRelease();
190+
* }
191+
* </code></div>
124192
*/
125193
p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {
126194
var secondsFromNow = secondsFromNow || 0;

src/polysynth.js

Lines changed: 114 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)