|<- [[1.20 Fiddling with the filter]]|[[2.1 Learning outcomes]] ->| https://live.codecircle.com/d/hXaWcYsRyEwfHizNR index.html : exercice.js : function jouer_note ( contexte, frequence, enveloppe ) { /* joue une note donnée ContextAudio, Number, Object -> Void */ var instant = contexte.currentTime; var oscillateur = contexte.createOscillator(); oscillateur.frequency.value = frequence; var amplificateur = contexte.createGain(); amplificateur.gain.value = 0; // LFO : Low frequency Oscillator var lfo = contexte.createOscillator(); // amplificateur LFO var amplificateur_lfo = contexte.createGain(); amplificateur_lfo.gain.value = 400; lfo.frequency.value = 0.5; // on connecte notre lfo à l'entrée fréquence de notre oscillateur /* ┌—————┐ -1 à 1 ┌——————┐ -200 à 200 ┌—————┐ ┌———————————┐ │ LFO ├————————▸┤ gain.├—▸ entrée : fréquence —▸┤ osc.├—▸┤ audio out.│ │ osc.│ │ 200 │ └—————┘ └———————————┘ └—————┘ └——————┘ */ lfo.connect( amplificateur_lfo ); amplificateur_lfo.connect( oscillateur.frequency ); oscillateur.connect( amplificateur ); amplificateur.connect( contexte.destination ); //oscillateur.connect( amplificateur ); //amplificateur.connect( contexte.destination ); amplificateur.gain.linearRampToValueAtTime ( enveloppe.attaque.gain, instant + enveloppe.attaque.duree); amplificateur.gain.linearRampToValueAtTime ( enveloppe.chute.gain, instant + enveloppe.chute.duree); amplificateur.gain.linearRampToValueAtTime ( enveloppe.maintien.gain, instant + enveloppe.maintien.duree); amplificateur.gain.linearRampToValueAtTime ( enveloppe.extinction.gain, instant + enveloppe.extinction.duree); oscillateur.start(); lfo.start(); oscillateur.stop( instant + enveloppe.extinction.duree + 1 ); } function generer_enveloppe ( attaque_gain, attaque_duree, chute_gain, chute_duree, maintien_gain, maintien_duree, extinction_gain, extinction_duree ) { /* génère un objet figurant une enveloppe ADSR */ var adsr = {}; adsr.attaque = {}; adsr.chute = {}; adsr.maintien = {}; adsr.extinction = {}; adsr.attaque.gain = attaque_gain; adsr.attaque.duree = attaque_duree; adsr.chute.gain = chute_gain; adsr.chute.duree = adsr.attaque.duree + chute_duree; adsr.maintien.gain = maintien_gain; adsr.maintien.duree = adsr.chute.duree + maintien_duree; adsr.extinction.gain = extinction_gain; adsr.extinction.duree = adsr.maintien.duree + extinction_duree; return adsr; } // correspondances touche/note var notes = { a: 261.63, // C4 z: 293.66, // D4 e: 329.63, // E4 r: 349.23, // F4 t: 392.00, // G4 y: 440.00, // A4 u: 493.88, // B4 q: 523.25, // C5 s: 587.33, // D5 d: 659.25, // E5 f: 698.46, // F5 g: 783.99, // G5 h: 880.00, // A5 j: 987.77, // B5 }; var contexte_audio = window.AudioContext || window.webkitAudioContext; var contexte = new contexte_audio(); var enveloppe = generer_enveloppe ( 0.08, 0.25, 0.04, 0.1, 0.04, 0.5, 0, 0.15 ); document.addEventListener( 'keyup', function ( evenement ) { // on récupère la touche qui a été relâchée var touche = evenement.key; if ( notes[ touche ] ) { jouer_note( contexte, notes[ touche ], enveloppe ); } }, false);