/***************************************************************************
                            DeviceManager.h -  description
                             -------------------
    begin                : Fri Mar  8 13:55:08 2002
    copyright            : (C) 2000-2002 Lost Highway Ltd. All rights reserved.
    email                : Lost_Highway@tipitina.demon.co.uk
    generated by         : duke@tipitina on Fri Mar  8 13:55:08 2002, using kalyptus 0.9.
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                       *
 *                                                                         *
 ***************************************************************************/

#ifndef DEVICEMANAGER_H
#define DEVICEMANAGER_H

#include <Foundation/NSObject.h>
#include <Foundation/NSString.h>
#include <qtobjc/QtSupport.h>

/**

 MIDI Device Manager class . This class is the one you should use to
 send MIDI events to any device, as it creates and manages the *Out classes.

 This class is usually used by creating a DeviceManager object, then call
 @ref  #--openDev and @ref  #--initDev . Then, use @ref  #--numberOfMidiPorts,
 @ref  #--numberOfSynthDevices, @ref  #--name and @ref  #--type to choose which
 device to play MIDI events to and then use @ref -defaultDevice to set the
 MIDI device to play.

 @author Antonio Larrosa Jimenez <larrosa@kde.org>
 
 @version 0.9.5 17/01/2000

 @short Manages all MIDI devices and redirects MIDI events to each one as
 configured.

*/
@class MidiMapper; 
@class MidiOut; 

@interface  DeviceManager : NSObject <QtSupport>
{
@private
	void * _qt;
	BOOL  _allocatedInObjcWorld;
}

/** 
 Constructor. It just initializes internal variables, before playing any
 music, you should call @ref  #--initManager, @ref  #--setMidiMap
 (optional), @ref  #--openDev, @ref  #--initDev, @ref  #--setPatchesToUse
 (not required, unless you're playing to a GUS device, which must load
 the patches), @ref  #--tmrStart, and finally, play the music.
     
*/
- initWithInt: (int)def;
- init;

/** 
 Destructor. It closes the device (calling @ref  #--closeDev ) if it wasn't
 closed before.
     
*/
- (void) dealloc;

/** 
 Initializes the MIDI Device Manager object.

 The /dev/sequencer and/or /dev/snd/seq files are opened, available
 devices are analyzed and *Out objects are created. Then, the
 device files are closed.

*/
- (int) initManager;

/** 
 Checks if the device manager has been initialized (with @initManager),
 and in case it wasn't, initializes it.

*/
- (int) checkInit;

/** 
 Obsolete. Please use @ref  #--deviceForChannel instead.

     
*/
- (MidiOut*) chntodev: (int)chn;

/** 
 It's possible to send different MIDI channels to different MIDI devices,
 so that you can for example send channel 1 to an external synthesizer,
 channel 2 to a FM device and channel 10 to an AWE synth.

*/
- (MidiOut*) deviceForChannel: (int)chn;

/** 
 Returns the device number associated with a given channel.
     
*/
- (int) deviceNumberForChannel: (int)chn;

/** 
 Sets the device number associated with a given channel.
     
*/
- setDeviceNumberForChannel: (int)chn dev: (int)dev;

/** 

*/
- (int) ok;

/** 
 Returns true if it's running ALSA and false if OSS is being run
     
*/
- (int) usingAlsa;

/** 
 Open the devices. It first initializes the manager it that wasn't done
 yet (you should do it yourself, to be able to choose the MIDI output
 device, as it will be set to an external synth by default, if available).

 Then /dev/sequencer is opened and the MIDI devices are opened
 (calling @ref -[MidiOut openDev] ).

*/
- openDev;

/** 
 Closes the devices, and /dev/sequencer.

*/
- closeDev;

/** 
 Calls @ref -[MidiOut initDev] in turn in each of the available devices.

*/
- initDev;

/** 
 Sends a Note On MIDI event.

*/
- noteOn: (unsigned char)chn note: (unsigned char)note vel: (unsigned char)vel;

/** 
 Sends a Note Off MIDI event. This is equivalent to send a Note On event
 with a vel value of 0.

*/
- noteOff: (unsigned char)chn note: (unsigned char)note vel: (unsigned char)vel;

/** 
 Sends a Key Pressure (or Aftertouch) MIDI event.
 This event changes the pressure over a key after this key has been played.

*/
- keyPressure: (unsigned char)chn note: (unsigned char)note vel: (unsigned char)vel;

/** 
 Changes the patch (instrument) on a MIDI channel.

*/
- chnPatchChange: (unsigned char)chn patch: (unsigned char)patch;

/** 
 Changes the Pressure (Aftertouch) on a MIDI channel. Keep in mind that
 some synthesizers don't like this events, and it's better not to send it.

*/
- chnPressure: (unsigned char)chn vel: (unsigned char)vel;

/** 
 Changes the Pitch Bender value on a MIDI channel. This bends the tone of
 each note played on this channel.

*/
- chnPitchBender: (unsigned char)chn lsb: (unsigned char)lsb msb: (unsigned char)msb;

