diff options
Diffstat (limited to 'libtdemid/player.h')
-rw-r--r-- | libtdemid/player.h | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/libtdemid/player.h b/libtdemid/player.h new file mode 100644 index 000000000..ae33de849 --- /dev/null +++ b/libtdemid/player.h @@ -0,0 +1,396 @@ +/* player.h - class MidiPlayer. Plays a set of tracks + This file is part of LibKMid 0.9.5 + Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez + LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libtdemid.html + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org> + +***************************************************************************/ +#ifndef _PLAYER_H +#define _PLAYER_H + +#include <libtdemid/dattypes.h> +#include <libtdemid/midfile.h> +#include <libtdemid/deviceman.h> +#include <libtdemid/track.h> +#include <libtdemid/notearray.h> +#include <kdemacros.h> + +/** + * This struct stores text, lyrics and change tempo events among others. + * + * It includes the main information for an event. That is, the absolute + * millisecond at which this event is played (from the beginning of the song), + * the delta milliseconds from the previous SpecialEvent, an ID, etc. + * + * This struct is used as nodes for a linked list, which you can get using + * MidiPlayer::specialEvents(). + * + * @short Struct used to store certain events + * @version 0.9.5 17/01/2000 + * @author Antonio Larrosa Jimenez <larrosa@kde.org> + */ +struct SpecialEvent +{ + /** + * An integer ID, that is assigned in order to each SpecialEvent. + */ + int id; + + /** + * Delta milliseconds from the previous SpecialEvent. + * + * @see absmilliseconds + */ + ulong diffmilliseconds; + + /** + * The absolute millisecond (from the beginning of the song) at which this + * SpecialEvent object is played. + * + * @see diffmilliseconds + */ + ulong absmilliseconds; + + /** + * MIDI ticks (from the beginning of the song) at which this event is played. + */ + int ticks; + + /** + * Type of event. This currently includes: + * + * @li 0 - Nothing, end of linked list. + * @li 1 - Text Event . See text. + * @li 3 - Change Tempo Event . See tempo. + * @li 5 - Lyrics Event . See text. + * @li 6 - Change number of beats per measure . See num and den. + * @li 7 - Beat . See num and den. + * + * The "Change number of beats per measure" and "beat" events are not really + * in the midi file, but they are added to the linked list in case you have + * an use for it. + */ + int type; + + /** + * Text field . It has a meaning only for Text and Lyrics events. + */ + char text[1024]; + + /** + * Tempo field . It has a meaning only for Change Tempo events. + */ + ulong tempo; + /** + * Numerator . It has a meaning only for Change number of beats per measure and + * beat events. + */ + int num; + /** + * Denominator . It has a meaning only for Change number of beats per measure + * and beat events. + */ + int den; + + /** + * This struct stores text, lyrics and change tempo events among others. + * + * It includes the main information for an event. That is, the absolute + * millisecond at which this event is played (from the beginning of the song), + * the delta milliseconds from the previous SpecialEvent, an ID, etc. + * + * This struct is used as nodes for a linked list, which you can get using + * MidiPlayer::specialEvents(). + */ + struct SpecialEvent *next; + + /** + * Next node in the linked list. + */ + +}; + + +/** + * PlayerController is a struct that is used by the MidiPlayer object + * to tell other parts of the application about the status of the MIDI playing. + * + * @short Struct used to have control over the player engine + * @version 0.9.5 17/01/2000 + * @author Antonio Larrosa Jimenez <larrosa@kde.org> + */ +struct PlayerController +{ + volatile ulong ticksTotal; + volatile ulong ticksPlayed; + volatile double millisecsPlayed; + volatile ulong beginmillisec; + + volatile int tempo; + volatile int num; + volatile int den; + + volatile int SPEVprocessed; + volatile int SPEVplayed; + + /** + * When pause is released, if the caller must know when the player has + * opened the devices and is playing again, then it just has to check + * to see when OK changes the value to 1 + */ + volatile int OK; + + /** + * When the player is playing (or paused), playing is set to 1. + */ + volatile int playing; + + /** + * When the player is paused, paused is set to 1. + */ + volatile int paused; + + /** + * When the player seeking the position of the song, moving is set to 1. + */ + volatile int moving; + + /** + * When the player has finished playing a song, finished is set to 1. + */ + volatile int finished; + + /** + * @internal + * @deprecated + * Not used + */ + volatile int message KDE_DEPRECATED; // set one of the following : + +#define PLAYER_DOPAUSE 1 +#define PLAYER_DOSTOP 2 +#define PLAYER_SETPOS 4 +#define PLAYER_HALT 8 + + volatile ulong gotomsec; //milliseconds to go to,if player_setpos is set + + /** + * When error is 1, an error has ocurred (i.e. it coultn't open the device) + */ + volatile int error; + + /** + * If gm is 1, the song follows the General Midi standard, if gm is 0, the song + * is in MT 32 format. + */ + volatile int gm; + + /** + * 100 means no change, 50 halfs the volume, 200 doubles it (if possible), etc. + * + * @see DeviceManager::setVolumePercentage() + */ + volatile int volumepercentage ; + + /** + * Activate or disactivate the force to use a patch for a given channel. + * @see pgm + */ + volatile bool forcepgm[16]; + + /** + * Force a given patch in each channel at "this" moment, as determined by + * forcepgm. + */ + volatile int pgm[16]; + + /** + * Ratio to multiply the tempo to. + */ + volatile double ratioTempo; + + /** + * @internal Used to stop the main pid until the child has finished to + * send the all notes off event + */ + volatile bool isSendingAllNotesOff; + + volatile MidiEvent *ev; +}; + + +/** + * MIDI file player routines . This class reads a MIDI file and + * play it using a DeviceManager object. + * + * To use it, just call loadSong() with the filename you want to play, + * and then play(). + * + * Please have a look at the note in the play() documentation. + * + * MidiPlayer will write information about the playing process on a + * PlayerController() structure that you must supply to the constructor + * + * Alternatively, if everything you want is to play a midi file in a game or + * any other application that doesn't need to fine tune the midi playing, just + * use the tdemidplay() function. + * + * @see KMidSimpleAPI + * + * @short The MIDI file player engine + * @version 0.9.5 17/01/2000 + * @author Antonio Larrosa Jimenez <larrosa@kde.org> + */ +class KMID_EXPORT MidiPlayer +{ + class MidiPlayerPrivate; + MidiPlayerPrivate *d; + + DeviceManager *midi; + MidiFileInfo *info; + MidiTrack **tracks; + SpecialEvent *spev; + NoteArray *na; + + int songLoaded; + + PlayerController *ctl; + + bool parsesong; + bool generatebeats; + + void removeSpecialEvents(void); + void parseSpecialEvents(void); + void insertBeat(SpecialEvent *ev,ulong ms,int num,int den); + void generateBeats(void); + + //NoteArray *parseNotes(void); + void debugSpecialEvents(void); + public: + + /** + * Constructor . You must construct and pass a DeviceManager object and a + * PlayerController structure. None of them will be destroyed by this + * object, so you should do it after destroying the MidiPlayer object. + */ + MidiPlayer(DeviceManager *midi_,PlayerController *pctl); + + /** + * Destructor. + */ + ~MidiPlayer(); + + /** + * Loads a Song, and parses it (it the parse wasn't disabled with + * setParseSong() ) . It also generates the Beat events (see + * SpecialEvent::type() ) if you enabled this by using + * setGenerateBeats() . + */ + int loadSong(const char *filename); + + /** + * Unloads the current song, so that every internal variable is empty and clean + * for further usage. + */ + void removeSong(void); + + /** + * Returns true if there's a song already loaded (with a previous call to + * loadSong() ) and false if not. + */ + int isSongLoaded(void) { return songLoaded; } + + /** + * Returns the linked list of SpecialEvents objects . For this to work, + * the parse should be enabled (the default), by using setParseSong(). + */ + SpecialEvent *specialEvents() { return spev; } + + /** + * Returns and array with the notes playen through the song . MidiPlayer must + * parse the song to get the notes, so be sure not to disable the parsing of + * the song. + * + * Returns an array of notes, (just note on and note off events), in the form + * of a NoteArray object + */ + NoteArray *noteArray(void) { return na; } + + + /** + * Plays the song using the DeviceManager object supplied in the + * constructor. It should be already configured, as play doesn't change the + * volume, nor midi mapper, for example. + * + * Note: Calling this function will block the execution of your application + * until the song finishes playing. The solution for this is simple, fork + * before calling it, and create the PlayerController object on shared + * memory. + * + * As alternative, if everything you want is playing a midi file in a game or + * any other application that doesn't need to fine tune the midi playing, just + * use the KMidSimpleAPI::kMidPlay() function. + * + * @see KMidSimpleAPI::kMidInit + * @see KMidSimpleAPI::kMidPlay + * @see KMidSimpleAPI::kMidStop + * @see KMidSimpleAPI::kMidDestruct + */ + void play(bool calloutput=false,void output(void) = 0); + + /** + * Enables or disables the parsing of the song when loading it. This affects + * the SpecialEvents ( specialEvents() ) and the NoteArray + * ( noteArray() ). + */ + void setParseSong(bool b = true); + + /** + * Enables or disables the generation of beats event in a song when loading + * it. + */ + void setGenerateBeats(bool b = false); + + /** + * Returns information about the current MIDI file. + * + * @see loadSong + */ + MidiFileInfo *information(void) { return info; } + + /** + * Sets the position in a song. + * @param gotomsec the number of milliseconds to go to . A subsequent call to + * play() will start playing the song from that moment, instead of the + * beginning. + * @param midistat a MidiStatus object that will contain the status in + * which the MIDI device would be if it would have arrived to this situation by + * a normal playing of the song. + */ + void setPos(ulong gotomsec, class MidiStatus *midistat); + + /** + * Changes the speed at which a song is played. The song's tempo is multiplied + * by the specified ratio. + */ + void setTempoRatio(double ratio); + +}; + +#endif |