synthing

a waveform sequencing synth on the web
Log | Files | Refs | Submodules

Polyphonic.js (2277B)


      1 import consts from './consts.js';
      2 import Envelope from 'envelope-generator';
      3 
      4 export default class Polyphonic {
      5     constructor(audioContext) {
      6         const masterVol = audioContext.createGain();
      7         masterVol.gain.value = 0.7;
      8         masterVol.connect(audioContext.destination);
      9         this.voices = {};
     10         this.audioContext = audioContext;
     11         this.periodicWave = null;
     12         this.masterVolume = masterVol;
     13     }
     14     setVolume(newVol) {
     15         this.masterVolume.gain.value = newVol;
     16     }
     17     addVoice(note, adsr) {
     18         this.voices[note.note] = this.voices[note.note] || [];
     19 
     20         let osc = this.audioContext.createOscillator();
     21         let gain = this.audioContext.createGain();
     22         let envelope = new Envelope(this.audioContext, {
     23             attackTime: adsr.attack,
     24             decayTime: adsr.decay,
     25             sustainLevel: adsr.sustain,
     26             releaseTime: adsr.release,
     27             maxLevel: 0.4
     28         });
     29 
     30         osc.frequency.value = note.frequency;
     31         gain.gain.setValueAtTime(0, 0)
     32         if (this.periodicWave) {
     33             osc.setPeriodicWave(this.periodicWave);
     34         }
     35 
     36         envelope.connect(gain.gain);
     37         osc.connect(gain);
     38         gain.connect(this.masterVolume);
     39 
     40         osc.start();
     41         envelope.start(this.audioContext.currentTime - 0.1);
     42 
     43         this.voices[note.note].push({
     44             note,
     45             osc,
     46             gain,
     47             envelope
     48         });
     49     }
     50     removeVoice(note) {
     51         const voiceList = this.voices[note.note];
     52         const voice = voiceList[voiceList.length - 1];
     53         voice.envelope.release(this.audioContext.currentTime);
     54         voice.osc.stop(voice.envelope.getReleaseCompleteTime());
     55         setTimeout(() => {
     56             voice.gain.disconnect();
     57             voiceList.splice(voiceList.indexOf(voice), 1);
     58         }, 1000 * (voice.envelope.getReleaseCompleteTime() - this.audioContext.currentTime));
     59     }
     60     changeWave(waveform) {
     61         if (waveform !== this.periodicWave) {
     62             this.periodicWave = waveform;
     63             for (let noteVoices in this.voices) {
     64                 for (let voice of this.voices[noteVoices]) {
     65                     voice.osc.setPeriodicWave(this.periodicWave);
     66                 }
     67             }
     68         }
     69     }
     70 }