|<- [[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);