# Source: player.h |
Annotated List
Files
Globals
Hierarchy
Index

    /*  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/libkmid.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., 59 Temple Place - Suite 330,
        Boston, MA 02111-1307, USA.

        Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>

    ***************************************************************************/
    #ifndef _PLAYER_H
    #define _PLAYER_H

    #include <libkmid/dattypes.h>
    #include <libkmid/midfile.h>
    #include <libkmid/deviceman.h>
    #include <libkmid/track.h>
    #include <libkmid/notearray.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
     * @ref 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 @ref #text.
       * @li 3 - Change Tempo Event . See @ref #tempo.
       * @li 5 - Lyrics Event . See @ref #text.
       * @li 6 - Change number of beats per measure . See @ref #num and @ref den.
       * @li 7 - Beat . See @ref #num and @ref #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
       * @ref MidiPlayer::specialEvents().
       */
      struct SpecialEvent *next;

      /**
       * Next node in the linked list.
       */

    };

    /**
     * PlayerController is a struct that is used by the @ref 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; // 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
       * @ref #forcepgm.
       */
      volatile int pgm[16];

      /**
       * Ratio to multiply the tempo to.
       */
      volatile double ratioTempo;

      volatile MidiEvent *ev;
    };

    /**
     * MIDI file player routines . This class reads a MIDI file and
     * play it using a @ref DeviceManager object.
     *
     * To use it, just call @ref #loadSong() with the filename you want to play,
     * and then @ref #play().
     *
     * Please have a look at the note in the @ref #play() documentation.
     *
     * MidiPlayer will write information about the playing process on a
     * @ref 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 @ref kmidplay() function.
     *
     * @see KMidSimpleAPI
     *
     * @short The MIDI file player engine
     * @version 0.9.5 17/01/2000
     * @author Antonio Larrosa Jimenez <larrosa@kde.org>
     */
    class 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 @ref DeviceManager object and a
       * @ref 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
       * @ref #setParseSong() ) . It also generates the Beat events (see
       * @ref SpecialEvent::type() ) if you enabled this by using
       * @ref #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
       * @ref loadSong() ) and false if not.
       */
      int isSongLoaded(void) { return songLoaded; };

      /**
       * Returns the linked list of @ref SpecialEvents objects . For this to work,
       * the parse should be enabled (the default), by using @ref #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 @ref NoteArray object
       */
      NoteArray *noteArray(void) { return na; };

      /**
       * Plays the song using the @ref 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 @ref 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 @ref 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 (@ref #specialEvents() ) and the NoteArray
       * (@ref #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
       * @ref #play() will start playing the song from that moment, instead of the
       * beginning.
       * @param midistat a @ref 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

Generated by: root@sparc.ports.openbsd.org on Wed May 2 09:49:53 2001, using kdoc 2.0a53.