summaryrefslogtreecommitdiffstats
path: root/player.mjs
blob: 55ce64f722f2c8b35c1c56debf574d805dd671a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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');
    }
}