![]() |
MD_MIDIFile Standard MIDI File Processing
2.3
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) |
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 |
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. THge SDFat 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.
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 when this condition is reached.
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().
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, calls to methods to play the SMF will not work.
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::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.
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. |