Project in progress
Arduino Due Midi File Player

Arduino Due Midi File Player © GPL3+

Plays standard Midi files.

  • 26 views
  • 0 comments
  • 0 respects

Components and supplies

Ard due
Arduino Due
×1
MP3 Arduino Shield - VS1003/1053
×1
3.5TFT Touch Display
×1
Micro SD Card
×1
11026 02
Jumper wires (generic)
×1

About this project

Another project using the vs1053 and the 3, 5' tft display. At the moment only the sd-card is used. General MIDI format 0 files can played.

Needed libraries:

MD_MIDIFILE

SDfat libraries can install from the library manager.

In the SdFat library we must change the SdFatConfig.h

#define ENABLE_SOFTWARE_SPI_CLASS 0

to

#define ENABLE_SOFTWARE_SPI_CLASS 1

and make changes to the MIDIFile.h from the MD_MIDIFILE library

edit TRACK_PRIORITY to 0 and

edit MIDI_MAX_TRACKS to 32

Then copy the examples/sd_card_files from the MD_MIDFILE library folder to your home dir of the sd-card.

Wiring

for the vs1053:

  • XCS -> 46
  • XDCS -> 48
  • DREQ -> 50
  • XRST -> 52
  • MOSI -> A.26
  • MISO -> A.25
  • SCK -> A.27
  • 5V -> 5V

Code

Arduino Due midi file playerArduino
a mid file player
////////////////////////////////////////////////////////////////////
//                      Midi-File-Player                          //
//                       source  from                             // 
//                       MajicDesigns                             // 
//         https://github.com/MajicDesigns/MD_MIDIFile            //
//                         modified by                            //
//                            rom3                                //
//                         07,23,2019                             //
////////////////////////////////////////////////////////////////////

// Test playing a succession of MIDI files from the SD card.
// Example program to demonstrate the use of the MIDFile library

// Hardware required:
//  SD card interface - change SD_SELECT for SPI comms
//  Change pin definitions for specific hardware setup - defined below.

#include <SPI.h>
#include <SdFat.h>
SdFatSoftSpi<12, 11, 13> SD; //Bit-Bang on the Shield pins
#include <MD_MIDIFile.h>

#define VS_XCS    46 // Control Chip Select Pin (for accessing SPI Control/Status registers)
#define VS_XDCS   48 // Data Chip Select / BSYNC Pin
#define VS_DREQ   50 // Data Request Pin: Player asks for more data
#define VS_RESET  52 //Reset is active low

// SD chip select pin for SPI comms.
// Arduino Ethernet shield, pin 4.
// Default SD chip select is the SPI SS pin (10).
// Other hardware will be different as documented for that hardware.
#define CS_PIN 10

#define WAIT_DELAY    2000 // ms

#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

// The files in the tune list should be located on the SD card 
// or an error will occur opening the file and the next in the 
// list will be opened (skips errors).
char *tuneList[] = 
{
  "LOOPDEMO.MID",  // simplest and shortest file
  "ELISE.MID",
  "TWINKLE.MID",
  "GANGNAM.MID",
  "FUGUEGM.MID",
  "POPCORN.MID",
  "AIR.MID",
  "PRDANCER.MID",
  "MINUET.MID",
  "FIRERAIN.MID",
  "MOZART.MID",
  "FERNANDO.MID",
  "SONATAC.MID",
  "SKYFALL.MID",
  "XMAS.MID",
  "GBROWN.MID",
  "PROWLER.MID",
  "IPANEMA.MID",
  "JZBUMBLE.MID",
  "SYMPH9.MID",
  "CHATCHOO.MID",
  "STRIPPER.MID"
};

// These don't play as they need more than 16 tracks but will run if MIDIFile.h is changed
//#define MIDI_FILE  "SYMPH9.MID"		// 29 tracks
//#define MIDI_FILE  "CHATCHOO.MID"		// 17 tracks
//#define MIDI_FILE  "STRIPPER.MID"		// 25 tracks

SdFat file;
MD_MIDIFile SMF;

