MIDI *load_midi(char *filename);
Loads a MIDI file (handles both format 0 and format 1), returning a
pointer to a MIDI structure, or NULL on error.
void destroy_midi(MIDI *midi);
Destroys a MIDI structure when you are done with it. It is safe to call
this even when the MIDI file might be playing, because it checks and will
kill it off if it is active.
int play_midi(MIDI *midi, int loop);
Starts playing the specified MIDI file, first stopping whatever music was
previously playing. If the loop flag is set, the data will be repeated
until replaced with something else, otherwise it will stop at the end of
the file. Passing a NULL pointer will stop whatever music is currently
playing. Returns non-zero if an error occurs (this may happen if a
patch-caching wavetable driver is unable to load the required samples, or
at least it might in the future when somebody writes some patch-caching
wavetable drivers :-)
int play_looped_midi(MIDI *midi, int loop_start, int loop_end);
Starts playing a MIDI file with a user-defined loop position. When the
player reaches the loop end position or the end of the file (loop_end may
be -1 to only loop at EOF), it will wind back to the loop start point.
Both positions are specified in the same beat number format as the
midi_pos variable.
void stop_midi();
Stops whatever music is currently playing. This is the same thing as
calling play_midi(NULL, FALSE).
void midi_pause();
Pauses the MIDI player.
void midi_resume();
Resumes playback of a paused MIDI file.
int midi_seek(int target);
Seeks to the given midi_pos in the current MIDI file. If the target is
earlier in the file than the current midi_pos it seeks from the
beginning; otherwise it seeks from the current position. Returns zero if
successful, non-zero if it hit the end of the file (1 means it stopped
playing, 2 means it looped back to the start). If this function stops
because it reached EOF, midi_pos will be set to the negative length of
the MIDI file.
void midi_out(unsigned char *data, int length);
Streams a block of MIDI commands into the player in realtime, allowing
you to trigger notes, jingles, etc, over the top of whatever MIDI file is
currently playing.
int load_midi_patches();
Forces the MIDI driver to load the entire set of patches ready for use.
You will not normally need to call this, because Allegro automatically
loads whatever data is required for the current MIDI file, but you must
call it before sending any program change messages via the midi_out()
command. Returns non-zero if an error occurred.
extern volatile long midi_pos;
Stores the current position (beat number) in the MIDI file, or contains
a negative number if no music is currently playing. Useful for
synchronising animations with the music, and for checking whether a MIDI
file has finished playing.
extern long midi_loop_start;
extern long midi_loop_end;
The loop start and end points, set by the play_looped_midi() function.
These may safely be altered while the music is playing, but you should be
sure they are always set to sensible values (start < end). If you are
changing them both at the same time, make sure to alter them in the right
order in case a MIDI interrupt happens to occur in between your two
writes! Setting these values to -1 represents the start and end of the
file respectively.
extern void (*midi_msg_callback)(int msg, int byte1, int byte2);
extern void (*midi_meta_callback)(int type, unsigned char *data, int length);
extern void (*midi_sysex_callback)(unsigned char *data, int length);
Hook functions allowing you to intercept MIDI player events. If set to
anything other than NULL, these routines will be called for each MIDI
message, meta-event, and system exclusive data block respectively. They
will execute in an interrupt handler context, so all the code and data
they use should be locked, and they must not call any operating system
functions. In general you just use these routines to set some flags and
respond to them later in your mainline code.
int load_ibk(char *filename, int drums);
Reads in a .IBK patch definition file for use by the Adlib driver. If
drums is set, it will load it as a percussion patch set, otherwise it
will use it as a replacement set of General MIDI instruments. You may
call this before or after initialising the sound code, or can simply set
the ibk_file and ibk_drum_file variables in the configuration file to
have the data loaded automatically. Note that this function has no effect
on any drivers other than the Adlib one!