MD_MIDIFile Standard MIDI File Processing  2.3
Library to play Standard MIDI Files (SMF)
MD_MIDIFile Class Reference

#include <MD_MIDIFile.h>

+ Collaboration diagram for MD_MIDIFile:

Public Member Functions

 MD_MIDIFile (void)
 
 ~MD_MIDIFile (void)
 
void begin (SdFat *psd)
 
Methods for MIDI time base
uint32_t getTickTime (void)
 
uint16_t getTempo (void)
 
int16_t getTempoAdjust (void)
 
uint16_t getTicksPerQuarterNote (void)
 
uint16_t getTimeSignature (void)
 
void setMicrosecondPerQuarterNote (uint32_t m)
 
void setTempo (uint16_t t)
 
void setTempoAdjust (int16_t t)
 
void setTicksPerQuarterNote (uint16_t ticks)
 
void setTimeSignature (uint8_t n, uint8_t d)
 
Methods for SMF file handling
void close (void)
 
bool isEOF (void)
 
const char * getFilename (void)
 
void setFilename (const char *aname)
 
int load (void)
 
Methods for SMF header data
uint8_t getFormat (void)
 
uint8_t getTrackCount (void)
 
Methods for MIDI playback control
void looping (bool bMode)
 
void pause (bool bMode)
 
void restart (void)
 
Methods for data handling
boolean getNextEvent (void)
 
void processEvents (uint16_t ticks)
 
void setMidiHandler (void(*mh)(midi_event *pev))
 
void setSysexHandler (void(*sh)(sysex_event *pev))
 
void setMetaHandler (void(*mh)(const meta_event *mev))
 
Methods for debugging
void dump (void)
 

Protected Member Functions

void calcTickTime (void)
 called internally to update the tick time when parameters change
 
void initialise (void)
 initialize class variables all in one place
 
void synchTracks (void)
 synchronize the start of all tracks
 
uint16_t tickClock (void)
 work out the number of ticks since the last event check
 

Protected Attributes

void(* _midiHandler )(midi_event *pev)
 callback into user code to process MIDI stream
 
void(* _sysexHandler )(sysex_event *pev)
 callback into user code to process SYSEX stream
 
void(* _metaHandler )(const meta_event *pev)
 callback into user code to process META stream
 
char _fileName [13]
 MIDI file name - should be 8.3 format.
 
uint8_t _format
 file format - 0: single track, 1: multiple track, 2: multiple song
 
uint8_t _trackCount
 number of tracks in file
 
uint16_t _ticksPerQuarterNote
 time base of file
 
uint32_t _tickTime
 calculated per tick based on other data for MIDI file
 
uint16_t _lastTickError
 error brought forward from last tick check
 
uint32_t _lastTickCheckTime
 the last time (microsec) an tick check was performed
 
bool _syncAtStart
 sync up at the start of all tracks
 
bool _paused
 if true we are currently paused
 
bool _looping
 if true we are currently looping
 
uint16_t _tempo
 tempo for this file in beats per minute
 
int16_t _tempoDelta
 tempo offset adjustment in beats per minute
 
uint8_t _timeSignature [2]
 time signature [0] = numerator, [1] = denominator
 
uint8_t _selectSD
 SDFat select line.
 
SdFat * _sd
 SDFat library descriptor supplied by calling program.
 
SdFile _fd
 SDFat file descriptor.
 
MD_MFTrack _track [MIDI_MAX_TRACKS]
 the track data for this file
 

Friends

class MD_MFTrack
 

Detailed Description

Core object for the MD_MIDIFile library

This is the class to handle a MIDI file, including all tracks, and is the only one available to user programs.

Constructor & Destructor Documentation

◆ MD_MIDIFile()

MD_MIDIFile::MD_MIDIFile ( void  )

Class Constructor

Instantiate a new instance of the class.

Returns
No return data.

◆ ~MD_MIDIFile()

MD_MIDIFile::~MD_MIDIFile ( void  )

Class Destructor

Released allocated memory and does the necessary to clean up once the object is no longer required.

Returns
No return data.

Member Function Documentation

◆ begin()

void MD_MIDIFile::begin ( SdFat *  psd)

Initialize the object

Initialize the object data. This needs to be called during setup() to initialize new data for the class that cannot be done during the object creation.

The main purpose if to pass in a pointer to the SDFat object will be used for file operations on the SMF. A copy of this pointer is retained by the library for the life of the MD_MIDIFile object. THge SDFat object should be initialized before calling this method.

Parameters
psdPointer to the SDFat object.
Returns
No return data.

◆ close()

void MD_MIDIFile::close ( void  )

Close the SMF

Before a new SMF is processed the current SMF must be closed. All tracks are stopped and the file name is reset. A new file can then be started using load().

Returns
No return data.

◆ dump()

