Skip to content

Commit

Permalink
adding audiovoice and polysynth class for polyphonic synths
Browse files Browse the repository at this point in the history
  • Loading branch information
b2renger committed Mar 7, 2016
1 parent 0db7563 commit 37a1a93
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 1 deletion.
4 changes: 3 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ module.exports = function(grunt) {
'signal': 'src/signal',
'metro': 'src/metro',
'peakdetect': 'src/peakDetect',
'gain': 'src/gain'
'gain': 'src/gain',
'audiovoice': 'src/audiovoice',
'polysynth': 'src/polysynth'
},
useStrict: true,
wrap: {
Expand Down
2 changes: 2 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ define(function (require) {
require('soundRecorder');
require('peakdetect');
require('gain');
require('audiovoice');
require('polysynth');

return p5SOUND;

Expand Down
128 changes: 128 additions & 0 deletions src/audiovoice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
define(function (require) {
'use strict';

var p5sound = require('master');
require('sndcore');

/**
* An AudioVoice is used as a single voice for sound synthesis.
*
* @class p5.AudioVoice
* @constructor
*
* This is a class to be used in conjonction with the PolySynth
* class. Custom synthetisers should be built inheriting from
* this class.
**/

p5.AudioVoice = function (){

this.osctype = 'sine';
this.volume= 0.33;
this.note = 60;

this.attack = 0.25;
this.decay=0.25;
this.sustain=0.95;
this.release=0.25;
this.env = new p5.Env(this.attack,this.volume, this.decay,this.volume, this.sustain, this.volume,this.release);

this.filter = new p5.LowPass();
this.filter.set(22050, 5);

this.env.connect(this.filter);

}


/**
* Play the envelopp
*
* @method voicePlay
*/

p5.AudioVoice.prototype.voicePlay = function (){
this.env.play(this.filter);
}

/**
* Trigger the attack
*
* @method attackPlay
*/
p5.AudioVoice.prototype.attackPlay = function (){
this.env.triggerAttack(this.oscillator);
}

/**
* Trigger the release
*
* @method releasePlay
*/

p5.AudioVoice.prototype.releasePlay = function (){
this.env.triggerRelease(this.oscillator);
}

/**
* Set the note to be played.
* This method can be overriden when creating custom synth
*
* @method setNote
* @param {Number} Midi note to be played (from 0 to 127).
*
*/

p5.AudioVoice.prototype.setNote = function(note){
this.oscillator.freq(midiToFreq(note));
}

/**
* Set cutoms parameters to a specific synth implementation.
* This method does nothing by default unless you implement
* something for it.
* For instance if you want to build a complex synthetiser
* with one or more filters, effects etc. this is where you
* will want to set them.
*
* @method setParams
* @param
*
*/

p5.AudioVoice.prototype.setParams = function(params){

}

/**
* Set values like a traditional
* <a href="https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg">
* ADSR envelope
* </a>.
*
* @method setADSR
* @param {Number} attackTime Time (in seconds before envelope
* reaches Attack Level
* @param {Number} [decayTime] Time (in seconds) before envelope
* reaches Decay/Sustain Level
* @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,
* where 1.0 = attackLevel, 0.0 = releaseLevel.
* The susRatio determines the decayLevel and the level at which the
* sustain portion of the envelope will sustain.
* For example, if attackLevel is 0.4, releaseLevel is 0,
* and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is
* increased to 1.0 (using <code>setRange</code>),
* then decayLevel would increase proportionally, to become 0.5.
* @param {Number} [releaseTime] Time in seconds from now (defaults to 0)
**/

p5.AudioVoice.prototype.setADSR = function (a,d,s,r){
this.attack = a;
this.decay=d;
this.sustain=s;
this.release=r;
this.env = new p5.Env(this.attack, this.decay, this.sustain, this.release);
this.env.play(this.filter);
}

});
101 changes: 101 additions & 0 deletions src/polysynth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
define(function (require) {
'use strict';

var p5sound = require('master');
require('sndcore');
require('audiovoice');

/**
* An AudioVoice is used as a single voice for sound synthesis.
* The PolySynth class holds an array of AudioVoice, and deals
* with voices allocations, with setting notes to be played, and
* parameters to be set.
*
* @class p5.PolySynth
* @constructor
* @param {Number} [num] Number of voices used by the polyphonic
* synthetiser.
*
* @param {Number} [synthVoice] A monophonic synth voice inheriting
* the AudioVoice class.
**/

p5.PolySynth = function(num,synthVoice){
this.voices = [];
this.num_voices = num;
this.poly_counter=0;

for (var i = 0 ; i < this.num_voices ; i++){
this.voices.push(new synthVoice());
}
}

/**
* Play a note.
*
* @method play
*/

p5.PolySynth.prototype.play = function (){
this.voices[this.poly_counter].voicePlay();
this.poly_counter += 1;
this.poly_counter = this.poly_counter % this.num_voices;
}


/**
* Set values like a traditional
* <a href="https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg">
* ADSR envelope
* </a>.
*
* @method setADSR
* @param {Number} attackTime Time (in seconds before envelope
* reaches Attack Level
* @param {Number} [decayTime] Time (in seconds) before envelope
* reaches Decay/Sustain Level
* @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,
* where 1.0 = attackLevel, 0.0 = releaseLevel.
* The susRatio determines the decayLevel and the level at which the
* sustain portion of the envelope will sustain.
* For example, if attackLevel is 0.4, releaseLevel is 0,
* and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is
* increased to 1.0 (using <code>setRange</code>),
* then decayLevel would increase proportionally, to become 0.5.
* @param {Number} [releaseTime] Time in seconds from now (defaults to 0)
**/

p5.PolySynth.prototype.setADSR = function (a,d,s,r){
this.voices[this.poly_counter].setADSR(a,d,s,r);
}

/**
* Set the note to be played.
* This method can be overriden when creating custom synth
*
* @method setNote
* @param {Number} Midi note to be played (from 0 to 127).
*
*/

p5.PolySynth.prototype.setNote = function (note){
this.voices[this.poly_counter].setNote(note);
}


/**
* Set cutoms parameters to a specific synth implementation
* with the help of JavaScript Object Notation (JSON).
*
* @method setParams
* @param JSON object
*
* For instance to set the detune parameter of a synth, call :
* setParams({detune: 15 });
*
*/
p5.PolySynth.prototype.setParams = function (params){
this.voices[this.poly_counter].setParams(params);
}

});

0 comments on commit 37a1a93

Please sign in to comment.