Skip to content

Commit fefe04f

Browse files
committed
restructed to trigger/release by note, added defaults
1 parent f16fe8e commit fefe04f

File tree

2 files changed

+98
-47
lines changed

2 files changed

+98
-47
lines changed

examples/synthpresets/sketch.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,45 @@ var polySynth;
33
var note;
44
var octave = 0;
55

6+
var keysDown={};
7+
68
function setup() {
79
// monoSynth = new p5.MonoSynth();
810
// monoSynth.loadPreset('punchyBass');
911

1012
polySynth = new p5.PolySynth(p5.MonoSynth, 4);
13+
1114
}
1215

1316
function keyPressed() {
14-
// monoSynth.triggerAttack(keyToMidi() + octave, 1 )
15-
// monoSynth.triggerAttack(keyToMidi() + octave, 1 )
16-
17-
18-
1917
//OCTAVEf
2018
if (keyCode === UP_ARROW) {
2119
octave +=12;
2220
} else if (keyCode === DOWN_ARROW) {
2321
octave -=12;
2422
}
2523
else {
26-
// monoSynth.play(keyToMidi() + octave, 1);
27-
polySynth.play(keyToMidi() + octave, 1, 0, 4);
24+
polySynth.noteAttack(keyToMidi() + octave);
25+
26+
if (keysDown[key] === undefined) {
27+
keysDown[key] = true;
28+
}
2829
}
2930
}
3031

31-
// function keyReleased() {
32-
// monoSynth.triggerRelease();
33-
// }
32+
function keyReleased() {
33+
Object.keys(keysDown).forEach(function(key) {
34+
if(!keyIsDown(key)){
35+
polySynth.noteRelease(keyToMidi(key) + octave);
36+
delete keysDown[key];
37+
}
38+
});
39+
}
3440

3541

