import SimpleJSSynth from './simple-js-synth.js'; import * as pattern from './pattern.js'; const panel = document.getElementById('synth'); const enabled = document.getElementById('synth-enabled'); const freq = document.getElementById('synth-freq'); const poly = document.getElementById('synth-voices'); const optsPaste = document.getElementById('synth-opts-paste'); const optsReset = document.getElementById('synth-opts-reset'); const ctx = new window.AudioContext(); const opts = {}; const voices = []; const tones = []; export const getOptions = () => opts; export const setOptions = (o) => { Object.assign(opts, o); while (voices.length) voices.pop().destroy(); for (let i = 0; i < opts.polyphony; i++) voices.push(SimpleJSSynth(ctx.destination, opts)); }; enabled.onchange = () => { if (enabled.checked) ctx.resume(); else ctx.suspend(); panel.classList.toggle('controls--minimized', !enabled.checked); }; freq.onchange = () => { let frequency = +freq.value; if (!frequency || frequency < 1) frequency = 110; opts.frequency = frequency; }; poly.onchange = () => { let polyphony = +poly.value; if (!polyphony || polyphony < 1) polyphony = 1; setOptions({ polyphony }); }; optsPaste.onclick = () => { const json = window.prompt("Please paste the JSON from the right panel of the synth page:"); setOptions(JSON.parse(json)); }; optsReset.onclick = () => setOptions({ osc1type: "sine", osc1vol: 0.2, osc1tune: 0, osc2type: "square", osc2vol: 0.14, osc2tune: 12, osc3type: "sine", osc3vol: 0.05, osc3tune: -6.7, attack: 0, decay: 0.3, sustain: 0.5, susdecay: 5, cutoff: 36, frequency: 110, polyphony: 8, }); optsReset.onclick(); export const on = (key, note, vol=1) => { if (!enabled.checked) return; ctx.resume(); if (tones[key]?.note === note) return; off(key); const freq = opts.frequency * Math.pow(2, note / pattern.getLength()); const voice = voices.find(s => s.isReady()); if (!voice) return; voice.noteOn(freq, vol); tones[key] = off && { note, voice }; }; export const off = (key) => { tones[key]?.voice.noteOff(); delete tones[key]; }; export const isOn = (note) => Object.values(tones).some(t => t.note === note);