From d9be9dc9a0b72b08d5bfaf3803bb4c2ba1fb84d1 Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Mon, 28 Jul 2025 15:24:01 -0400 Subject: wip: get tones playing again --- player.mjs | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 15 deletions(-) (limited to 'player.mjs') diff --git a/player.mjs b/player.mjs index 070a8b7..988d5d6 100644 --- a/player.mjs +++ b/player.mjs @@ -14,34 +14,88 @@ const tromboneWave = new PeriodicWave(audioCtx, { const globalGain = new GainNode(audioCtx, { gain: 0.06 }) -export default class { +export default class extends HTMLElement { + static name = 'x-player' + static register() { + console.debug('Registering Element', this.name, this); + customElements.define(this.name, this); + } + // oscillatornodes notes = []; + getOffsets = () => []; + detuneParams = []; - // offsets is an array of offsets in cents from A4. - constructor(offsets) { - console.debug('Player#constructor', this, offsets); - this.offsets = offsets; + constructor() { + super(); + console.debug('Player#constructor', this); + } + + connectedCallback() { + this.querySelector('.volume').onchange = e => { + console.debug('vol changed', e, this.volume); + globalGain.setValueAtTime(0.1, audioCtx.currentTime); + globalGain.value = this.volume; + } + } + + get volume() { + return Number(this.querySelector('.volume').value); + } + + set volume(volume) { + console.debug('Player#volume()', this, volume); + this.querySelector('.volume').value = volume; + } - this.notes = offsets.map(o => - new OscillatorNode(audioCtx, { - frequency: 440, // a above middle c (c4) - detune: o, - // type: 'sine', - type: 'custom', - periodicWave: tromboneWave, - })); + get isPlaying() { + return this.classList.contains('playing'); + } + + // offsets is an array of offsets in cents from A4. + get offsets() { + console.debug('offsets getoffsets', this.getOffsets); + return this.getOffsets(); + } - this.notes.forEach(n => n.connect(globalGain).connect(audioCtx.destination)); + set isPlaying(isPlaying) { + console.debug('Player#isPlaying', this, isPlaying); + if (isPlaying) { + this.classList.add('playing'); + this.start(); + } else { + this.classList.remove('playing'); + this.stop(); + } } start() { console.debug('Player#start', this); - this.notes.forEach(n => n.start()); + for (let i = 0; i < this.offsets.length; i++) { + if (!this.notes[i]) { + const note = new OscillatorNode(audioCtx, { + frequency: 440, // a above middle c (c4) + // detune: o, + // type: 'sine', + type: 'custom', + periodicWave: tromboneWave, + }); + note.connect(globalGain).connect(audioCtx.destination); + note.start(); + this.notes[i] = note; + } + const note = this.notes[i]; + note.detune.setValueAtTime(this.offsets[i], audioCtx.currentTime); + } + for (let j = this.notes.length-1; j >= this.offsets.length; j--) { + this.notes[j].stop(); + delete this.notes[j]; + } } stop() { console.debug('Player#stop', this); this.notes.forEach(n => n.stop()); + this.notes = []; } } -- cgit v1.3