diff options
| author | Brian Cully <bjc@spork.org> | 2025-07-26 20:19:25 -0400 |
|---|---|---|
| committer | Brian Cully <bjc@spork.org> | 2025-07-26 20:19:25 -0400 |
| commit | 2d12e407ccac850dd2e1ce133a2f335677a2ef29 (patch) | |
| tree | 385946aa84f5e6ed251bfd22c380574c9caa98bb /player.mjs | |
| parent | c37f7d63ce3d67a22b0432c1085c080df4ffa819 (diff) | |
| download | chords-2d12e407ccac850dd2e1ce133a2f335677a2ef29.tar.gz chords-2d12e407ccac850dd2e1ce133a2f335677a2ef29.zip | |
whoops, missing files
Diffstat (limited to 'player.mjs')
| -rw-r--r-- | player.mjs | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/player.mjs b/player.mjs new file mode 100644 index 0000000..55ce64f --- /dev/null +++ b/player.mjs @@ -0,0 +1,66 @@ +import { Note, toCents } from './scale.mjs'; +import GuitarFuzz from './vend/guitar-fuzz.mjs'; +import Trombone from './vend/trombone.mjs'; + +const audioCtx = new AudioContext(); +const fuzzWave = new PeriodicWave(audioCtx, { + real: GuitarFuzz.real, + imag: GuitarFuzz.imag +}); +const tromboneWave = new PeriodicWave(audioCtx, { + real: Trombone.real, + imag: Trombone.imag +}); + +const globalGain = new GainNode(audioCtx, { gain: 0.06 }) + +export default class { + // oscillatornodes + notes = []; + + // offsets is an array of offsets in cents from A4. + constructor(offsets) { + console.debug('Player#constructor', this, offsets); + this.offsets = offsets; + + this.notes = offsets.map(o => + new OscillatorNode(audioCtx, { + frequency: 440, // a above middle c (c4) + detune: o, + // type: 'sine', + type: 'custom', + periodicWave: tromboneWave, + })); + + this.notes.forEach(n => n.connect(globalGain).connect(audioCtx.destination)); + } + + start() { + console.debug('Player#start', this); + this.notes.forEach(n => n.start()); + } + + stop() { + console.debug('Player#stop', this); + this.notes.forEach(n => n.stop()); + } + + test() { + const cNote = Note.fromString('C'); + console.assert(cNote.distanceTo(cNote) === 0); + const dNote = Note.fromString('D'); + console.assert(cNote.distanceTo(dNote) === 2); + const dSharpNote = Note.fromString('D♯'); + console.assert(cNote.distanceTo(dSharpNote) === 3); + + const aNote = Note.fromString('A', 'A to A'); + console.assert(toCents([aNote, 4], [aNote, 3]) === -1200); + const bNote = Note.fromString('B'); + console.assert(toCents([aNote, 4], [bNote, 4]) == 200, 'A4 to B4 is 200 cents'); + // E F F# G G# A + const eNote = Note.fromString('E'); + console.assert(toCents([aNote, 4], [eNote, 4]) === -500, 'E4 is 500 cents lower than A4'); + + console.assert(toCents([aNote, 4], [bNote, 3]) === -1000, 'A4 to B3 is 100 cents above -1200'); + } +} |