36-
function keyToMidi() {
37-
switch (key) {
42+
function keyToMidi(keyboard) {
43+
var thisKey = typeof keyboard ==='undefined' ? key : keyboard
44+
switch (thisKey) {
3845
case 'A':
3946
return 60;
4047

src/polysynth.js

Lines changed: 79 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,19 @@ define(function (require) {
2929
this.audiovoices = [];
3030
this._voicesInUse = [];
3131

32+
this.notes = {};
33+
3234
this._newest = 0;
3335
this._oldest = 0;
3436

3537

3638
this.polyValue = polyValue || 8;
3739

38-
this.AudioVoice = audioVoice;
40+
this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;
3941

4042
this._voicesInUse = new TimelineSignal(0);
4143

42-
4344
this.allocateVoices();
44-
4545
p5sound.soundArray.push(this);
4646
};
4747

@@ -69,23 +69,30 @@ p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime){
6969
// this.voices[note].play(note,velocity, secondsFromNow, susTime);
7070

7171

72-
if(this._voicesInUse.value < this.polyValue) {
72+
// if(this._voicesInUse.value < this.polyValue) {
7373

74-
var currentVoice = this._voicesInUse.value;
75-
this.noteAttack(currentVoice, note, velocity, secondsFromNow);
76-
this.noteRelease(currentVoice, secondsFromNow + susTime);
77-
} else {
78-
if(this.audiovoices[this._oldest]._isOn) {
79-
this.noteRelease(this._oldest);
80-
}
81-
this.noteAttack(this._oldest, note, velocity, secondsFromNow);
82-
this.noteRelease(this._oldest, secondsFromNow + susTime);
74+
// var currentVoice = this._voicesInUse.value;
8375

84-
this._newest = this._oldest;
85-
this._oldest = ( this._oldest + 1 ) % (this.polyValue - 1);
86-
}
76+
// this.noteAttack(currentVoice, note, velocity, secondsFromNow);
77+
// this.noteRelease(currentVoice, secondsFromNow + susTime);
78+
79+
80+
81+
// } else {
82+
// if(this.audiovoices[this._oldest]._isOn) {
83+
// this.noteRelease(this._oldest);
84+
// }
8785

8886

87+
// this.noteAttack(this._oldest, note, velocity, secondsFromNow);
88+
// this.noteRelease(this._oldest, secondsFromNow + susTime);
89+
90+
// this._newest = this._oldest;
91+
// this._oldest = ( this._oldest + 1 ) % (this.polyValue - 1);
92+
// }
93+
94+
this.noteAttack(note, velocity, secondsFromNow);
95+
this.noteRelease(note, secondsFromNow + susTime);
8996

9097
// this.noteAttack(this._newest, note, velocity,secondsFromNow);
9198
// this.noteRelease(this._newest, secondsFromNow+susTime);
@@ -120,11 +127,11 @@ p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime){
120127
**/
121128

122129
p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r){
123-
if(this.voices[note] == null){
124-
this.voices[note] = new this.AudioVoice();
125-
}
126-
this.voices[note]._setNote(note);
127-
this.voices[note].setADSR(a,d,s,r);
130+
if(this.voices[note] == null){
131+
this.voices[note] = new this.AudioVoice();
132+
}
133+
this.voices[note]._setNote(note);
134+
this.voices[note].setADSR(a,d,s,r);
128135
}
129136

130137
/**
@@ -138,23 +145,49 @@ p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r){
138145
* @param {Number} [secondsFromNow] time from now (in seconds)
139146
*
140147
*/
141-
p5.PolySynth.prototype.noteAttack = function (voice, note, velocity, secondsFromNow){
148+
p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow){
142149
var now = p5sound.audiocontext.currentTime;
143150
var tFromNow = secondsFromNow || 0;
144151
var t = now + tFromNow;
152+
153+
var note = _note === undefined ? 60 : _note;
154+
var velocity = _velocity === undefined ? 1 : _velocity;
155+
156+
var currentVoice;
157+
158+
if (this.notes[note] !== undefined) {
159+
// this.audiovoices[this.notes[note]].triggerRelease();
160+
this.noteRelease(note,0);
161+
}
162+
163+
164+
if(this._voicesInUse.value < this.polyValue) {
165+
currentVoice = this._voicesInUse.value;
166+
} else {
167+
currentVoice = this._oldest;
168+
169+
// this._newest = this._oldest;
170+
//
171+
var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);
172+
this.noteRelease(oldestNote);
173+
this._oldest = ( this._oldest + 1 ) % (this.polyValue - 1);
174+
}
175+
176+
this.notes[note] = currentVoice;
177+
145178
this._voicesInUse.setValueAtTime(this._voicesInUse.value + 1, t);
146179

147-
this._newest = voice;
148-
this.audiovoices[voice].triggerAttack(note, velocity, secondsFromNow);
149-
this.audiovoices[voice]._isOn = true;
180+
this._newest = currentVoice;
181+
182+
this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);
150183

151184
// if(this.voices[note] == null){
152185
// this.voices[note] = new this.AudioVoice();
153186
// }
154187
// this.voices[note]._setNote(note);
155188
// this.voices[note].env.setRange(velocity,0);
156189
// this.voices[note].triggerAttack(secondsFromNow);
157-
}
190+
};
158191

159192
/**
160193
* Trigger the Release of a MonoSynth. This is similar to releasing
@@ -167,16 +200,27 @@ p5.PolySynth.prototype.noteAttack = function (voice, note, velocity, secondsFrom
167200
*
168201
*/
169202

170-
p5.PolySynth.prototype.noteRelease = function (voice,secondsFromNow){
171-
var now = p5sound.audiocontext.currentTime;
172-
var tFromNow = secondsFromNow || 0;
173-
var t = now + tFromNow;
174-
this._voicesInUse.setValueAtTime(this._voicesInUse.value - 1, t);
175-
176-
177-
this.audiovoices[voice].triggerRelease(secondsFromNow);
203+
p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow){
204+
var note = _note === undefined ?
205+
p5.prototype.freqToMidi(this.audiovoices[this._newest].oscillator.freq().value)
206+
: _note;
207+
208+
if (this.notes[_note] === undefined) {
209+
console.warn('Cannot release a note that is not already playing');
210+
} else {
211+
var now = p5sound.audiocontext.currentTime;
212+
var tFromNow = secondsFromNow || 0;
213+
var t = now + tFromNow;
214+
215+
216+
217+
this._voicesInUse.setValueAtTime(this._voicesInUse.value - 1, t);
218+
this.audiovoices[ this.notes[note] ].triggerRelease(secondsFromNow);
219+
this.notes[note] = undefined;
220+
221+
this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.polyValue - 1);
222+
}
178223

179-
this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.polyValue - 1);
180224
// if (this.voices[note] != null) {
181225
// this.voices[note]._setNote(note);
182226
// this.voices[note].triggerRelease(secondsFromNow);

0 commit comments

Comments
 (0)