EM MIDI Arduino Lib 1.0.1
Loading...
Searching...
No Matches
midi.cpp
1#include "midi.h"
2
3namespace em {
4
5Midi::Midi(Stream& stream) : stream_(stream) {
6}
7
8void Midi::NoteOn(const uint8_t channel, const uint8_t midi_note, const uint8_t note_velocity) {
9 const uint8_t command[] = {0x90 | (channel & 0x0F), midi_note & 0x7F, note_velocity & 0x7F};
10 Write(command, sizeof(command) / sizeof(command[0]));
11}
12
13void Midi::NoteOff(const uint8_t channel, const uint8_t midi_note) {
14 const uint8_t command[] = {0x80 | (channel & 0x0F), midi_note & 0x7F, 0x00};
15 Write(command, sizeof(command) / sizeof(command[0]));
16}
17
18void Midi::SetChannelTimbre(const uint8_t channel, const uint8_t bank, const uint8_t timbre) {
20 printf("Error: bank parameter error, can only be EM_MIDI_TIMBRE_BANK_0 or EM_MIDI_TIMBRE_BANK_127.\n");
21 return;
22 }
23
24 const uint8_t command_bank[] = {0xB0 | (channel & 0x0F), 0x00, bank};
25 Write(command_bank, sizeof(command_bank) / sizeof(command_bank[0]));
26
27 const uint8_t command_timbre[] = {0xC0 | (channel & 0x0F), timbre & 0x7F};
28 Write(command_timbre, sizeof(command_timbre) / sizeof(command_timbre[0]));
29}
30
31void Midi::PitchBend(const uint8_t channel, uint16_t pitch_bend_value) {
32 if (pitch_bend_value > 1023) {
33 pitch_bend_value = 1023;
34 }
35 pitch_bend_value = map(pitch_bend_value, 0, 1023, 0, 0x3FFF);
36 const uint8_t command[] = {0xE0 | (channel & 0x0F), pitch_bend_value & 0x7F, pitch_bend_value >> 7};
37 Write(command, sizeof(command) / sizeof(command[0]));
38}
39
40void Midi::PitchBendRange(const uint8_t channel, const uint8_t pitch_bend_range_value) {
41 SendNrpnOrRpnParameter(channel, 0x65, 0x00, 0x64, 0x00, pitch_bend_range_value);
42
43 NullNrpnOrRpn(channel, 0x65, 0x64);
44}
45
47 Write(0xFF);
48}
49
50void Midi::ChannelAllNotesOff(const uint8_t channel) {
51 const uint8_t command[] = {0xB0 | (channel & 0x0F), 0x7B, 0x00};
52 Write(command, sizeof(command) / sizeof(command[0]));
53}
54
55void Midi::SetChannelVolume(const uint8_t channel, const uint8_t volume) {
56 const uint8_t command[] = {0xB0 | (channel & 0x0F), 0x07, volume & 0x7F};
57 Write(command, sizeof(command) / sizeof(command[0]));
58}
59
60void Midi::SetAllChannelVolume(const uint8_t volume) {
61 const uint8_t command[] = {0xF0, 0x7F, 0x7F, 0x04, 0x01, 0x00, volume & 0x7F, 0xF7};
62 Write(command, sizeof(command) / sizeof(command[0]));
63}
64
65void Midi::SetReverberation(const uint8_t channel,
66 const uint8_t reverberation_type,
67 const uint8_t reverberation_volume,
68 const uint8_t delay_feedback) {
69 uint8_t command[] = {0xB0 | (channel & 0x0F), 0x50, reverberation_type & 0x07};
70 Write(command, sizeof(command) / sizeof(command[0]));
71
72 command[1] = 0x5B;
73 command[2] = reverberation_volume & 0x7F;
74 Write(command, sizeof(command) / sizeof(command[0]));
75
76 const uint8_t command_delay_feedback[] = {0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x35, delay_feedback & 0x7F, 0x00, 0xF7};
77 Write(command_delay_feedback, sizeof(command_delay_feedback) / sizeof(command_delay_feedback[0]));
78}
79
80void Midi::SetChorus(const uint8_t channel,
81 const uint8_t chorus_effect_type,
82 const uint8_t chorus_effect_volume,
83 const uint8_t chorus_effect_feedback,
84 const uint8_t chorus_delay_time) {
85 uint8_t command[] = {0xB0 | (channel & 0x0F), 0x51, chorus_effect_type & 0x07};
86 Write(command, sizeof(command) / sizeof(command[0]));
87
88 command[1] = 0x5D;
89 command[2] = chorus_effect_volume & 0x7F;
90 Write(command, sizeof(command) / sizeof(command[0]));
91
92 const uint8_t command_feedback[] = {0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x3B, chorus_effect_feedback & 0x7F, 0x00, 0xF7};
93 Write(command_feedback, sizeof(command_feedback) / sizeof(command_feedback[0]));
94
95 const uint8_t command_chorus_delay[] = {0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x3C, chorus_delay_time & 0x7F, 0x00, 0xF7};
96 Write(command_chorus_delay, sizeof(command_chorus_delay) / sizeof(command_chorus_delay[0]));
97}
98
99void Midi::SetPanPosition(const uint8_t channel, const uint8_t pan_position_value) {
100 const uint8_t command[] = {0xB0 | (channel & 0x0F), 0x0A, pan_position_value & 0x7F};
101 Write(command, sizeof(command) / sizeof(command[0]));
102}
103
104void Midi::SetEqualizer(const uint8_t channel, const EqualizerParameter& equalizer_parameter) {
105 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x00, equalizer_parameter.low_frequency_gain);
106 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x01, equalizer_parameter.medium_low_frequency_gain);
107 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x02, equalizer_parameter.medium_high_frequency_gain);
108 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x03, equalizer_parameter.high_frequency_gain);
109 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x08, equalizer_parameter.low_frequency);
110 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x09, equalizer_parameter.medium_low_frequency);
111 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x0A, equalizer_parameter.medium_high_frequency);
112 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x0B, equalizer_parameter.high_frequency);
113
114 NullNrpnOrRpn(channel, 0x63, 0x62);
115}
116
117void Midi::SetTuning(const uint8_t channel, const uint8_t fine_tuning, const uint8_t coarse_tuning) {
118 SendNrpnOrRpnParameter(channel, 0x65, 0x00, 0x64, 0x01, fine_tuning);
119 SendNrpnOrRpnParameter(channel, 0x65, 0x00, 0x64, 0x02, coarse_tuning);
120
121 NullNrpnOrRpn(channel, 0x65, 0x64);
122}
123
124void Midi::SetVibrato(const uint8_t channel, const uint8_t vibrato_rate, const uint8_t vibrato_depth, const uint8_t vibrato_delay_modify) {
125 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x08, vibrato_rate);
126 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x09, vibrato_depth);
127 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x0A, vibrato_delay_modify);
128
129 NullNrpnOrRpn(channel, 0x63, 0x62);
130}
131
132void Midi::SetTimeVaryingFilter(const uint8_t channel, const uint8_t cutoff, const uint8_t resonance) {
133 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x20, cutoff);
134 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x21, resonance);
135
136 NullNrpnOrRpn(channel, 0x63, 0x62);
137}
138
139void Midi::SetEnvelope(const uint8_t channel, const uint8_t attack_time, const uint8_t attenuation_time, const uint8_t release_time) {
140 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x63, attack_time);
141 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x64, attenuation_time);
142 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x66, release_time);
143
144 NullNrpnOrRpn(channel, 0x63, 0x62);
145}
146
147void Midi::SetScaleTuning(const uint8_t channel, const ScaleTuningParameter& scale_tuning_parameter) {
148 const uint8_t command[] = {0xF0,
149 0x41,
150 0x10,
151 0x42,
152 0x12,
153 0x40,
154 0x10 | (channel & 0x0F),
155 0x40,
156 scale_tuning_parameter.note_c & 0x7F,
157 scale_tuning_parameter.note_c_sharp & 0x7F,
158 scale_tuning_parameter.note_d & 0x7F,
159 scale_tuning_parameter.note_d_sharp & 0x7F,
160 scale_tuning_parameter.note_e & 0x7F,
161 scale_tuning_parameter.note_f & 0x7F,
162 scale_tuning_parameter.note_f_sharp & 0x7F,
163 scale_tuning_parameter.note_g & 0x7F,
164 scale_tuning_parameter.note_g_sharp & 0x7F,
165 scale_tuning_parameter.note_a & 0x7F,
166 scale_tuning_parameter.note_a_sharp & 0x7F,
167 scale_tuning_parameter.note_b & 0x7F,
168 0xF7};
169
170 Write(command, sizeof(command) / sizeof(command[0]));
171}
172
173void Midi::SetModulationWheel(const uint8_t channel, const ModulationWheelParameter& modulation_wheel_parameter) {
174 uint8_t command[] = {
175 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x20 | (channel & 0x0F), 0x00, modulation_wheel_parameter.high_pitch_volume & 0x7F, 0x00, 0xF7};
176 Write(command, sizeof(command) / sizeof(command[0]));
177
178 command[8] = 0x01;
179 command[9] = modulation_wheel_parameter.time_varying_timbre_cutoff & 0x7F;
180 Write(command, sizeof(command) / sizeof(command[0]));
181
182 command[8] = 0x02;
183 command[9] = modulation_wheel_parameter.amplitude & 0x7F;
184 Write(command, sizeof(command) / sizeof(command[0]));
185
186 command[8] = 0x03;
187 command[9] = modulation_wheel_parameter.low_frequency_oscillator_rate & 0x7F;
188 Write(command, sizeof(command) / sizeof(command[0]));
189
190 command[8] = 0x04;
191 command[9] = modulation_wheel_parameter.pitch_depth & 0x7F;
192 Write(command, sizeof(command) / sizeof(command[0]));
193
194 command[8] = 0x05;
195 command[9] = modulation_wheel_parameter.time_varying_filter_depth & 0x7F;
196 Write(command, sizeof(command) / sizeof(command[0]));
197
198 command[8] = 0x06;
199 command[9] = modulation_wheel_parameter.time_varying_amplifier_depth & 0x7F;
200 Write(command, sizeof(command) / sizeof(command[0]));
201}
202
204 uint8_t command[] = {0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x15, 0x01, 0x00, 0xF7};
205 for (uint8_t i = 0; i <= 15; i++) {
206 command[6] = 0x10 | (i & 0x0F);
207 Write(command, sizeof(command) / sizeof(command[0]));
208 }
209}
210
211void Midi::Write(const uint8_t data) {
212 stream_.write(data);
213}
214
215void Midi::Write(const uint8_t* buffer, const size_t size) {
216 if (!buffer || size == 0) {
217 printf("Error: Invalid buffer\n");
218 return;
219 }
220 stream_.write(buffer, size);
221}
222
223void Midi::SendNrpnOrRpnParameter(const uint8_t channel,
224 const uint8_t most_significant_byte_controller,
225 const uint8_t most_significant_byte,
226 const uint8_t least_significant_byte_controller,
227 const uint8_t least_significant_byte,
228 const uint8_t value) {
229 const uint8_t command_most_significant_byte[] = {0xB0 | (channel & 0x0F), most_significant_byte_controller, most_significant_byte};
230 Write(command_most_significant_byte, sizeof(command_most_significant_byte) / sizeof(command_most_significant_byte[0]));
231
232 const uint8_t command_least_significant_byte[] = {0xB0 | (channel & 0x0F), least_significant_byte_controller, least_significant_byte};
233 Write(command_least_significant_byte, sizeof(command_least_significant_byte) / sizeof(command_least_significant_byte[0]));
234
235 const uint8_t command_set_value[] = {0xB0 | (channel & 0x0F), 0x06, value & 0x7F};
236 Write(command_set_value, sizeof(command_set_value) / sizeof(command_set_value[0]));
237}
238
239void Midi::NullNrpnOrRpn(const uint8_t channel,
240 const uint8_t most_significant_byte_controller,
241 const uint8_t least_significant_byte_controller) {
242 const uint8_t command_most_significant_byte[] = {0xB0 | (channel & 0x0F), most_significant_byte_controller, 0x7F};
243 Write(command_most_significant_byte, sizeof(command_most_significant_byte) / sizeof(command_most_significant_byte[0]));
244
245 const uint8_t command_least_significant_byte[] = {0xB0 | (channel & 0x0F), least_significant_byte_controller, 0x7F};
246 Write(command_least_significant_byte, sizeof(command_least_significant_byte) / sizeof(command_least_significant_byte[0]));
247}
248
249} // namespace em
void SetTimeVaryingFilter(const uint8_t channel, const uint8_t cutoff, const uint8_t resonance)
Set Time Varying Filter (TVF).
Definition midi.cpp:132
void SetChannelTimbre(const uint8_t channel, const uint8_t bank, const uint8_t timbre)
Change the tone of the specified channel. Among them, channel 9 is a dedicated drum channel,...
Definition midi.cpp:18
void SetEqualizer(const uint8_t channel, const EqualizerParameter &equalizer_parameter)
Set up a four segment equalizer.
Definition midi.cpp:104
void SetChannelVolume(const uint8_t channel, const uint8_t volume)
Set specific channel volume.
Definition midi.cpp:55
void SetScaleTuning(const uint8_t channel, const ScaleTuningParameter &scale_tuning_parameter)
Set the 12 scale tuning parameters for the specified MIDI channel (independent pitch offset for each ...
Definition midi.cpp:147
void AllDrums()
Activate all drum channels and set all 16 MIDI channels (0-15) as drum channels.
Definition midi.cpp:203
void SetPanPosition(const uint8_t channel, const uint8_t pan_position_value)
Set the pan position.
Definition midi.cpp:99
void SetEnvelope(const uint8_t channel, const uint8_t attack_time, const uint8_t attenuation_time, const uint8_t release_time)
Set envelope parameters.
Definition midi.cpp:139
void SetModulationWheel(const uint8_t channel, const ModulationWheelParameter &modulation_wheel_parameter)
Set modulation wheel parameters and configure multiple control effects for modulation wheel sound.
Definition midi.cpp:173
void PitchBendRange(const uint8_t channel, const uint8_t pitch_bend_range_value)
Set the pitch bend range (sensitivity).
Definition midi.cpp:40
void SetChorus(const uint8_t channel, const uint8_t chorus_effect_type, const uint8_t chorus_effect_volume, const uint8_t chorus_effect_feedback, const uint8_t chorus_delay_time)
Apply a chorus effect to a specified channel.
Definition midi.cpp:80
void ChannelAllNotesOff(const uint8_t channel)
Send a noteOff() for each note on the specified channel.
Definition midi.cpp:50
void NoteOff(const uint8_t channel, const uint8_t midi_note)
Close the note in the specified channel, which was previously opened at a given pitch using the noteO...
Definition midi.cpp:13
void SetAllChannelVolume(const uint8_t volume)
Set the volume for all channels.
Definition midi.cpp:60
void SetReverberation(const uint8_t channel, const uint8_t reverberation_type, const uint8_t reverberation_volume, const uint8_t delay_feedback)
Apply reverberation effect to the specified channel.
Definition midi.cpp:65
void NoteOn(const uint8_t channel, const uint8_t midi_note, const uint8_t z)
Generate the given MIDI note on the designated channel (0-15).
Definition midi.cpp:8
Midi(Stream &stream)
Constructor.
Definition midi.cpp:5
void MidiReset()
MIDI system reset sends MIDI system reset command (0xFF) to reset all connected MIDI devices to their...
Definition midi.cpp:46
void PitchBend(const uint8_t channel, uint16_t pitch_bend_value)
Bend the pitch upwards or downwards, with a default swing of+/-1 semitone.
Definition midi.cpp:31
void SetTuning(const uint8_t channel, const uint8_t fine_tuning, const uint8_t coarse_tuning)
Set tone (coarse/fine).
Definition midi.cpp:117
void SetVibrato(const uint8_t channel, const uint8_t vibrato_rate, const uint8_t vibrato_depth, const uint8_t vibrato_delay_modify)
Set vibrato parameters.
Definition midi.cpp:124
#define EM_MIDI_TIMBRE_BANK_127_ALTO_SAX
Alto Sax.
#define EM_MIDI_TIMBRE_BANK_0
Standard GM Sound Bank.
Definition midi_timbre.h:23
Equalizer parameter structure.
Definition midi.h:28
uint8_t medium_high_frequency
Medium-high frequency center value (0-127).
Definition midi.h:97
uint8_t medium_low_frequency
Medium-low frequency center value (0-127).
Definition midi.h:87
uint8_t medium_high_frequency_gain
Medium-high frequency gain value (0-127).
Definition midi.h:57
uint8_t low_frequency
Low frequency center value (0-127).
Definition midi.h:77
uint8_t high_frequency_gain
High frequency gain value (0-127).
Definition midi.h:67
uint8_t medium_low_frequency_gain
Medium-low frequency gain value (0-127).
Definition midi.h:47
uint8_t high_frequency
High frequency center value (0-127).
Definition midi.h:107
uint8_t low_frequency_gain
Low frequency gain value (0-127).
Definition midi.h:37
Modulation wheel parameters.
Definition midi.h:248
uint8_t time_varying_filter_depth
Time-varying filter depth (0-127).
Definition midi.h:307
uint8_t amplitude
Amplitude modulation depth (0-127).
Definition midi.h:277
uint8_t high_pitch_volume
High pitch volume intensity (0-127).
Definition midi.h:257
uint8_t low_frequency_oscillator_rate
Low-frequency oscillator rate (0-127).
Definition midi.h:287
uint8_t pitch_depth
Pitch modulation depth (0-127).
Definition midi.h:297
uint8_t time_varying_amplifier_depth
Time-varying amplifier depth (0-127).
Definition midi.h:317
uint8_t time_varying_timbre_cutoff
Time-varying timbre cutoff frequency (0-127).
Definition midi.h:267
12 scale tuning parameter structures.
Definition midi.h:118
uint8_t note_b
B note fine-tuning value (0-127).
Definition midi.h:237
uint8_t note_d_sharp
D# note fine-tuning value (0-127).
Definition midi.h:157
uint8_t note_c_sharp
C# note fine-tuning value (0-127)
Definition midi.h:137
uint8_t note_d
D note fine-tuning value (0-127).
Definition midi.h:147
uint8_t note_a_sharp
A# note fine-tuning value (0-127).
Definition midi.h:227
uint8_t note_f
F note fine-tuning value (0-127).
Definition midi.h:177
uint8_t note_f_sharp
F# note fine-tuning value (0-127).
Definition midi.h:187
uint8_t note_g
G note fine-tuning value (0-127).
Definition midi.h:197
uint8_t note_e
E note fine-tuning value (0-127).
Definition midi.h:167
uint8_t note_c
C note fine-tuning value (0-127)
Definition midi.h:127
uint8_t note_g_sharp
G# note fine-tuning value (0-127).
Definition midi.h:207
uint8_t note_a
A note fine-tuning value (0-127).
Definition midi.h:217