/** 
 Sends a Controller event to a MIDI channel. This can be used for example
 to change the volume, set a XG patch, etc. Look for any General Midi
 resource page on the net for more information about the available
 controller events.

 For example, to set the tremolo value to a maximum on the MIDI channel
 number one, you should pass 1 to @p chn, 1 to @p ctl and 127 to @p v.

*/
- chnController: (unsigned char)chn ctl: (unsigned char)ctl v: (unsigned char)v;

/** 
 Sends a SYStem EXclusive message to the default MIDI device (usually,
 external MIDI synths, as most internal synths do not support sysex
 messages)

*/
- sysEx: (unsigned char*)data size: (unsigned long)size;

/** 
 Sets the number of milliseconds at which the next event will be sent.
 This way, you can schedule notes and events to send to the MIDI device.

*/
- wait: (double)ms;

/** 
 Sets the tempo which will be used to convert between ticks and
 milliseconds.
     
*/
- tmrSetTempo: (int)v;

/** 
 Starts the timer. You must call tmrStart before using @ref  #--wait
     
*/
- tmrStart: (long)tpcn;

/** 
 Stops the timer. This will be called by @ref  #--closeDev before closing
 the device
     
*/
- tmrStop;

/** 
 Continue the stopped timer . It is the same than starting a new timer, but
 without resetting it.
     
*/
- tmrContinue;

/** 
 Sends an all notes off event
     
*/
- allNotesOff;

/** 
 Synchronizes with the MIDI buffer. Midi events are put into a buffer,
 along with timer delays (see @ref  #--wait ). sync returns when the buffer
 is empty.

*/
- sync: (BOOL)f;
- sync;

/** 
 Changes the "master" volume of the played events by altering next volume
 controller events. The parameter @p i should be in the range of 0
 (nothing is heard) to 150 (music is played at a 150% of the original
 volume).

 Keep in mind that as most MIDI files already play music at near the
 maximum volume, an @p i value greater than 100 is very probably ignored
 most of the times.
     
*/
- setVolumePercentage: (int)i;

/** 
 Returns the device to which the MIDI events will be sent.
 Returns -1 if there's no available device.

*/
- (int) defaultDevice;

/** 
 Sets the device to send the MIDI events to.

 By using @ref  #--midiPorts, @ref  #--synthDevices, @ref  #--name and
 @ref  #--type, you should choose which device to use (note that they are
 numbered with midi ports being first and synth devices next)

*/
- setDefaultDevice: (int)i;

/** 
 Loads the patches you're going to use . This has effect only for GUS
 cards, although, if you use this function when @ref -defaultDevice is
 not a GUS device, it will be ignored.

 The parameter is an int [256] array, which contain the following:

 The first 0..127 integers, are the number of times each General MIDI patch
 will be used, and -1 when the corresponding patch won't be used.

 The 128..255 integers are the number of times each drum voice (each note
 on the drum channel) will be used, and -1 when the corresponding
 percussion won't be used.

 This is done this way so that if the user has very little memory on his
 GUS card, and not all patches will be loaded, they are at least
 reordered, so that it first loads the one you're going to use most.

 In case you don't worry about such users, or you don't know "a priori"
 the number of notes you're going to play, you can just use 1 for each
 patch you want to load and -1 in the rest.

*/
- (int) setPatchesToUse: (int*)patchesused;

/** 
 Returns the filename where the Midi Mapper was loaded from, or "" if no
 MIDI Mapper is in use.

*/
- (NSString *) midiMapFilename;

/** 
 Sets a @ref MidiMapper object to use. This object should already have
 loaded the configuration. See the description of @ref MidiMapper for
 more information.

*/
- setMidiMap: (MidiMapper*)map;

/** 
 Returns the SNDCTL_SEQ_CTRLRATE ioctl value
     
*/
- (int) rate;

/** 
 Returns the number of MIDI ports available on the system. It's common that
 users have MIDI ports available, but there are no external synthesizers
 connected to these ports, so sending MIDI events to these ports will not
 produce any music in this case.

*/
- (int) midiPorts;

/** 
 Returns the number of internal synthesizers available on the system. Some
 of these devices will need special configuration, for example, to load
 sound patches.

*/
- (int) synthDevices;

/** 
 Returns the name of the @p i-th device . In case the DeviceManager wasn't
 yet initialized ( see @ref  #--checkInit ), the return value is NULL, and
 in case the parameter has a value out of the valid range ( 0 to
 @ref -midiPorts + @ref -synthDevices ) it returns an empty string.
     
*/
- (NSString *) name: (int)i;

/** 
 Returns the type of device the @p i-th device is , in a user-friendly
 string . For example, "External Midi Port" for midi ports, "FM" for FM
 synthesizers, "GUS" for Gravis Ultrasound devices, etc.
     
*/
- (NSString *) type: (int)i;

/** 

     
*/
- seqbuf_dump;

/** 

     
*/
- seqbuf_clean;

/** 

     
*/
- checkAlsa;
@end

#endif
