From f9d00d01bf37c2d4ea3ec32b01d59ddef9ac097e Mon Sep 17 00:00:00 2001 From: arnoson Date: Wed, 11 Oct 2023 10:13:06 +0200 Subject: [PATCH] feat: pass context to `onNote()` events closes #14 --- README.md | 21 +++++++++++++++++++++ src/hydra-api/onNote.ts | 4 ++-- src/midiAccess.ts | 4 ++-- src/state.ts | 4 ++-- src/transforms/channel.ts | 4 ++-- src/transforms/input.ts | 4 ++-- src/types.ts | 6 ++++++ 7 files changed, 37 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2f6195e..225973e 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,27 @@ myController = midi.input(3).channel(15) myController.onNote('c1', () => { osc().out() }) + +// or listen to all notes: +myController.onNote('*', ({ note, velocity, channel }) => { + osc().out() +}) +``` + +Or listen to any note: + +```js +myController = midi.input(3).channel('*') + +scene1 = () => solid(1,0,0).out() +scene2 = () => solid(0,1,0).out() + +myController.onNote('*', ({ note, velocity, channel }) => { + switch (note) { + case 36: { scene1(); break; } + case 37: { scene2(); break; } + } +}) ``` ### Transforms diff --git a/src/hydra-api/onNote.ts b/src/hydra-api/onNote.ts index 7bc9780..f40a6f5 100644 --- a/src/hydra-api/onNote.ts +++ b/src/hydra-api/onNote.ts @@ -1,12 +1,12 @@ import state from '../state' -import { ChannelArg, InputArg, NoteArg } from '../types' +import { ChannelArg, InputArg, NoteArg, NoteEventContext } from '../types' import { getNoteId } from './note' export const onNote = ( note: NoteArg, channel: ChannelArg, input: InputArg, - event: Function + event: (context: NoteEventContext) => void ) => { const noteId = getNoteId(note, channel, input) state.noteOnEvents.set(noteId, event) diff --git a/src/midiAccess.ts b/src/midiAccess.ts index 7a9c58c..8868f5e 100644 --- a/src/midiAccess.ts +++ b/src/midiAccess.ts @@ -79,12 +79,12 @@ midiAccess.on(MidiAccess.TypeNoteOn, ({ data, channel, input }) => { const noteId = getMidiId(note, channel, input.id) playingNotes.set(noteId, velocity) envelopes.get(noteId)?.trigger() - noteOnEvents.get(noteId)?.() + noteOnEvents.get(noteId)?.({ note, velocity, channel }) getMidiWildcards(note, channel, input.id).forEach(wildcard => { playingNotes.set(wildcard, velocity) envelopes.get(wildcard)?.trigger() - noteOnEvents.get(wildcard)?.() + noteOnEvents.get(wildcard)?.({ note, velocity, channel }) }) logMidiMessage({ input, type: 'on', channel, data }) diff --git a/src/state.ts b/src/state.ts index 65d0406..c58746d 100644 --- a/src/state.ts +++ b/src/state.ts @@ -1,4 +1,4 @@ -import type { CCValues, Defaults } from './types' +import type { CCValues, Defaults, NoteEventContext } from './types' const ccValues: CCValues = new Map( JSON.parse(sessionStorage.getItem('hydra-midi_ccValues') || '[]') @@ -17,7 +17,7 @@ export default { playingNotes: new Map(), - noteOnEvents: new Map(), + noteOnEvents: new Map void>(), defaults: { channel: '*', diff --git a/src/transforms/channel.ts b/src/transforms/channel.ts index d84b269..1d14758 100644 --- a/src/transforms/channel.ts +++ b/src/transforms/channel.ts @@ -1,7 +1,7 @@ import { cc } from '../hydra-api/cc' import { note } from '../hydra-api/note' import { onNote } from '../hydra-api/onNote' -import { ChannelArg, InputArg, NoteArg } from '../types' +import { ChannelArg, InputArg, NoteArg, NoteEventContext } from '../types' /** * Channel is chainable to `midi` and `input()` and provides a channel for all @@ -16,6 +16,6 @@ export const channel = (channel: ChannelArg, input?: InputArg) => ({ cc: (_index?: number, _channel?: ChannelArg, _input?: InputArg) => cc(_index, _channel ?? channel, _input ?? input), - onNote: (_note: NoteArg, _event: Function) => + onNote: (_note: NoteArg, _event: (context: NoteEventContext) => void) => onNote(_note, channel, input ?? '*', _event), }) diff --git a/src/transforms/input.ts b/src/transforms/input.ts index a0708d3..bae8cff 100644 --- a/src/transforms/input.ts +++ b/src/transforms/input.ts @@ -1,5 +1,5 @@ import { cc, note, onNote } from '../hydra-api' -import { ChannelArg, InputArg, NoteArg } from '../types' +import { ChannelArg, InputArg, NoteArg, NoteEventContext } from '../types' import { channel } from './channel' /** @@ -15,7 +15,7 @@ export const input = (input: InputArg) => ({ cc: (_index: number, _channel: ChannelArg, _input?: InputArg) => cc(_index, _channel, _input ?? input), - onNote: (_note: NoteArg, _event: Function) => + onNote: (_note: NoteArg, _event: (context: NoteEventContext) => void) => onNote(_note, '*', input, _event), channel: (_channel: ChannelArg) => channel(_channel, input), diff --git a/src/types.ts b/src/types.ts index 885f735..c233459 100644 --- a/src/types.ts +++ b/src/types.ts @@ -23,6 +23,12 @@ export interface HydraContext { } } +export interface NoteEventContext { + note: number + velocity: number + channel: number +} + export interface Defaults { input: InputArg channel: ChannelArg