EM MIDI Arduino Lib 1.0.1
Loading...
Searching...
No Matches
drum_pattern_player.ino

Drum pattern player.

/**
* @~Chinese
* @file drum_pattern_player.ino
* @brief 示例:鼓型播放器。
* @example drum_pattern_player.ino
* 鼓型播放器。
*/
/**
* @~English
* @file drum_pattern_player.ino
* @brief Example: Drum pattern player.
* @example drum_pattern_player.ino
* Drum pattern player.
*/
#include "midi.h"
#if defined(ESP32)
#include <HardwareSerial.h>
#else
#include <SoftwareSerial.h>
#endif
namespace {
constexpr uint8_t kChannel = 9;
constexpr uint8_t kChannelVolume = 100;
constexpr uint8_t kReverberationVolume = 127;
constexpr uint8_t kReverberationDelayFeedback = 100;
constexpr uint8_t kTempoRandomRange = 5;
constexpr uint8_t kTempoRandomOffset = 2;
constexpr uint8_t kMinTempo = 40;
constexpr uint8_t kMaxTempo = 250;
constexpr uint8_t kTickSize = 15;
#if defined(ESP32)
constexpr gpio_num_t kMidiPin = GPIO_NUM_17;
constexpr uart_port_t kUartPort = UART_NUM_2; // Using UART2
HardwareSerial g_midi_serial(kUartPort);
#else
constexpr uint8_t kMidiPin = 4;
SoftwareSerial g_midi_serial(-1, kMidiPin);
#endif
em::Midi g_midi(g_midi_serial);
// Every array cell is the velocity of the note played
// Tick 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
constexpr uint8_t kBassDrumTick[] = {127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0};
constexpr uint8_t kSnareDrumTick[] = {0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
constexpr uint8_t kHiHatOpenTick[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0};
constexpr uint8_t kHiHatCloseTick[] = {127, 40, 80, 40, 127, 40, 80, 40, 127, 40, 80, 40, 127, 0, 0};
constexpr uint8_t kHiHatPedalTick[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127};
static_assert(sizeof(kBassDrumTick) / sizeof(kBassDrumTick[0]) == kTickSize, "kBassDrumTick size must be 15");
static_assert(sizeof(kSnareDrumTick) / sizeof(kSnareDrumTick[0]) == kTickSize, "kSnareDrumTick size must be 15");
static_assert(sizeof(kHiHatOpenTick) / sizeof(kHiHatOpenTick[0]) == kTickSize, "kHiHatOpenTick size must be 15");
static_assert(sizeof(kHiHatCloseTick) / sizeof(kHiHatCloseTick[0]) == kTickSize, "kHiHatCloseTick size must be 15");
static_assert(sizeof(kHiHatPedalTick) / sizeof(kHiHatPedalTick[0]) == kTickSize, "kHiHatPedalTick size must be 15");
uint16_t g_tempo = 120;
void PlayDrumNote(const uint8_t midi_note, const uint8_t note_velocity) {
if (note_velocity > 0) {
g_midi.NoteOn(kChannel, midi_note, note_velocity);
g_midi.NoteOff(kChannel, midi_note);
}
}
} // namespace
void setup() {
#if defined(ESP32)
g_midi_serial.begin(31250, SERIAL_8N1, -1, kMidiPin);
#else
g_midi_serial.begin(31250);
#endif
g_midi.MidiReset();
g_midi.SetChannelTimbre(kChannel, EM_MIDI_TIMBRE_BANK_0, EM_MIDI_PERCUSSION_TIMBRE_1);
g_midi.SetReverberation(kChannel, EM_MIDI_REVERBERATION_PLATE, kReverberationVolume, kReverberationDelayFeedback);
g_midi.SetChannelVolume(kChannel, kChannelVolume);
}
void loop() {
for (uint8_t tick_no = 0; tick_no < kTickSize; tick_no++) {
g_tempo = g_tempo + (random(kTempoRandomRange) - kTempoRandomOffset);
g_tempo = constrain(g_tempo, kMinTempo, kMaxTempo);
PlayDrumNote(EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_C_2_KICK_DRUM_1, kBassDrumTick[tick_no]);
PlayDrumNote(EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_D_2_SNARE_DRUM_1, kSnareDrumTick[tick_no]);
PlayDrumNote(EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_F_SHARP_2_CLOSED_HI_HAT, kHiHatCloseTick[tick_no]);
PlayDrumNote(EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_A_SHARP_2_OPEN_HI_HAT, kHiHatOpenTick[tick_no]);
PlayDrumNote(EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_G_SHARP_2_PEDAL_HI_HAT, kHiHatPedalTick[tick_no]);
delay(g_tempo);
}
}
Midi is a driver class for the MIDI module, used for synthesizing music.
Definition midi.h:335
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 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
#define EM_MIDI_REVERBERATION_PLATE
Plate reverberation effect.
#define EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_D_2_SNARE_DRUM_1
D-2 (Snare drum 1)
#define EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_F_SHARP_2_CLOSED_HI_HAT
F#-2 (Closed hi-hat)
#define EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_A_SHARP_2_OPEN_HI_HAT
A#-2 (Open hi-hat)
#define EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_C_2_KICK_DRUM_1
C-2 (Kick drum 1)
#define EM_MIDI_PERCUSSION_TIMBRE_1
Define the constant of percussion timbre type for channel 9.
#define EM_MIDI_PERCUSSION_TIMBRE_1_NOTE_G_SHARP_2_PEDAL_HI_HAT
G#-2 (Pedal hi-hat)
#define EM_MIDI_TIMBRE_BANK_0
Standard GM Sound Bank.
Definition midi_timbre.h:23