void midiCallback(midi_event *pev)
// Called by the MIDIFile library when a file event needs to be processed
// thru the midi communications interface.
// This callback is set up in the setup() function.
{
  while (!digitalRead(VS_DREQ));
  digitalWrite(VS_XDCS, LOW);
  for (uint8_t i=0; i<pev->size; i++)
  {
    sendMIDI(pev->data[i]);
  }
  digitalWrite(VS_XDCS, HIGH);
}

void midiSilence(void)
// Turn everything off on every channel.
// Some midi files are badly behaved and leave notes hanging, so between songs turn
// off all the notes and sound
{
  midi_event ev;

  // All sound off
  // When All Sound Off is received all oscillators will turn off, and their volume
  // envelopes are set to zero as soon as possible.
  ev.size = 0;
  ev.data[ev.size++] = 0xb0;
  ev.data[ev.size++] = 120;
  ev.data[ev.size++] = 0;

  for (ev.channel = 0; ev.channel < 16; ev.channel++)
    midiCallback(&ev);
}

void setup(void)
{
  SPI.begin(); 
  pinMode(VS_DREQ, INPUT);
  pinMode(VS_XCS, OUTPUT);
  pinMode(VS_XDCS, OUTPUT);
  pinMode(VS_RESET, OUTPUT);
  digitalWrite(VS_XCS, HIGH); //Deselect Controltft.cursorToXY
  digitalWrite(VS_XDCS, HIGH); //Deselect Data
  digitalWrite(VS_RESET, HIGH); 
  // Initialize SD
  if (!SD.begin(CS_PIN, SPI_FULL_SPEED))
  {
//    DEBUG("\nSD init fail!");
    while (true) ;
  }

  // Initialize MIDIFile
  SMF.begin(&file);
  SMF.setMidiHandler(midiCallback);
}

void tickMetronome(void)
// flash a LED to the beat
{
  static uint32_t	lastBeatTime = 0;
  static boolean	inBeat = false;
  uint16_t	beatTime;

  beatTime = 60000/SMF.getTempo();		// msec/beat = ((60sec/min)*(1000 ms/sec))/(beats/min)
  if (!inBeat)
  {
    if ((millis() - lastBeatTime) >= beatTime)
    {
      lastBeatTime = millis();
//      digitalWrite(BEAT_LED, HIGH);
      inBeat = true;
    }
  }
  else
  {
    if ((millis() - lastBeatTime) >= 100)	// keep the flash on for 100ms only
    {
//      digitalWrite(BEAT_LED, LOW);
      inBeat = false;
    }
  }
}

void loop(void)
{
    int  err;
  
  for (uint8_t i=0; i<ARRAY_SIZE(tuneList); i++)
  {
    // use the next file name and play it
//    DEBUG("\nFile: ");
//    DEBUG(tuneList[i]);
    SMF.setFilename(tuneList[i]);
    err = SMF.load();
    if (err != -1)
    {
//    DEBUG("\nSMF load Error ");
//    DEBUG(err);
    delay(WAIT_DELAY);
    }
    else
    {
    // play the file
    while (!SMF.isEOF())
    {
      if (SMF.getNextEvent())
      tickMetronome();
    }

    // done with this one
    SMF.close();
    midiSilence();
    delay(WAIT_DELAY);
    }
  }
}
void sendMIDI(byte data)
{
  SPI.transfer(0x00);
  SPI.transfer(data);
}

Comments

Similar projects you might like

Arduino MIDI Controller with Encoder + OLED Display + EEPROM

Project in progress by yilmazyurdakul

  • 4,635 views
  • 0 comments
  • 17 respects

Arduino 101 Bluetooth MIDI

Project showcase by Don Coleman

  • 7,554 views
  • 0 comments
  • 4 respects

Arduino MIDI Controller

Project tutorial by MEGA DAS

  • 5,955 views
  • 0 comments
  • 21 respects

Back Up SD File to Dropbox

Project tutorial by Andrei Florian

  • 4,079 views
  • 6 comments
  • 36 respects

Arduino LED MIDI Controller with FL Studio

Project tutorial by reyadeetopee

  • 2,965 views
  • 0 comments
  • 12 respects

MIDI Windbell

Project showcase by Team Daddy's Man Cave

  • 2,667 views
  • 3 comments
  • 4 respects
Add projectSign up / Login