User:Pailiaq/common.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 5: | Line 5: | ||
var activeNodes = []; | var activeNodes = []; | ||
var activeBtn = null; | var activeBtn = null; | ||
var STORAGE_KEY = 'edoChordPlayTimbre'; | |||
var TIMBRES = ['triangle', 'sawtooth', 'square', 'sine']; | |||
var TIMBRE_LABELS = { triangle: 'Triangle', sawtooth: 'Sawtooth', square: 'Square', sine: 'Sine' }; | |||
var timbre = (function () { | |||
try { | |||
var saved = localStorage.getItem(STORAGE_KEY); | |||
return TIMBRES.indexOf(saved) >= 0 ? saved : 'triangle'; | |||
} catch (e) { return 'triangle'; } | |||
})(); | |||
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; | |||
}); | |||
} | |||
function getCtx() { | function getCtx() { | ||
| Line 31: | Line 51: | ||
if (c.state === 'suspended') c.resume(); | 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. | var attack = 0.02, sustain = 2.5, release = 1.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 39: | 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 58: | Line 78: | ||
}, totalDur * 1000); | }, totalDur * 1000); | ||
} | } | ||
} | |||
function injectSelectors() { | |||
var tables = new Set(); | |||
document.querySelectorAll('.edo-chord-play').forEach(function (btn) { | |||
var table = btn.closest('table'); | |||
if (table) tables.add(table); | |||
}); | |||
tables.forEach(function (table) { | |||
var firstTh = table.querySelector('th'); | |||
if (!firstTh || firstTh.querySelector('.edo-chord-timbre')) return; | |||
var sel = document.createElement('select'); | |||
sel.className = 'edo-chord-timbre'; | |||
sel.title = 'Synth timbre'; | |||
TIMBRES.forEach(function (t) { | |||
var opt = document.createElement('option'); | |||
opt.value = t; | |||
opt.textContent = TIMBRE_LABELS[t]; | |||
if (t === timbre) opt.selected = true; | |||
sel.appendChild(opt); | |||
}); | |||
sel.addEventListener('change', function () { setTimbre(sel.value); }); | |||
sel.addEventListener('click', function (e) { e.stopPropagation(); }); | |||
firstTh.innerHTML = ''; | |||
firstTh.appendChild(sel); | |||
}); | |||
} | } | ||
| Line 64: | Line 110: | ||
if (!btn) return; | if (!btn) return; | ||
e.preventDefault(); | e.preventDefault(); | ||
if (btn === activeBtn) { stopAll(); return; } | if (btn === activeBtn) { stopAll(); return; } | ||
var edo = parseInt(btn.dataset.edo, 10); | var edo = parseInt(btn.dataset.edo, 10); | ||
var steps = (btn.dataset.steps || '').split(',').map(Number); | var steps = (btn.dataset.steps || '').split(',').map(Number); | ||
| Line 78: | Line 124: | ||
} | } | ||
}); | }); | ||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', injectSelectors); | |||
} else { | |||
injectSelectors(); | |||
} | |||
}()); | }()); | ||