Skip to content

Commit 7fc89a5

Browse files
committed
Added README.md
1 parent 4e9bb87 commit 7fc89a5

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

README.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# @react-midi/hooks
2+
3+
This package provides hooks for working with midi in your React app.
4+
5+
```
6+
npm install --save @react-midi/hooks
7+
```
8+
9+
### `useMIDI()`
10+
11+
`useMidi()` requests midi access using the browser's web midi api.
12+
It returns and array containing MIDI inputs and outputs, respectively, and updates anytime a connection to one of these changes (for example, if an input or output is disconnected or a connection is opened).
13+
14+
```js
15+
const App = () => {
16+
const [inputs, outputs] = useMIDI(); // Initially returns [[], []]
17+
};
18+
```
19+
20+
### `useMIDINote(input, {note?, channel?}?)`
21+
22+
`useMIDINote()` subscribes to both note on and note off midi messages, optionally filtered by note and/or channel.
23+
It returns an object `{on, note, velocity, channel}` reflecting the received midi message, updating when a new relevant message is received.
24+
25+
- `on` will be `true` for note on, and `false` for note off
26+
- `note` will be a MIDI number (60 = C4)
27+
- `velocity` will be an integer between 0 - 127
28+
29+
```js
30+
const App = () => {
31+
const [inputs, outputs] = useMIDI();
32+
if (inputs.length < 1) return <div>No MIDI Inputs</div>;
33+
return <MIDINoteLog input={inputs[0]} />;
34+
};
35+
36+
const MIDINoteLog = ({ input }) => {
37+
const event = useMIDINote(input, { channel: 1 }); // Intially returns {}
38+
const { on, note, velocity, channel } = event;
39+
return (
40+
<div>
41+
Note {note} {on ? 'on' : 'off'} ({velocity}) on channel {channel}
42+
</div>
43+
);
44+
};
45+
```
46+
47+
### `useMIDIControl(input, {control?, channel?}?)`
48+
49+
`useMIDIControl()` subscribes to a control change midi message, optionally filtered by control and/or channel.
50+
It returns an object `{value, control, channel}` reflecting the received midi message, updating when a new relevant message is received.
51+
52+
```js
53+
const App = () => {
54+
const [inputs, outputs] = useMIDI();
55+
if (inputs.length < 1) return <div>No MIDI Inputs</div>;
56+
return <MIDIControlLog input={inputs[0]} />;
57+
};
58+
59+
const MIDIControlLog = ({ input }) => {
60+
const control = useMIDIControl(input, { control: 15, channel: 1 }); // Initially returns {value: 0, control, channel}
61+
return <div>Value: {control.value}</div>;
62+
};
63+
```
64+
65+
### `useMIDIClock(input, division?)`
66+
67+
`useMIDIClock()` subscribes to the midi clock messages of a given input, with the option to specify a division.
68+
It returns the number of steps that have occured since the hook began receiving midi clock messages, as well as the play state.
69+
70+
The division argument can be used to update `steps` only when the number of steps recieved is evenly divisible by given `division`.
71+
A midi clock message is received 24 times for every quarter note, so if you only wanted to count quarter notes, you could use `useMIDIClock(input, 24)`
72+
73+
The play state is updated when the input receives a midi play or stop message.
74+
The steps are reset when the input receives a midi stop message.
75+
76+
```js
77+
const App = () => {
78+
const [inputs, outputs] = useMIDI();
79+
if (inputs.length < 1) return <div>No MIDI Inputs</div>;
80+
return <MIDIClock input={inputs[0]} />;
81+
};
82+
83+
const MIDIClock = ({ input }) => {
84+
const [step, isPlaying] = useMIDIClock(input, 12); // initially return [0, false]
85+
return <div>Eight notes since starting: {step}</div>;
86+
};
87+
```
88+
89+
### `useMIDIControls(input, controls, {channel?}?)`
90+
91+
`useMIDIControls()` subscribes to multiple control change midi message, optionally filtered by channel.
92+
It returns an array of integers representing the value of controls passed in with the `controls` argument, updating when a new relevant message is received.
93+
94+
```js
95+
const App = () => {
96+
const [inputs, outputs] = useMIDI();
97+
if (inputs.length < 1) return <div>No MIDI Inputs</div>;
98+
return <MIDIControlLog input={inputs[0]} />;
99+
};
100+
101+
const MIDIControlLog = ({ input }) => {
102+
const controls = [13, 14, 15];
103+
const values = useMIDIControls(input, controls, { channel: 1 }); // Intially returns [0, 0, 0]
104+
return (
105+
<div>
106+
{controls.map((control) => (
107+
<div>
108+
Control {control}: {values[controls]}
109+
</div>
110+
))}
111+
</div>
112+
);
113+
};
114+
```
115+
116+
### `useMIDINotes(input, {channel?}?)`
117+
118+
`useMIDINotes()` subscribes to both note on and note off midi messages, optionally filtered channel.
119+
It returns an array of active note objects (see above), updating when notes are played or released.
120+
121+
```js
122+
const App = () => {
123+
const [inputs, outputs] = useMIDI();
124+
if (inputs.length < 1) return <div>No MIDI Inputs</div>;
125+
return <MIDINoteLog input={inputs[0]} />;
126+
};
127+
128+
const MIDINoteLog = ({ input }) => {
129+
const notes = useMIDINotes(input, { channel: 1 }); // Intially returns []
130+
return (
131+
<div>Playing notes: {notes.map((n) => n.note).join(', ')} // Playing notes: 60, 72, 80</div>
132+
);
133+
};
134+
```
135+
136+
### `useMIDIMessage(input)`
137+
138+
`useMIDIMessage()` subscribes to the general midi message handler of a given input, updating everytime a message is received.
139+
140+
```js
141+
const App = () => {
142+
const [inputs, outputs] = useMIDI();
143+
if (inputs.length < 1) return <div>No MIDI Inputs</div>;
144+
return <MIDILog input={inputs[0]} />;
145+
};
146+
147+
const MIDINoteLog = ({ input }) => {
148+
const message = useMIDIMessage(input); // initially return {}
149+
return (
150+
<div>
151+
Message Data: {message.data ? message.data.join(', ') : ''} // Message Data: 144, 60,
152+
100 (Note On, Middle C, Velocity 100)
153+
</div>
154+
);
155+
};
156+
```
157+
158+
### `useMIDIOutput(output)`
159+
160+
`useMIDIOutput()` returns function that can be used to send data to the given output.
161+
162+
- `noteOn(note, velocity=127, channel=1)`: Sends a note on message to the output, defaulting to a velocity of 127 and channel 1.
163+
- `noteOff(note, velocity=127, channel=1)`: Sends a note of message to the output, defaulting to a velocity of 127 and channel 1.
164+
- `cc(value, control, channel=1)`: Sends a midi cc (control change) message to the output, defaulting to channel 1.
165+
166+
```js
167+
const App = () => {
168+
const [inputs, outputs] = useMIDI();
169+
if (inputs.length < 1) return <div>No MIDI Inputs</div>;
170+
return <MIDIButton output={inputs[0]} />;
171+
};
172+
173+
const MIDIButton = ({ output }) => {
174+
const { noteOn, noteOff } = useMIDIOutput(output);
175+
const handleClick = () => {
176+
noteOn(60); // Play middle C, using velocity and channel defaults
177+
setTimeout(() => noteOff(60), 200); // Wait 200ms and then trigger note off.
178+
};
179+
return <div onClick={handleClick}>Click me!</div>;
180+
};
181+
```

0 commit comments

Comments
 (0)