summaryrefslogtreecommitdiffstats
path: root/libtdemid/player.h
diff options
context:
space:
mode:
Diffstat (limited to 'libtdemid/player.h')
-rw-r--r--libtdemid/player.h396
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