Arduino + VS1053 + Midi

Bonjour,

J'ai équipé mon R4 WiFi de la carte Adafruit Music Maker afin de pouvoir lire des fichiers musicaux.
J'ai fait un test avec un fichier mp3 et ça fonctionne nickel.
Je suis maintenant en train d'essayer de lire un fichier Midi et là, ça bloque. Je n'entend rien qui sort comme son. Il me semble pourtant que les données sont bien lues puisque mon deboggage les écrit dans le moniteur série. J'ai fait un fichier midi très simple pour le test. Je le mets en zip ci-dessous.

Si vous avez une idée du problème, je prends !!!! Merci.

#include "SdFat.h"
#include "Adafruit_VS1053.h"

// 📌 Configuration SD et VS1053
#define SD_FAT_TYPE 3
const uint8_t SD_CS_PIN = 4; // CS de la carte SD sur le VS1053
#define SPI_CLOCK SD_SCK_MHZ(50)
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)

// Broches VS1053
#define VS1053_RESET  -1 // Non utilisé
#define VS1053_CS      7
#define VS1053_DCS     6
#define VS1053_DREQ    3  // Doit être une entrée

Adafruit_VS1053 player(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ);

SdFs sd;
FsFile file;

String receivedFileName = ""; // Stocke le nom du fichier Midi à lire

// -------------------------------------------------
// Patch pour activer le mode MIDI temps réel du VS1053
// (patch extrait de VS1053b_Realtime_MIDI_Plugin)
// -------------------------------------------------
const unsigned short sVS1053b_Realtime_MIDI_Plugin[28] = {
  0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080,
  0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890,
  0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030,
  0x0200, 0x000a, 0x0001, 0x0050
};

void VSLoadUserCode() {
  int i = 0;
  int patchSize = sizeof(sVS1053b_Realtime_MIDI_Plugin) / sizeof(sVS1053b_Realtime_MIDI_Plugin[0]);
  while(i < patchSize) {
    unsigned short reg = sVS1053b_Realtime_MIDI_Plugin[i++];
    unsigned short n   = sVS1053b_Realtime_MIDI_Plugin[i++];
    while(n--) {
      unsigned short val = sVS1053b_Realtime_MIDI_Plugin[i++];
      // Utilisation de sciWrite(address, data) de la bibliothèque Adafruit_VS1053
      player.sciWrite(reg, val);
    }
  }
}
// -------------------------------------------------

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // Initialisation de la carte SD
  if (!sd.begin(SD_CONFIG)) {
    Serial.println("⚠️ Erreur SD");
    return;
  }

  // Initialisation du VS1053
  if (!player.begin()) {
    Serial.println("⚠️ Erreur VS1053");
    return;
  }

  player.softReset();
  // Passage en mode MIDI via SCI
  player.sciWrite(0x00, 0x0800); // SCI_MODE: active le mode MIDI
  player.sciWrite(0x03, 0x6000); // SCI_CLOCKF: ajuste l'horloge
  // Charge le patch MIDI pour VS1053
  VSLoadUserCode();
  
  player.setVolume(20, 20);
  Serial.println("🎶 VS1053 prêt en mode MIDI !");
  Serial.println("Entrez le nom du fichier MIDI à jouer :");
}

void loop() {
  if (Serial.available()) {
    receivedFileName = Serial.readStringUntil('\n');
    receivedFileName.trim(); // Supprime les espaces inutiles
    Serial.print("Fichier MIDI à jouer : ");
    Serial.println(receivedFileName);
    playMIDI(receivedFileName.c_str());
  }
}

// Lecture du fichier MIDI et envoi en mode MIDI temps réel
void playMIDI(const char* fileName) {
  char path[50] = "/MIDI/";
  strcat(path, fileName);

  if (!file.open(path, O_RDONLY)) {
    Serial.println("⚠️ Erreur ouverture fichier MIDI");
    return;
  }

  Serial.print("🎵 Lecture MIDI : ");
  Serial.println(fileName);

  uint8_t buffer[32]; // Buffer plus grand pour éviter de fragmenter les messages MIDI
  uint32_t deltaTime = 0;

  while (file.available()) {
    int bytesRead = file.read(buffer, sizeof(buffer));
    
    for (int i = 0; i < bytesRead; i++) {
      // Attendre que le VS1053 soit prêt (DREQ = HIGH)
      while (!digitalRead(VS1053_DREQ)) {
        delayMicroseconds(10);
      }
      // Envoi de l'octet dans le registre AUDATA (0x05)
      player.sciWrite(0x05, buffer[i]);
      Serial.print("Octet lu : ");
      Serial.println(buffer[i], HEX);

      // Respecter le timing MIDI (delta time)
      if (buffer[i] & 0x80) { // Si c'est un statut byte (commande MIDI)
        deltaTime = 0; // Réinitialiser le delta time
      } else {
        deltaTime += buffer[i]; // Accumuler le delta time
        delayMicroseconds(deltaTime * 100); // Ajuster le délai
      }
    }
  }

  file.close();
  Serial.println("✅ Lecture terminée !");
}

test-midi.mid.zip (333 Octets)

Le problème est là :

Il faut utiliser : player.playData(buffer, bytesRead);

Ça marche !!! Ça fait une semaine que je me casse les dents dessus et il suffit que je me décide à poster pour résoudre le problème.
Désolé du dérangement !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.