home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / libkmid / deviceman.h < prev    next >
Encoding:
C/C++ Source or Header  |  2007-10-08  |  16.1 KB  |  538 lines

  1. /*  deviceman.h  - The device manager, that hides the use of midiOut
  2.     This file is part of LibKMid 0.9.5
  3.     Copyright (C) 1997,98,99,2000  Antonio Larrosa Jimenez
  4.     LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public License
  16.     along with this library; see the file COPYING.LIB.  If not, write to
  17.     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  18.     Boston, MA 02110-1301, USA.
  19.  
  20.     Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>
  21.  
  22. ***************************************************************************/
  23. #ifndef DEVICEMAN_H
  24. #define DEVICEMAN_H
  25.  
  26. #include <libkmid/dattypes.h>
  27. #include <kdelibs_export.h>
  28.  
  29. class MidiOut;
  30. class MidiMapper;
  31.  
  32. /**
  33.  * MIDI Device Manager class . This class is the one you should use to
  34.  * send MIDI events to any device, as it creates and manages the *Out classes.
  35.  *
  36.  * This class is usually used by creating a DeviceManager object, then call
  37.  * openDev() and initDev() . Then, use numberOfMidiPorts(),
  38.  * numberOfSynthDevices(), name() and type() to choose which
  39.  * device to play MIDI events to and then use defaultDevice() to set the
  40.  * MIDI device to play.
  41.  *
  42.  * @short Manages all MIDI devices and redirects MIDI events to each one as
  43.  * configured.
  44.  * @version 0.9.5 17/01/2000
  45.  * @author Antonio Larrosa Jimenez <larrosa@kde.org>
  46.  */
  47. class KMID_EXPORT DeviceManager
  48. {
  49.   protected:
  50.  
  51.     /**
  52.      * @internal
  53.      * The midi devices objects
  54.      */
  55.     MidiOut **device;
  56.  
  57.     /**
  58.      * @internal
  59.      * Midi info
  60.      */
  61.     struct midi_info *midiinfo;
  62.  
  63.     /**
  64.      * @internal
  65.      * Synth info
  66.      */
  67.     struct synth_info *synthinfo;
  68.  
  69.     /**
  70.      * @internal
  71.      * Stores the device thru which a channel will be sent
  72.      */
  73.     int chn2dev[16];
  74.  
  75.     /**
  76.      * @internal
  77.      * Number of synths devices
  78.      */
  79.     int n_synths;
  80.  
  81.     /**
  82.      * @internal
  83.      * Number of midi ports
  84.      */
  85.     int n_midi;
  86.  
  87.     /**
  88.      * @internal
  89.      * n_midi + n_synths
  90.      */
  91.     int n_total;
  92.  
  93.     /**
  94.      * @internal
  95.      * rate
  96.      */
  97.     int m_rate;
  98.  
  99.     /**
  100.      * @internal
  101.      * A "constant" used to convert from milliseconds to the computer rate.
  102.      */
  103.     double convertrate;
  104.  
  105.     /**
  106.      * @internal
  107.      * Newest kernels don't want me to stop a timer that hasn't been started :-)
  108.      */
  109.     int timerstarted;
  110.  
  111.     /**
  112.      * @internal
  113.      * Last time waited for in wait(double)
  114.      */
  115.     double lastwaittime;
  116.  
  117.     /**
  118.      * @internal
  119.      * Keeps a pointer to the mapper so that if devices weren't initialized when
  120.      * first called setMidiMap then, when they get initialized, they use the
  121.      * proper mapper
  122.      */
  123.     MidiMapper *mapper_tmp;
  124.  
  125.     int initialized;
  126.  
  127.     /**
  128.      * @internal
  129.      * The real file handler for /dev/sequencer, that is opened and closed.
  130.      */
  131.     int seqfd;
  132.  
  133.     /**
  134.      * @internal
  135.      * The device to which timer events will be sent
  136.      */
  137.     int default_dev;
  138.  
  139.     /**
  140.      * @internal
  141.      */
  142.     int _ok;
  143.  
  144.     /**
  145.      * @internal
  146.      * True if the user is running ALSA. False if (s)he's using OSS
  147.      */
  148.     bool alsa;
  149.  
  150.     /**
  151.      * @internal
  152.      */
  153.     void seqbuf_dump (void);
  154.  
  155.     /**
  156.      * @internal
  157.      */
  158.     void seqbuf_clean (void);
  159.  
  160.     /**
  161.      * @internal
  162.      */
  163.     void checkAlsa (void);
  164.   public:
  165.     /**
  166.      * Constructor. It just initializes internal variables, before playing any
  167.      * music, you should call initManager(), setMidiMap()
  168.      * (optional), openDev(), initDev(), setPatchesToUse()
  169.      * (not required, unless you're playing to a GUS device, which must load
  170.      * the patches), tmrStart(), and finally, play the music.
  171.      */
  172.     DeviceManager(int def=-1);
  173.  
  174.     /**
  175.      * Destructor. It closes the device (calling closeDev() ) if it wasn't
  176.      * closed before.
  177.      */
  178.     ~DeviceManager(void);
  179.  
  180.     /**
  181.      * Initializes the MIDI Device Manager object.
  182.      *
  183.      * The /dev/sequencer and/or /dev/snd/seq files are opened, available
  184.      * devices are analyzed and *Out objects are created. Then, the
  185.      * device files are closed.
  186.      *
  187.      * @return 0 if everything was OK, or -1 if there was an error and it
  188.      * couldn't be initialized (for example, because it couldn't open the
  189.      * /dev/sequencer file)
  190.      */
  191.     int initManager(void);
  192.  
  193.     /**
  194.      * Checks if the device manager has been initialized (with @p initManager),
  195.      * and in case it wasn't, initializes it.
  196.      *
  197.      * @return 0 if it was (or has just been) correctly initialized, and -1 if
  198.      * there was an error.
  199.      */
  200.     int checkInit(void);
  201.  
  202.     /**
  203.      * \obsolete Please use deviceForChannel() instead.
  204.      *
  205.      */
  206.     MidiOut *chntodev(int chn)
  207.         { return deviceForChannel(chn); }
  208.  
  209.     /**
  210.      * It's possible to send different MIDI channels to different MIDI devices,
  211.      * so that you can for example send channel 1 to an external synthesizer,
  212.      * channel 2 to a FM device and channel 10 to an AWE synth.
  213.      *
  214.      * @return the device to which MIDI events goind to channel @p chn should
  215.      * be sent.
  216.      */
  217.     MidiOut *deviceForChannel(int chn)
  218.         { return (device!=0L) ? device[chn2dev[chn]] : 0L ; }
  219.  
  220.     /**
  221.      * Returns the device number associated with a given channel.
  222.      */
  223.     int deviceNumberForChannel(int chn) { return chn2dev[chn]; }
  224.  
  225.     /**
  226.      * Sets the device number associated with a given channel.
  227.      */
  228.     void setDeviceNumberForChannel(int chn, int dev);
  229.  
  230.     /**
  231.      * @return 0 if there was a problem and 1 if everything was OK. Note that the
  232.      * return value is changed after you check it, so you can only check it once.
  233.      */
  234.     int ok(void);
  235.  
  236.     /**
  237.      * Returns true if it's running ALSA and false if OSS is being run
  238.      */
  239.     int usingAlsa(void) { return alsa; }
  240.  
  241.     // The following function are here to emulate a midi, so that the
  242.     // DeviceManager sends the events to the appropriate devices.
  243.  
  244.     /**
  245.      * Open the devices. It first initializes the manager it that wasn't done
  246.      * yet (you should do it yourself, to be able to choose the MIDI output
  247.      * device, as it will be set to an external synth by default, if available).
  248.      *
  249.      * Then /dev/sequencer is opened and the MIDI devices are opened
  250.      * (calling MidiOut::openDev() ).
  251.      * @see ok() to check if there was any problem
  252.      * @see closeDev()
  253.      * @see initDev()
  254.      */
  255.     void openDev        (void);
  256.  
  257.     /**
  258.      * Closes the devices, and /dev/sequencer.
  259.      *
  260.      * @see openDev()
  261.      */
  262.     void closeDev       (void);
  263.  
  264.     /**
  265.      * Calls MidiOut::initDev() in turn in each of the available devices.
  266.      *
  267.      * @see MidiOut::initDev()
  268.      */
  269.     void initDev        (void);
  270.  
  271.     /**
  272.      * Sends a Note On MIDI event.
  273.      *
  274.      * @param chn the MIDI channel (0 to 15) to play the note on.
  275.      * @param note the key of the note to play (0 to 127).
  276.      * @param vel the velocity of the note (0 to 127).
  277.      *
  278.      * @see noteOff()
  279.      */
  280.     void noteOn         ( uchar chn, uchar note, uchar vel );
  281.  
  282.     /**
  283.      * Sends a Note Off MIDI event. This is equivalent to send a Note On event
  284.      * with a vel value of 0.
  285.      *
  286.      * @param chn the MIDI channel (0 to 15) to play the note on.
  287.      * @param note the key of the note to play (0 to 127).
  288.      * @param vel the velocity of the note (0 to 127).
  289.      *
  290.      * @see noteOn()
  291.      */
  292.     void noteOff        ( uchar chn, uchar note, uchar vel );
  293.  
  294.     /**
  295.      * Sends a Key Pressure (or Aftertouch) MIDI event.
  296.      * This event changes the pressure over a key after this key has been played.
  297.      *
  298.      * @param chn the MIDI channel (0 to 15) where the note is being played.
  299.      * @param note the key of the note (0 to 127).
  300.      * @param vel the new velocity (or pressure) of the note (0 to 127).
  301.      */
  302.     void keyPressure    ( uchar chn, uchar note, uchar vel );
  303.  
  304.     /**
  305.      * Changes the patch (instrument) on a MIDI channel.
  306.      *
  307.      * @see setPatchesToUse()
  308.      *
  309.      * @param chn the MIDI channel (0 to 15) .
  310.      * @param patch the General Midi patch (0 to 127) to use on the channel chn.
  311.      */
  312.     void chnPatchChange ( uchar chn, uchar patch );
  313.  
  314.     /**
  315.      * Changes the Pressure (Aftertouch) on a MIDI channel. Keep in mind that
  316.      * some synthesizers don't like this events, and it's better not to send it.
  317.      *
  318.      * @param chn the MIDI channel (0 to 15) to change.
  319.      * @param vel the velocity (0 to 127) to use on the channel chn.
  320.      */
  321.     void chnPressure    ( uchar chn, uchar vel );
  322.  
  323.     /**
  324.      * Changes the Pitch Bender value on a MIDI channel. This bends the tone of
  325.      * each note played on this channel.
  326.      *
  327.      * @param chn the MIDI channel (0 to 15) to use.
  328.      * @param lsb and @p msb the less significant byte and the most significant
  329.      * byte (0 to 127 each) of the number by which notes will be bend. a 0x4000
  330.      * value means not to bend.
  331.      * @param msb the most significant byte
  332.      */
  333.     void chnPitchBender ( uchar chn, uchar lsb,  uchar msb );
  334.  
  335.     /**
  336.      * Sends a Controller event to a MIDI channel. This can be used for example
  337.      * to change the volume, set a XG patch, etc. Look for any General Midi
  338.      * resource page on the net for more information about the available
  339.      * controller events.
  340.      *
  341.      * For example, to set the tremolo value to a maximum on the MIDI channel
  342.      * number one, you should pass 1 to @p chn, 1 to @p ctl and 127 to @p v.
  343.      *
  344.      * @param chn the MIDI channel (0 to 15) to send the event to.
  345.      * @param ctl the controller (0 to 15) to send.
  346.      * @param v the value (data) of the controller.
  347.      */
  348.     void chnController  ( uchar chn, uchar ctl , uchar v );
  349.  
  350.     /**
  351.      * Sends a SYStem EXclusive message to the default MIDI device (usually,
  352.      * external MIDI synths, as most internal synths do not support sysex
  353.      * messages)
  354.      *
  355.      * @param data the array of bytes that comform the system exclusive message.
  356.      * Without the initial 0xF0 char, and including the final 0xF7 char (end of
  357.      * exclusive message)
  358.      * @param size the size in bytes of the data to send
  359.      *
  360.      * @see setDefaultDevice()
  361.      */
  362.     void sysEx          ( uchar *data,ulong size);
  363.  
  364.     /**
  365.      * Sets the number of milliseconds at which the next event will be sent.
  366.      * This way, you can schedule notes and events to send to the MIDI device.
  367.      * @see tmrStart()
  368.      */
  369.     void wait (double ms);
  370.  
  371.     /**
  372.      * Sets the tempo which will be used to convert between ticks and
  373.      * milliseconds.
  374.      */
  375.      void tmrSetTempo(int v);
  376.  
  377.     /**
  378.      * Starts the timer. You must call tmrStart before using wait()
  379.      */
  380.     void tmrStart(long int tpcn);
  381.  
  382.     /**
  383.      * Stops the timer. This will be called by closeDev() before closing
  384.      * the device
  385.      */
  386.     void tmrStop(void);
  387.  
  388.     /**
  389.      * Continue the stopped timer . It is the same than starting a new timer, but
  390.      * without resetting it.
  391.      */
  392.     void tmrContinue(void);
  393.  
  394.     /**
  395.      * Sends an all notes off event
  396.      */
  397.     void allNotesOff(void);
  398.  
  399.     /**
  400.      * Synchronizes with the MIDI buffer. Midi events are put into a buffer,
  401.      * along with timer delays (see wait() ). sync returns when the buffer
  402.      * is empty.
  403.      *
  404.      * @param f if false, it syncronizes by waiting for the buffer to be sent.
  405.      * If true, it forces the synchronization by clearing the buffer
  406.      * inmediately. The "force" method is, of course, not recommended, except
  407.      * in rare situations.
  408.      */
  409.     void sync(bool f=0);
  410.  
  411.     /**
  412.      * Changes the "master" volume of the played events by altering next volume
  413.      * controller events. The parameter @p i should be in the range of 0
  414.      * (nothing is heard) to 150 (music is played at a 150% of the original
  415.      * volume).
  416.      *
  417.      * Keep in mind that as most MIDI files already play music at near the
  418.      * maximum volume, an @p i value greater than 100 is very probably ignored
  419.      * most of the times.
  420.      */
  421.     void setVolumePercentage(int i);
  422.  
  423.     /**
  424.      * Returns the device to which the MIDI events will be sent.
  425.      * Returns -1 if there's no available device.
  426.      *
  427.      * @see setDefaultDevice()
  428.      */
  429.     int defaultDevice(void);
  430.  
  431.     /**
  432.      * Sets the device to send the MIDI events to.
  433.      *
  434.      * By using midiPorts(), synthDevices(), name() and
  435.      * type(), you should choose which device to use (note that they are
  436.      * numbered with midi ports being first and synth devices next)
  437.      *
  438.      * @see defaultDevice()
  439.      */
  440.     void setDefaultDevice(int i);
  441.  
  442.     /**
  443.      * Loads the patches you're going to use . This has effect only for GUS
  444.      * cards, although, if you use this function when defaultDevice() is
  445.      * not a GUS device, it will be ignored.
  446.      *
  447.      * The parameter is an int [256] array, which contain the following:
  448.      *
  449.      * The first 0..127 integers, are the number of times each General MIDI patch
  450.      * will be used, and -1 when the corresponding patch won't be used.
  451.      *
  452.      * The 128..255 integers are the number of times each drum voice (each note
  453.      * on the drum channel) will be used, and -1 when the corresponding
  454.      * percussion won't be used.
  455.      *
  456.      * This is done this way so that if the user has very little memory on his
  457.      * GUS card, and not all patches will be loaded, they are at least
  458.      * reordered, so that it first loads the one you're going to use most.
  459.      *
  460.      * In case you don't worry about such users, or you don't know "a priori"
  461.      * the number of notes you're going to play, you can just use 1 for each
  462.      * patch you want to load and -1 in the rest.
  463.      *
  464.      * @see GUSOut::setPatchesToUse()
  465.      * @see GUSOut::loadPatch()
  466.      *
  467.      * @return 0 if ok, and -1 if there wasn't enough memory to load the patches
  468.      * in the card's memory.
  469.      */
  470.     int setPatchesToUse(int *patchesused);
  471.  
  472.     /**
  473.      * Returns the filename where the Midi Mapper was loaded from, or "" if no
  474.      * MIDI Mapper is in use.
  475.      *
  476.      * @see setMidiMap()
  477.      */
  478.     const char *midiMapFilename(void);
  479.  
  480.     /**
  481.      * Sets a MidiMapper object to use. This object should already have
  482.      * loaded the configuration. See the description of MidiMapper for
  483.      * more information.
  484.      *
  485.      * @see MidiMapper::MidiMapper()
  486.      * @see midiMapFilename()
  487.      */
  488.     void setMidiMap(MidiMapper *map);
  489.  
  490.     /**
  491.      * Returns the SNDCTL_SEQ_CTRLRATE ioctl value
  492.      */
  493.     int rate(void) { return m_rate; }
  494.  
  495.     /**
  496.      * Returns the number of MIDI ports available on the system. It's common that
  497.      * users have MIDI ports available, but there are no external synthesizers
  498.      * connected to these ports, so sending MIDI events to these ports will not
  499.      * produce any music in this case.
  500.      *
  501.      * @see synthDevices()
  502.      * @see setDefaultDevice()
  503.      */
  504.     int midiPorts(void) { return n_midi; }
  505.  
  506.     /**
  507.      * Returns the number of internal synthesizers available on the system. Some
  508.      * of these devices will need special configuration, for example, to load
  509.      * sound patches.
  510.      *
  511.      * @see midiPorts()
  512.      * @see setDefaultDevice()
  513.      * @see setPatchesToUse()
  514.      */
  515.     int synthDevices(void) { return n_synths; }
  516.  
  517.     /**
  518.      * Returns the name of the @p i-th device . In case the DeviceManager wasn't
  519.      * yet initialized ( see checkInit() ), the return value is NULL, and
  520.      * in case the parameter has a value out of the valid range ( 0 to
  521.      * midiPorts() + synthDevices() ) it returns an empty string.
  522.      */
  523.     const char *name(int i);
  524.  
  525.     /**
  526.      * Returns the type of device the @p i-th device is , in a user-friendly
  527.      * string . For example, "External Midi Port" for midi ports, "FM" for FM
  528.      * synthesizers, "GUS" for Gravis Ultrasound devices, etc.
  529.      */
  530.     const char *type(int i);
  531.  
  532.   private:
  533.     class DeviceManagerPrivate;
  534.     DeviceManagerPrivate *d;
  535. };
  536.  
  537. #endif
  538.