🎵 Notas Ativas¶
O MIDIHandler mantém um mapa interno de quais notas estão atualmente pressionadas (NoteOn recebido mas NoteOff ainda não). Diversas APIs permitem consultar esse estado.
API de Notas Ativas¶
getActiveNotes() — String formatada¶
Retorna uma string com todas as notas ativas:
std::string ativas = midiHandler.getActiveNotes();
Serial.println(ativas.c_str());
// Exemplo: "{C4, E4, G4}"
getActiveNotesVector() — Lista de strings¶
Retorna um vetor com cada nota como string:
auto notas = midiHandler.getActiveNotesVector();
// Exemplo: ["C4", "E4", "G4"]
for (const auto& n : notas) {
Serial.println(n.c_str());
}
getActiveNotesCount() — Quantidade¶
Número de notas atualmente pressionadas:
fillActiveNotes() — Array booleano¶
Preenche um array de 128 posições (uma por nota MIDI):
bool ativas[128] = {false};
midiHandler.fillActiveNotes(ativas);
// Verificar nota específica:
if (ativas[60]) Serial.println("C4 está pressionada!");
// Listar todas as ativas:
for (int i = 0; i < 128; i++) {
if (ativas[i]) {
Serial.printf("Nota %d ativa\n", i);
}
}
Exemplo Completo¶
#include <ESP32_Host_MIDI.h>
// Tools > USB Mode → "USB Host"
void setup() {
Serial.begin(115200);
midiHandler.begin();
}
void loop() {
midiHandler.task();
// Mostrar notas ativas quando algo mudar
static size_t lastCount = 0;
size_t count = midiHandler.getActiveNotesCount();
if (count != lastCount) {
lastCount = count;
if (count == 0) {
Serial.println("[ sem notas ]");
} else {
Serial.printf("[%d notas] %s\n",
(int)count,
midiHandler.getActiveNotes().c_str());
}
}
}
Saída ao tocar um acorde de Dó maior e soltar:
[1 notas] {C4}
[2 notas] {C4, E4}
[3 notas] {C4, E4, G4}
[2 notas] {C4, E4}
[1 notas] {C4}
[ sem notas ]
Usar para Síntese de Áudio¶
O fillActiveNotes() é ideal para síntese em tempo real — copie o array uma vez por frame:
bool notas[128];
midiHandler.fillActiveNotes(notas);
// Sintetizar todas as notas ativas
for (int i = 0; i < 128; i++) {
if (notas[i]) {
float freq = 440.0f * powf(2.0f, (i - 69) / 12.0f);
// addOscillator(freq);
}
}
Piano Roll com notas ativas¶
#include <ESP32_Host_MIDI.h>
// Mostrar quais teclas estão pressionadas (ASCII art)
void printPianoRoll() {
bool notas[128];
midiHandler.fillActiveNotes(notas);
// Teclas C4 a B4 (60–71)
for (int i = 60; i <= 71; i++) {
Serial.print(notas[i] ? "█" : "░");
}
Serial.println();
}
void loop() {
midiHandler.task();
printPianoRoll();
delay(50);
}
Limpar Notas Ativas¶
Em alguns casos (desconexão, reset) você precisa limpar o estado:
getActiveNotesString() — Alternativa¶
Alias de getActiveNotes() com nome alternativo:
Monitorar Pressão de Teclas Específicas¶
Combine fillActiveNotes() com uma lista de notas de interesse:
const int ACORDE_CM[] = {60, 64, 67}; // C, E, G
bool notas[128];
midiHandler.fillActiveNotes(notas);
bool acordeCompleto = notas[60] && notas[64] && notas[67];
if (acordeCompleto) {
Serial.println("Dó maior pressionado!");
}
Próximos Passos¶
- Detecção de Acordes → — agrupar notas em acordes
- GingoAdapter → — identificar nome do acorde
- Histórico PSRAM → — guardar histórico de notas