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
@+