User:Pailiaq/common.js: Difference between revisions
No edit summary |
Tag: Undo |
||
| Line 3: | Line 3: | ||
var ctx = null; | var ctx = null; | ||
var | var activeNodes = []; | ||
var activeBtn = null; | var activeBtn = null; | ||
var STORAGE_KEY = 'edoChordPlayTimbre'; | var STORAGE_KEY = 'edoChordPlayTimbre'; | ||
var TIMBRES = ['triangle', 'sawtooth', 'square', 'sine']; | |||
var TIMBRE_LABELS = { triangle: 'Triangle', sawtooth: 'Sawtooth', square: 'Square', sine: 'Sine' }; | |||
var timbre = (function () { | |||
var | |||
try { | try { | ||
var saved = localStorage.getItem(STORAGE_KEY); | var saved = localStorage.getItem(STORAGE_KEY); | ||
return TIMBRES.indexOf(saved) >= 0 ? saved : 'triangle'; | |||
} catch (e) { | } catch (e) { return 'triangle'; } | ||
})(); | })(); | ||
function | function setTimbre(t) { | ||
if (TIMBRES.indexOf(t) < 0) return; | |||
timbre = t; | |||
try { localStorage.setItem(STORAGE_KEY, t); } catch (e) {} | |||
// Keep every selector on the page in sync | |||
document.querySelectorAll('.edo-chord-timbre').forEach(function (sel) { | |||
sel.value = t; | |||
try { localStorage.setItem(STORAGE_KEY, | }); | ||
document.querySelectorAll('.edo-chord-timbre').forEach(function ( | |||
} | } | ||
| Line 50: | Line 31: | ||
} | } | ||
function stopAll() { | function stopAll() { | ||
if (!ctx) return; | if (!ctx) return; | ||
var now = ctx.currentTime; | var now = ctx.currentTime; | ||
activeNodes.forEach(function (n) { | |||
try { | try { | ||
n.gain.gain.cancelScheduledValues(now); | n.gain.gain.cancelScheduledValues(now); | ||
| Line 86: | Line 42: | ||
} catch (e) {} | } catch (e) {} | ||
}); | }); | ||
activeNodes = []; | |||
if (activeBtn) { activeBtn.classList.remove('playing'); activeBtn = null; } | if (activeBtn) { activeBtn.classList.remove('playing'); activeBtn = null; } | ||
} | } | ||
function playChord(centsArr, btn) { | |||
function | stopAll(); | ||
var c = getCtx(); | var c = getCtx(); | ||
if (c.state === 'suspended') c.resume(); | |||
var now = c.currentTime; | var now = c.currentTime; | ||
var base = 261.63; | var base = 261.63; | ||
var attack = 0.02, sustain = 0.2, release = | var attack = 0.02, sustain = 0.2, release = 5; | ||
var totalDur = attack + sustain + release; | var totalDur = attack + sustain + release; | ||
var peak = 0.18 / Math.sqrt(centsArr.length); | var peak = 0.18 / Math.sqrt(centsArr.length); | ||
| Line 104: | Line 59: | ||
var osc = c.createOscillator(); | var osc = c.createOscillator(); | ||
var gain = c.createGain(); | var gain = c.createGain(); | ||
osc.type = | osc.type = timbre; | ||
osc.frequency.value = base * Math.pow(2, cents / 1200); | osc.frequency.value = base * Math.pow(2, cents / 1200); | ||
gain.gain.setValueAtTime(0, now); | gain.gain.setValueAtTime(0, now); | ||
| Line 113: | Line 68: | ||
osc.start(now); | osc.start(now); | ||
osc.stop(now + totalDur + 0.1); | osc.stop(now + totalDur + 0.1); | ||
activeNodes.push({ osc: osc, gain: gain }); | |||
}); | }); | ||
if (btn) { | if (btn) { | ||
btn.classList.add('playing'); | btn.classList.add('playing'); | ||
| Line 158: | Line 76: | ||
setTimeout(function () { | setTimeout(function () { | ||
if (activeBtn === btn) { btn.classList.remove('playing'); activeBtn = null; } | if (activeBtn === btn) { btn.classList.remove('playing'); activeBtn = null; } | ||
}, | }, totalDur * 1000); | ||
} | } | ||
} | } | ||
function injectSelectors() { | function injectSelectors() { | ||
var tables = new Set(); | var tables = new Set(); | ||
| Line 174: | Line 91: | ||
var sel = document.createElement('select'); | var sel = document.createElement('select'); | ||
sel.className = 'edo-chord-timbre'; | sel.className = 'edo-chord-timbre'; | ||
sel.title = 'Synth | sel.title = 'Synth timbre'; | ||
TIMBRES.forEach(function (t) { | TIMBRES.forEach(function (t) { | ||
var opt = document.createElement('option'); | var opt = document.createElement('option'); | ||
opt.value = t | opt.value = t; | ||
opt.textContent = t | opt.textContent = TIMBRE_LABELS[t]; | ||
if (t | if (t === timbre) opt.selected = true; | ||
sel.appendChild(opt); | |||
}); | }); | ||
sel.addEventListener('change', function () { setTimbre(sel.value); }); | sel.addEventListener('change', function () { setTimbre(sel.value); }); | ||