MD_MIDIFile Standard MIDI File Processing 2.6
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)
 
void setFileFolder (const char *apath)
 
int load (const char *fname)
 
Methods for SMF header data
uint8_t getFormat (void)
 
uint8_t getTrackCount (void)
 
Methods for MIDI playback control
void looping (bool bMode)
 
bool isLooping (void)
 
void pause (bool bMode)
 
bool isPaused (void)
 
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)
 

Static Public Attributes

static const int E_OK = 0
 No errors. More...
 
static const int E_NO_FILE = 1
 Blank file name.
 
static const int E_NO_OPEN = 2
 Can't open file specified.
 
static const int E_NOT_MIDI = 3
 File is not MIDI format.
 
static const int E_HEADER = 4
 MIDI header size incorrect.
 
static const int E_FORMAT = 5
 File format type not 0 or 1.
 
static const int E_FORMAT0 = 6
 File format 0 but more than 1 track.
 
static const int E_TRACKS = 7
 More than MIDI_MAX_TRACKS required.
 
static const int E_CHUNK_ID = 0
 error >= 10; n0 Track n track chunk not found
 
static const int E_CHUNK_EOF = 1
 error >= 10; n1 Track n chunk size past end of file
 

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
 
const char * _fileName
 MIDI file name buffer in user code.
 
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 _synchDone
 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. The SDFs 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.

This is a pointer to a user defined buffer passed to the load() method when the file is opened. The scope and persistence of this buffer depends on what the user code does, so the pointer returned may be invalid if the pointer references a buffer that has become out of scope.

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 true when this condition is reached.

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

◆ isLooping()

bool MD_MIDIFile::isLooping ( void  )

Get the current looping mode

Returns the currently set looping mode.

See also
looping()
Returns
Current looping mode.

◆ isPaused()

bool MD_MIDIFile::isPaused ( void  )

Get the current pause mode

Returns the currently set pause mode.

See also
looping()
Returns
Current paused mode.

◆ load()

int MD_MIDIFile::load ( const char *  fname)

Load the named SMF

Before it can be processed, a file must be opened, loaded and the MIDI playback initialized by invoking this method.

The file name specified can include path or just a file name. If not fully specified the file is located in the current working folder, which is the root folder by default. For files not in the root folder, change the current folder using the setFileFolder() method.

The file name buffer is located in user code and must persist during this call.

See also
setFileFolder()
Parameters
fnamepointer to a user buffered string with the file name.
Returns
Error code with one of the E_* error values

◆ 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, all callbacks are suspended.

Note that this call only stops the library from processing the file and has no effect on the playback device. Silencing the MIDI playback device during the pause is the responsibility of the user application.

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.

◆ setFileFolder()

void MD_MIDIFile::setFileFolder ( const char *  apath)

Set the current folder for the SMF

Sets the current working folder to the specified path. All subsequent simple (ie, not fully qualified) file names passed to setFilename() are referenced to this folder location.

The default file location is the root folder denoted by "/"

See also
setFilename
Parameters
apathpointer to a string with the path name.
Returns
No return data.

◆ setFilename()

void MD_MIDIFile::setFilename ( const char *  aname)

Set the name of the SMF

THIS METHOD IS DEPRECATED. Use play() with the file name.

Stores the pointer reference to the supplied name. The file name buffer is located in user code and must persist at least until the load() method is invoked.

The file specified can include path or just a file name. If not fully specified the file is located in the current working folder, which is the root folder by default. For files not in the root folder, change the current folder using the setFileFolder() method.

See also
setFileFolder(), load()
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.

Member Data Documentation

◆ E_OK

const int MD_MIDIFile::E_OK = 0
static

No errors.

Error codes as constants


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