void MD_MIDIFile::dump ( void  )

Dump the SMF header data to the debug stream

During debugging, this method provides a formatted dump of data to the debug output stream.

The DUMP_DATA macro define must be set to 1 to enable this method.

◆ getFilename()

const char* MD_MIDIFile::getFilename ( void  )

Get the name of the SMF

Gets a pointer to the buffer containing the name of the SMF.

Returns
character pointer to the name string

◆ getFormat()

uint8_t MD_MIDIFile::getFormat ( void  )

Get the format of the SMF

The SMF header specifies which of three SMF formats applies to the file

  • Type 0 file contains the entire performance, merged onto a single track
  • Type 1 files may contain any number of tracks, running synchronously.
  • Type 2 files may contain any number of tracks, running asynchronously. This type is rarely used and not supported by this library..

The load() method must be invoked to read the SMF header information.

Returns
number [0..2] representing the format.

◆ getNextEvent()

boolean MD_MIDIFile::getNextEvent ( void  )

Read and process the next event from the SMF

Once a SMF is ready for processing, this method is called as frequently as possible to process the next MIDI, SYSEX or META from the tracks in the SMF.

This method will generate the tick timing from the Arduino microsecond clock. If an event needs to be processed this function will call processEvents() to do the work.

Returns
true if a 'tick' has passed since the last call.

◆ getTempo()

uint16_t MD_MIDIFile::getTempo ( void  )

Get the overall tempo

Retrieve the overall tempo for the MIDI playback. Tempo is set by the SMF and the setTempo() method.

Returns
the tempo.

◆ getTempoAdjust()

int16_t MD_MIDIFile::getTempoAdjust ( void  )

Get the tempo adjust offset

Retrieve the tempo adjustment offset for the MIDI playback. Tempo adjust is set by the setTempoAdjust() method.

Returns
the tempo.

◆ getTicksPerQuarterNote()

uint16_t MD_MIDIFile::getTicksPerQuarterNote ( void  )

Get the number of ticks per quarter note

Retrieve the number of ticks per quarter note for the MIDI playback. TPQN is set by the SMF and the setTicksPerQuarterNote() method.

Returns
the number of TPQN.

◆ getTickTime()

uint32_t MD_MIDIFile::getTickTime ( void  )

Get the internally calculated tick time

Changes to tempo, TPQN and time signature all affect the tick time. This returns the number of microseconds for each tick.

Returns
the tick time in microseconds

◆ getTimeSignature()

uint16_t MD_MIDIFile::getTimeSignature ( void  )

Get the Time Signature

Retrieve the time signature for the MIDI playback. Time Signature is set by the SMF and the setTimeSignature() method.

Returns
the time signature (numerator in the top byte and the denominator in the lower byte).

◆ getTrackCount()

uint8_t MD_MIDIFile::getTrackCount ( void  )

Get the number of tracks in the file

The SMF header specifies the number of MIDI tracks in the file. This must be between [0..MIDI_MAX_TRACKS-1] for the SMF to be successfully processed.

The load() method must be invoked to read the SMF header information.

Returns
the number of tracks in the file

◆ isEOF()

bool MD_MIDIFile::isEOF ( void  )

Check if SMF is and end of file

An SMF is at EOF when there is nothing left to play (ie, all tracks have finished). The method will return EOF when this condition is reached.

Returns
true if the SMF is at EOF, false otherwise.

◆ load()

int MD_MIDIFile::load ( void  )

Load the SMF

Before it can be processed, a file must be opened, loaded and the MIDI playback initialized by invoking this method. The file name must be set using the setfilename() method before calling load().

Returns
Error code with one of these values
  • -1 = no errors
  • 0 = Blank file name
  • 2 = Can't open file specified
  • 3 = File is not MIDI format
  • 4 = MIDI header size incorrect
  • 5 = File format type not 0 or 1
  • 6 = File format 0 but more than 1 track
  • 7 = More than MIDI_MAX_TRACKS required
  • n0 = Track n track chunk not found
  • n1 = Track n chunk size past end of file

◆ looping()

void MD_MIDIFile::looping ( bool  bMode)

Set the looping mode for SMF playback

A SMF can be set to automatically loop to the start once it has completed. For SMF file type 0 (1 track only) the single track is looped. For file type 1, all tracks except track 0 (the first) is looped. Track 0 contains global setup information that does not need to be repeated and would delay the restart of the looped tracks.

Parameters
bModeSet true to enable mode, false to disable.
Returns
No return data.

◆ pause()

void MD_MIDIFile::pause ( bool  bMode)

Pause or un-pause SMF playback

SMF playback can be paused (true) or un-paused (false) using this method. Whilst in pause mode, calls to methods to play the SMF will not work.

Parameters
bModeSet true to enable mode, false to disable.
Returns
No return data.

◆ processEvents()

