File size: 2,869 Bytes
b0bfea8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { workletMessageType } from "./worklet_system/message_protocol/worklet_message.js";
import { KeyModifier, workletKeyModifierMessageType } from "./worklet_system/worklet_methods/worklet_key_modifier.js";

export class KeyModifierManager
{
    /**
     * @param synth {Synthetizer}
     */
    constructor(synth)
    {
        this.synth = synth;
        /**
         * The velocity override mappings for MIDI keys
         * @type {KeyModifier[][]}
         * @private
         */
        this._keyModifiers = [];
    }
    
    /**
     * @private
     * @param type {workletKeyModifierMessageType}
     * @param data {any}
     */
    _sendToWorklet(type, data)
    {
        this.synth.post({
            messageType: workletMessageType.keyModifierManager,
            messageData: [
                type,
                data
            ]
        });
    }
    
    /**
     * Modifies a single key
     * @param channel {number} the channel affected. Usually 0-15
     * @param midiNote {number} the MIDI note to change. 0-127
     * @param options {{
     *     velocity: number|undefined,
     *     patch: {
     *         bank: number,
     *         program: number
     *     }|undefined
     * }} the key's modifiers
     */
    addModifier(channel, midiNote, options)
    {
        const velocity = options?.velocity ?? -1;
        const program = options?.patch?.program ?? -1;
        const bank = options?.patch?.bank ?? -1;
        const mod = new KeyModifier(velocity, bank, program);
        if (this._keyModifiers[channel] === undefined)
        {
            this._keyModifiers[channel] = [];
        }
        this._keyModifiers[channel][midiNote] = mod;
        this._sendToWorklet(
            workletKeyModifierMessageType.addMapping,
            [channel, midiNote, mod]
        );
    }
    
    /**
     * Gets a key modifier
     * @param channel {number} the channel affected. Usually 0-15
     * @param midiNote {number} the MIDI note to change. 0-127
     * @returns {KeyModifier|undefined}
     */
    getModifier(channel, midiNote)
    {
        return this._keyModifiers?.[channel]?.[midiNote];
    }
    
    /**
     * Deletes a key modifier
     * @param channel {number} the channel affected. Usually 0-15
     * @param midiNote {number} the MIDI note to change. 0-127
     */
    deleteModifier(channel, midiNote)
    {
        this._sendToWorklet(
            workletKeyModifierMessageType.deleteMapping,
            [channel, midiNote]
        );
        if (this._keyModifiers[channel]?.[midiNote] === undefined)
        {
            return;
        }
        this._keyModifiers[channel][midiNote] = undefined;
    }
    
    /**
     * Clears ALL Modifiers
     */
    clearModifiers()
    {
        this._sendToWorklet(workletKeyModifierMessageType.clearMappings, undefined);
        this._keyModifiers = [];
    }
}