VCV Rack API v2
Loading...
Searching...
No Matches
midi.hpp
Go to the documentation of this file.
1#pragma once
2#include <dsp/common.hpp>
3#include <midi.hpp>
4
5
6namespace rack {
7namespace dsp {
8
9
13template <int CHANNELS>
15 int8_t vels[CHANNELS];
16 int8_t notes[CHANNELS];
17 bool gates[CHANNELS];
18 int8_t keyPressures[CHANNELS];
20 int8_t ccs[128];
21 int16_t pw;
22 bool clk;
23 bool start;
24 bool stop;
25 bool cont;
26 int64_t frame = -1;
27
29 reset();
30 }
31
32 void reset() {
33 for (int c = 0; c < CHANNELS; c++) {
34 vels[c] = 100;
35 notes[c] = 60;
36 gates[c] = false;
37 keyPressures[c] = -1;
38 }
39 channelPressure = -1;
40 for (int i = 0; i < 128; i++) {
41 ccs[i] = -1;
42 }
43 pw = 0x2000;
44 clk = false;
45 start = false;
46 stop = false;
47 cont = false;
48 }
49
50 void panic() {
51 reset();
52 // Send all note off commands
53 for (int note = 0; note <= 127; note++) {
54 // Note off
56 m.setStatus(0x8);
57 m.setNote(note);
58 m.setValue(0);
59 m.setFrame(frame);
60 onMessage(m);
61 }
62 }
63
65 void setVelocity(int8_t vel, int c) {
66 vels[c] = vel;
67 }
68
69 void setNoteGate(int8_t note, bool gate, int c) {
70 bool changedNote = gate && gates[c] && (note != notes[c]);
71 bool enabledGate = gate && !gates[c];
72 bool disabledGate = !gate && gates[c];
73 if (changedNote || disabledGate) {
74 // Note off
76 m.setStatus(0x8);
77 m.setNote(notes[c]);
78 m.setValue(vels[c]);
79 m.setFrame(frame);
80 onMessage(m);
81 }
82 if (changedNote || enabledGate) {
83 // Note on
85 m.setStatus(0x9);
86 m.setNote(note);
87 m.setValue(vels[c]);
88 m.setFrame(frame);
89 onMessage(m);
90 }
91 notes[c] = note;
92 gates[c] = gate;
93 }
94
95 void setKeyPressure(int8_t val, int c) {
96 if (keyPressures[c] == val)
97 return;
98 keyPressures[c] = val;
99 // Polyphonic key pressure
101 m.setStatus(0xa);
102 m.setNote(notes[c]);
103 m.setValue(val);
104 m.setFrame(frame);
105 onMessage(m);
106 }
107
108 void setChannelPressure(int8_t val) {
109 if (channelPressure == val)
110 return;
111 channelPressure = val;
112 // Channel pressure
114 m.setSize(2);
115 m.setStatus(0xd);
116 m.setNote(val);
117 m.setFrame(frame);
118 onMessage(m);
119 }
120
121 void setCc(int8_t cc, int id) {
122 if (ccs[id] == cc)
123 return;
124 ccs[id] = cc;
125 // Continuous controller
127 m.setStatus(0xb);
128 m.setNote(id);
129 m.setValue(cc);
130 m.setFrame(frame);
131 onMessage(m);
132 }
133
134 void setModWheel(int8_t cc) {
135 setCc(cc, 0x01);
136 }
137
138 void setVolume(int8_t cc) {
139 setCc(cc, 0x07);
140 }
141
142 void setBalance(int8_t cc) {
143 setCc(cc, 0x08);
144 }
145
146 void setPan(int8_t cc) {
147 setCc(cc, 0x0a);
148 }
149
150 void setSustainPedal(int8_t cc) {
151 setCc(cc, 0x40);
152 }
153
154 void setPitchWheel(int16_t pw) {
155 if (this->pw == pw)
156 return;
157 this->pw = pw;
158 // Pitch wheel
160 m.setStatus(0xe);
161 m.setNote(pw & 0x7f);
162 m.setValue((pw >> 7) & 0x7f);
163 m.setFrame(frame);
164 onMessage(m);
165 }
166
167 void setClock(bool clk) {
168 if (this->clk == clk)
169 return;
170 this->clk = clk;
171 if (clk) {
172 // Timing clock
174 m.setSize(1);
175 m.setStatus(0xf);
176 m.setChannel(0x8);
177 m.setFrame(frame);
178 onMessage(m);
179 }
180 }
181
182 void setStart(bool start) {
183 if (this->start == start)
184 return;
185 this->start = start;
186 if (start) {
187 // Start
189 m.setSize(1);
190 m.setStatus(0xf);
191 m.setChannel(0xa);
192 m.setFrame(frame);
193 onMessage(m);
194 }
195 }
196
197 void setContinue(bool cont) {
198 if (this->cont == cont)
199 return;
200 this->cont = cont;
201 if (cont) {
202 // Continue
204 m.setSize(1);
205 m.setStatus(0xf);
206 m.setChannel(0xb);
207 m.setFrame(frame);
208 onMessage(m);
209 }
210 }
211
212 void setStop(bool stop) {
213 if (this->stop == stop)
214 return;
215 this->stop = stop;
216 if (stop) {
217 // Stop
219 m.setSize(1);
220 m.setStatus(0xf);
221 m.setChannel(0xc);
222 m.setFrame(frame);
223 onMessage(m);
224 }
225 }
226
227 void setFrame(int64_t frame) {
228 this->frame = frame;
229 }
230
231 virtual void onMessage(const midi::Message& message) {}
232};
233
234
235} // namespace dsp
236} // namespace rack
Root namespace for the Rack API.
Definition AudioDisplay.hpp:9
Converts gates and CV to MIDI messages.
Definition midi.hpp:14
bool gates[CHANNELS]
Definition midi.hpp:17
void reset()
Definition midi.hpp:32
void setSustainPedal(int8_t cc)
Definition midi.hpp:150
void setChannelPressure(int8_t val)
Definition midi.hpp:108
void setContinue(bool cont)
Definition midi.hpp:197
void panic()
Definition midi.hpp:50
bool stop
Definition midi.hpp:24
bool cont
Definition midi.hpp:25
MidiGenerator()
Definition midi.hpp:28
void setPitchWheel(int16_t pw)
Definition midi.hpp:154
void setCc(int8_t cc, int id)
Definition midi.hpp:121
void setBalance(int8_t cc)
Definition midi.hpp:142
bool start
Definition midi.hpp:23
void setPan(int8_t cc)
Definition midi.hpp:146
int8_t notes[CHANNELS]
Definition midi.hpp:16
int16_t pw
Definition midi.hpp:21
void setNoteGate(int8_t note, bool gate, int c)
Definition midi.hpp:69
void setClock(bool clk)
Definition midi.hpp:167
void setFrame(int64_t frame)
Definition midi.hpp:227
void setVelocity(int8_t vel, int c)
Must be called before setNoteGate().
Definition midi.hpp:65
int8_t channelPressure
Definition midi.hpp:19
void setStop(bool stop)
Definition midi.hpp:212
bool clk
Definition midi.hpp:22
void setVolume(int8_t cc)
Definition midi.hpp:138
void setKeyPressure(int8_t val, int c)
Definition midi.hpp:95
int8_t ccs[128]
Definition midi.hpp:20
void setModWheel(int8_t cc)
Definition midi.hpp:134
int8_t keyPressures[CHANNELS]
Definition midi.hpp:18
void setStart(bool start)
Definition midi.hpp:182
int64_t frame
Definition midi.hpp:26
int8_t vels[CHANNELS]
Definition midi.hpp:15
virtual void onMessage(const midi::Message &message)
Definition midi.hpp:231
Definition midi.hpp:16
void setSize(int size)
Definition midi.hpp:31
void setFrame(int64_t frame)
Definition midi.hpp:85
void setValue(uint8_t value)
Definition midi.hpp:73
void setStatus(uint8_t status)
Definition midi.hpp:51
void setNote(uint8_t note)
Definition midi.hpp:62
void setChannel(uint8_t channel)
Definition midi.hpp:40