Petite banque de données musicale

J'ai un peu bossé. Lecture en boucle des fichiers situés dans un répertoire "/ZIC" d'une microSD.
Et un bouton sur D8 pour passer au morceau suivant.

#include "Arduino.h"
#include <string.h>
#include <SPI.h>
#include <SD.h>

// Liste des notes
#define SIL 0
#define DON 65
#define DOD 69
#define REN 74
#define RED 78
#define MIN 83
#define FAN 87
#define FAD 93
#define SON 98
#define SOD 104
#define LAN 110
#define LAD 117
#define SIN 123
#define FIN 255

// liste des rythmes
#define QUINTUPLECROCHE 1
#define QUADRUPLECROCHE 2
#define TRIPLECROCHE 4
#define DOUBLECROCHE 8
#define CROCHE 16
#define CROCHEPOINTEE 24
#define NOIRE 32
#define NOIREPOINTEE 48
#define BLANCHE 64
#define BLANCHEPOINTEE 96
#define RONDE 128

// liste des rythmiques de silences
#define TRENTEDEUXIEMEDESOUPIR 1
#define SEIZIEMEDESOUPIR 2
#define HUITIEMEDESOUPIR 4
#define QUARDESOUPIR 8
#define DEMISOUPIR 16
#define SOUPIR 32
#define DEMIPAUSE 64
#define PAUSE 128

// Tempo
#define LENTO 60
#define ANDANTE 80
#define MODERATO 100
#define ALLEGRO 120
#define PRESTO 150
#define PRESTISSIMO 200

#define MAX_SIZE  201
#define BUTTON  8

struct note
{
  byte base;
  byte tempo;
  byte octave;
};

class MusicPlayer
{
  protected:
    byte m_speakerPin; // numero de pin
    int m_tempo;
    byte m_track;

  public:
    MusicPlayer();
    MusicPlayer(byte speakerPin);
    bool openDir(char *name);
    void playNext(int tempo);
  private:
    File m_musicDir;
    struct note melody[MAX_SIZE];
    int getFrequency(int frequency, int octave);
    bool readMelody(File &f, struct note *melody);
};

MusicPlayer::MusicPlayer(byte speakerPin)
{
  m_speakerPin = speakerPin;
  pinMode(speakerPin, OUTPUT);
}

bool MusicPlayer::openDir(char *name)
{
  Serial.print(F("open "));
  Serial.println(name);
  m_musicDir = SD.open(name);
}

int MusicPlayer::getFrequency(int frequency, int octave) {
  return frequency * pow(2, octave);
}

bool MusicPlayer::readMelody(File &f, struct note *melody)
{
  int i = 0;

  while (f.available() && i < MAX_SIZE) {
    melody[i].base = f.read();
    melody[i].tempo = f.read();
    melody[i++].octave = f.read();
  }
  Serial.print(i);
  Serial.print(F(" notes from "));
  Serial.println(f.name());
  melody[i].base = FIN;
  f.close();
  return true;
}

void MusicPlayer::playNext(int tempo) {
  float ftempo = 0;
  bool play = false;

  if (m_musicDir == 0) {
    Serial.println(F("must open a directory first"));
    return;
  }
  File f =  m_musicDir.openNextFile();
  if (f == 0) {
    m_musicDir.rewindDirectory();
    f =  m_musicDir.openNextFile();
  }
  Serial.print(F("reading: "));
  Serial.println(f.name());
  play = readMelody(f, melody);
  ftempo = (1000.0 * 60.0) / float(tempo);

  if (play) {
    for (int n = 0; melody[n].base != FIN; n++) { // boucle de lecture du tableau
      char note = melody[n].base; // on récupère la fréquence de base dans le tableau
      char octave = melody[n].octave; // on récupère l'octave
      int frequence;
      if (note != SIL) {
        frequence = getFrequency(note, octave); //on calcule la bonne fréquence
      }
      //    Serial.println(frequence);
      float duree = ftempo * melody[n].tempo / 32; // on multiplie la duree de base par la valeur de duree du tableau
      //    Serial.println(duree);
      if (note != SIL) {
        tone (m_speakerPin, frequence); //on joue la note
      }
      delay(duree);
      if (note != SIL) {
        noTone(m_speakerPin);//on arrete la note
      }
      delay(10);// petite attente pour avoir l'impression d'attaquer la note
      if (digitalRead(BUTTON) == LOW) {
        break;
      }
    }
  }
  f.close();
}

MusicPlayer player = MusicPlayer(9);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(BUTTON, INPUT_PULLUP);
  if (!SD.begin(10)) {
    Serial.println(F("Card failed, or not present"));
    // don't do anything more:
    while (1);
  }
  Serial.println(F("card initialized."));
  player.openDir("/ZIC");
}

void loop()
{
  player.playNext(ALLEGRO);
  delay(2000);
}

Prochaine étape : il faudrait quelqu'un de courageux pour écrire un logiciel de reconnaissance de partition musicale ;D

@+