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]));
14 const uint8_t command[] = {0x80 | (channel & 0x0F), midi_note & 0x7F, 0x00};
15 Write(command,
sizeof(command) /
sizeof(command[0]));
20 printf(
"Error: bank parameter error, can only be EM_MIDI_TIMBRE_BANK_0 or EM_MIDI_TIMBRE_BANK_127.\n");
24 const uint8_t command_bank[] = {0xB0 | (channel & 0x0F), 0x00, bank};
25 Write(command_bank,
sizeof(command_bank) /
sizeof(command_bank[0]));
27 const uint8_t command_timbre[] = {0xC0 | (channel & 0x0F), timbre & 0x7F};
28 Write(command_timbre,
sizeof(command_timbre) /
sizeof(command_timbre[0]));
32 if (pitch_bend_value > 1023) {
33 pitch_bend_value = 1023;
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]));
41 SendNrpnOrRpnParameter(channel, 0x65, 0x00, 0x64, 0x00, pitch_bend_range_value);
43 NullNrpnOrRpn(channel, 0x65, 0x64);
51 const uint8_t command[] = {0xB0 | (channel & 0x0F), 0x7B, 0x00};
52 Write(command,
sizeof(command) /
sizeof(command[0]));
56 const uint8_t command[] = {0xB0 | (channel & 0x0F), 0x07, volume & 0x7F};
57 Write(command,
sizeof(command) /
sizeof(command[0]));
61 const uint8_t command[] = {0xF0, 0x7F, 0x7F, 0x04, 0x01, 0x00, volume & 0x7F, 0xF7};
62 Write(command,
sizeof(command) /
sizeof(command[0]));
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]));
73 command[2] = reverberation_volume & 0x7F;
74 Write(command,
sizeof(command) /
sizeof(command[0]));
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]));
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]));
89 command[2] = chorus_effect_volume & 0x7F;
90 Write(command,
sizeof(command) /
sizeof(command[0]));
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]));
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]));
100 const uint8_t command[] = {0xB0 | (channel & 0x0F), 0x0A, pan_position_value & 0x7F};
101 Write(command,
sizeof(command) /
sizeof(command[0]));
105 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x00, equalizer_parameter.
low_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);
112 SendNrpnOrRpnParameter(channel, 0x63, 0x37, 0x62, 0x0B, equalizer_parameter.
high_frequency);
114 NullNrpnOrRpn(channel, 0x63, 0x62);
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);
121 NullNrpnOrRpn(channel, 0x65, 0x64);
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);
129 NullNrpnOrRpn(channel, 0x63, 0x62);
133 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x20, cutoff);
134 SendNrpnOrRpnParameter(channel, 0x63, 0x01, 0x62, 0x21, resonance);
136 NullNrpnOrRpn(channel, 0x63, 0x62);
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);
144 NullNrpnOrRpn(channel, 0x63, 0x62);
148 const uint8_t command[] = {0xF0,
154 0x10 | (channel & 0x0F),
156 scale_tuning_parameter.
note_c & 0x7F,
158 scale_tuning_parameter.
note_d & 0x7F,
160 scale_tuning_parameter.
note_e & 0x7F,
161 scale_tuning_parameter.
note_f & 0x7F,
163 scale_tuning_parameter.
note_g & 0x7F,
165 scale_tuning_parameter.
note_a & 0x7F,
167 scale_tuning_parameter.
note_b & 0x7F,
170 Write(command,
sizeof(command) /
sizeof(command[0]));
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]));
180 Write(command,
sizeof(command) /
sizeof(command[0]));
183 command[9] = modulation_wheel_parameter.
amplitude & 0x7F;
184 Write(command,
sizeof(command) /
sizeof(command[0]));
188 Write(command,
sizeof(command) /
sizeof(command[0]));
191 command[9] = modulation_wheel_parameter.
pitch_depth & 0x7F;
192 Write(command,
sizeof(command) /
sizeof(command[0]));
196 Write(command,
sizeof(command) /
sizeof(command[0]));
200 Write(command,
sizeof(command) /
sizeof(command[0]));
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]));
211void Midi::Write(
const uint8_t data) {
215void Midi::Write(
const uint8_t* buffer,
const size_t size) {
216 if (!buffer || size == 0) {
217 printf(
"Error: Invalid buffer\n");
220 stream_.write(buffer, size);
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]));
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]));
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]));
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]));
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]));
void SetTimeVaryingFilter(const uint8_t channel, const uint8_t cutoff, const uint8_t resonance)
Set Time Varying Filter (TVF).
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,...
void SetEqualizer(const uint8_t channel, const EqualizerParameter &equalizer_parameter)
Set up a four segment equalizer.
void SetChannelVolume(const uint8_t channel, const uint8_t volume)
Set specific channel volume.
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 ...
void AllDrums()
Activate all drum channels and set all 16 MIDI channels (0-15) as drum channels.
void SetPanPosition(const uint8_t channel, const uint8_t pan_position_value)
Set the pan position.
void SetEnvelope(const uint8_t channel, const uint8_t attack_time, const uint8_t attenuation_time, const uint8_t release_time)
Set envelope parameters.
void SetModulationWheel(const uint8_t channel, const ModulationWheelParameter &modulation_wheel_parameter)
Set modulation wheel parameters and configure multiple control effects for modulation wheel sound.
void PitchBendRange(const uint8_t channel, const uint8_t pitch_bend_range_value)
Set the pitch bend range (sensitivity).
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.
void ChannelAllNotesOff(const uint8_t channel)
Send a noteOff() for each note on the specified channel.
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...
void SetAllChannelVolume(const uint8_t volume)
Set the volume for all channels.
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.
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).
Midi(Stream &stream)
Constructor.
void MidiReset()
MIDI system reset sends MIDI system reset command (0xFF) to reset all connected MIDI devices to their...
void PitchBend(const uint8_t channel, uint16_t pitch_bend_value)
Bend the pitch upwards or downwards, with a default swing of+/-1 semitone.
void SetTuning(const uint8_t channel, const uint8_t fine_tuning, const uint8_t coarse_tuning)
Set tone (coarse/fine).
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.
#define EM_MIDI_TIMBRE_BANK_127_ALTO_SAX
Alto Sax.
#define EM_MIDI_TIMBRE_BANK_0
Standard GM Sound Bank.
Equalizer parameter structure.
uint8_t medium_high_frequency
Medium-high frequency center value (0-127).
uint8_t medium_low_frequency
Medium-low frequency center value (0-127).
uint8_t medium_high_frequency_gain
Medium-high frequency gain value (0-127).
uint8_t low_frequency
Low frequency center value (0-127).
uint8_t high_frequency_gain
High frequency gain value (0-127).
uint8_t medium_low_frequency_gain
Medium-low frequency gain value (0-127).
uint8_t high_frequency
High frequency center value (0-127).
uint8_t low_frequency_gain
Low frequency gain value (0-127).
Modulation wheel parameters.
uint8_t time_varying_filter_depth
Time-varying filter depth (0-127).
uint8_t amplitude
Amplitude modulation depth (0-127).
uint8_t high_pitch_volume
High pitch volume intensity (0-127).
uint8_t low_frequency_oscillator_rate
Low-frequency oscillator rate (0-127).
uint8_t pitch_depth
Pitch modulation depth (0-127).
uint8_t time_varying_amplifier_depth
Time-varying amplifier depth (0-127).
uint8_t time_varying_timbre_cutoff
Time-varying timbre cutoff frequency (0-127).
12 scale tuning parameter structures.
uint8_t note_b
B note fine-tuning value (0-127).
uint8_t note_d_sharp
D# note fine-tuning value (0-127).
uint8_t note_c_sharp
C# note fine-tuning value (0-127)
uint8_t note_d
D note fine-tuning value (0-127).
uint8_t note_a_sharp
A# note fine-tuning value (0-127).
uint8_t note_f
F note fine-tuning value (0-127).
uint8_t note_f_sharp
F# note fine-tuning value (0-127).
uint8_t note_g
G note fine-tuning value (0-127).
uint8_t note_e
E note fine-tuning value (0-127).
uint8_t note_c
C note fine-tuning value (0-127)
uint8_t note_g_sharp
G# note fine-tuning value (0-127).
uint8_t note_a
A note fine-tuning value (0-127).