MD_MIDIFile Standard MIDI File Processing 2.6
Library to play Standard MIDI Files (SMF)
|
#include <MD_MIDIFile.h>
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 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 |
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.
MD_MIDIFile::MD_MIDIFile | ( | void | ) |
Class Constructor
Instantiate a new instance of the class.
MD_MIDIFile::~MD_MIDIFile | ( | void | ) |
Class Destructor
Released allocated memory and does the necessary to clean up once the object is no longer required.
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.
psd | Pointer to the SDFat object. |
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().
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.
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.
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
The load() method must be invoked to read the SMF header information.
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.
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.
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.
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.
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.
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.
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.
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.
bool MD_MIDIFile::isLooping | ( | void | ) |
Get the current looping mode
Returns the currently set looping mode.
bool MD_MIDIFile::isPaused | ( | void | ) |
Get the current pause mode
Returns the currently set pause mode.
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.
fname | pointer to a user buffered string with the file name. |
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.
bMode | Set true to enable mode, false to disable. |
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.
bMode | Set true to enable mode, false to disable. |
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:
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().
ticks | the number of ticks since the last call to this method. |
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.
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 "/"
apath | pointer to a string with the path name. |
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.
aname | pointer to a string with the file name. |
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!).
mh | the address of the function to be called from the library. |
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.
m | the number of microseconds per quarter note. |
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!).
mh | the address of the function to be called from the library. |
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!).
sh | the address of the function to be called from the library. |
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.
t | the tempo required. |
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.
t | the tempo adjustment required. |
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.
ticks | the number of ticks per quarter note. |
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.
n | numerator of the time signature. |
d | denominator of the time signature. |
|
static |
No errors.
Error codes as constants