void MD_MIDIFile::processEvents ( uint16_t  ticks)

Read and process the next event from the SMF

This method processes the events in the SMF that are due to be processed, given the number of ticks that have passed since the last call to the method. No tick timer calculations or other checks are performed, so this function is suitable to be called from user code that implements timer synchronization with an external MIDI clock.

Events in the SMF are processed in sequential order in one of 2 different ways:

  • process all events on one track before moving on to the next track (TRACK_PRIORITY)
  • process one event from each track and cycling through all tracks round robin fashion until no events are left to be processed (EVENT_PRIORITY).

The TRACK_PRIORITY define selects which is used. In practice there is little or no difference between the two methods.

Each MIDI and SYSEX event is passed back to the calling program for processing though the callback functions set up by setMidiHandler() and setSysexHandler().

Parameters
ticksthe number of ticks since the last call to this method.
Returns
No return data

◆ restart()

void MD_MIDIFile::restart ( void  )

Force the SMF to be restarted

SMF playback can be reset back to the beginning of all tracks using this method. The method can be invoked at any time during playback and has immediate effect.

Returns
No return data.

◆ setFilename()

void MD_MIDIFile::setFilename ( const char *  aname)

Set the name of the SMF

Copies the supplied name to the class file name buffer. The name is expected to be in 8.3 format.

Parameters
anamepointer to a string with the file name.
Returns
No return data.

◆ setMetaHandler()

void MD_MIDIFile::setMetaHandler ( void(*)(const meta_event *mev)  mh)

Set the META callback function

The callback function is called from the library when a META events read from a track needs to be processed.

The callback function has one parameter of type meta_event. The pointer passed to the callback will be initialized with the meta data for the callback to process. Once the function returns from the callback the pointer may no longer be valid (ie, don't rely on it!).

Parameters
mhthe address of the function to be called from the library.
Returns
No return data

◆ setMicrosecondPerQuarterNote()

void MD_MIDIFile::setMicrosecondPerQuarterNote ( uint32_t  m)

Set the internal tick time

Set the number of microseconds per quarter note directly. Normally this is calculated from the tempo and ticks per quarter note.

Parameters
mthe number of microseconds per quarter note.
Returns
No return data.

◆ setMidiHandler()

void MD_MIDIFile::setMidiHandler ( void(*)(midi_event *pev)  mh)

Set the MIDI callback function

The callback function is called from the library when a MIDI events read from a track needs to be processed.

The callback function has one parameter of type midi_event. The pointer passed to the callback will be initialized with the event data for the callback to process. Once the function returns from the callback the pointer may no longer be valid (ie, don't rely on it!).

Parameters
mhthe address of the function to be called from the library.
Returns
No return data

◆ setSysexHandler()

void MD_MIDIFile::setSysexHandler ( void(*)(sysex_event *pev)  sh)

Set the SYSEX callback function

The callback function is called from the library when a SYSEX events read from a track needs to be processed.

The callback function has one parameter of type sysex_event. The pointer passed to the callback will be initialized with the event data for the callback to process. Once the function returns from the callback the pointer may no longer be valid (ie, don't rely on it!).

Parameters
shthe address of the function to be called from the library.
Returns
No return data

◆ setTempo()

void MD_MIDIFile::setTempo ( uint16_t  t)

Set the overall tempo

Set the overall tempo for the MIDI playback. Tempo is set by the SMF but can be changed through this method.

The default MIDI tempo if not specified is 120 beats/minute.

Parameters
tthe tempo required.
Returns
No return data.

◆ setTempoAdjust()

void MD_MIDIFile::setTempoAdjust ( int16_t  t)

Set the tempo adjustment offset

Set the tempo offset for all tempo settings. This is useful to speed up a whole SMF by a set amount for the MIDI playback. The offset from SMF specified may be The Tempo set by the SMF can be increased changed through this method.

The default tempo offset if not specified is 0 beats/minute.

Parameters
tthe tempo adjustment required.
Returns
No return data.

◆ setTicksPerQuarterNote()

void MD_MIDIFile::setTicksPerQuarterNote ( uint16_t  ticks)

Set number of ticks per quarter note (TPQN)

Set the overall ticks per quarter note tempo for the MIDI playback. TPQN is set by the SMF but can be changed through this method.

The default if not specified is 48 TPQN.

Parameters
ticksthe number of ticks per quarter note.
Returns
No return data.

◆ setTimeSignature()

void MD_MIDIFile::setTimeSignature ( uint8_t  n,
uint8_t  d 
)

Set Time Signature for the SMF

Set the time signature for the MIDI playback. Time signature is specified in 2 parts defined by the numerator and the denominator of the normal notation.

The default if not specified is 4/4.

Parameters
nnumerator of the time signature.
ddenominator of the time signature.
Returns
No return data.

The documentation for this class was generated from the following files: