diff --git a/Gruntfile.js b/Gruntfile.js
index 92911303..6a4d63d8 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -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: {
diff --git a/src/app.js b/src/app.js
index 06a7da03..8171020a 100644
--- a/src/app.js
+++ b/src/app.js
@@ -24,6 +24,8 @@ define(function (require) {
require('soundRecorder');
require('peakdetect');
require('gain');
+ require('audiovoice');
+ require('polysynth');
return p5SOUND;
diff --git a/src/audiovoice.js b/src/audiovoice.js
new file mode 100644
index 00000000..f2e68bf1
--- /dev/null
+++ b/src/audiovoice.js
@@ -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
+ *
+ * ADSR envelope
+ * .
+ *
+ * @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 setRange
),
+ * 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);
+}
+
+});
diff --git a/src/polysynth.js b/src/polysynth.js
new file mode 100644
index 00000000..87f9acf6
--- /dev/null
+++ b/src/polysynth.js
@@ -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
+ *
+ * ADSR envelope
+ * .
+ *
+ * @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 setRange
),
+ * 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);
+}
+
+});