Source Code (Use browser search to find items of interest.)

Class Index

kmid'DeviceManager (./kdemultimedia/kmid/player/deviceman.h:45)

class DeviceManager
{
  protected:

    MidiOut **device; 	// The midi devices objects
    struct midi_info *midiinfo;   // Midi info
    struct synth_info *synthinfo; // Synth info
    int chn2dev[16];    // Stores the device thru which a channel will be sent
    int n_synths;  // Number of synths devices
    int n_midi;  // Number of midi ports
    int n_total; // n_midi+n_synths

#ifndef HANDLETIMEINDEVICES

    int			rate;
    double		convertrate; // A "constant" used to convert from
    // milliseconds to the computer rate

#endif
    int timerstarted; // Newest kernels don't want me to stop a timer that
    		// hasn't been started :-)

    double lastwaittime; // Last time waited for in wait(double)

    MidiMapper *mapper_tmp; // Keeps a pointer to the mapper so that if devices
		// weren't initialized when first called setMidiMap
		// then, when they get initialized, they use the proper mapper

    int initialized;
    int seqfd;       // The real file handler for /dev/sequencer,
		// that is opened and closed.
    int default_dev; // The device to which timer events will be sent

    int _ok;
    void seqbuf_dump (void);
    void seqbuf_clean (void);

  public:
/**
 * Constructor. It just initializes internal variables, before playing any
 * music, you should call @ref #initManager, @ref #setMidiMap (optional), 
 * @ref openDev, @ref initDev, @ref setPatchesToUse (optional, except if
 * you're playing to a GUS device, which must load the patches),
 * @ref tmrStart, and finally, play the music.
 */
    DeviceManager(int def=0);
/**
 * Destructor. It closes the device (calling @ref closeDev) if it wasn't
 * closed before. 
 */
    ~DeviceManager(void);

/**
 * Initializes the MIDI Device Manager object.
 * 
 * The /dev/sequencer file is opened,  available devices are analyzed and
 * *Out objects are created. Then, the /dev/sequencer file is closed.
 *
 * @return 0 if everything was OK, or -1 if there was an error and it couldn't
 * be initialized (for example, because it couldn't open the /dev/sequencer i
 * file)
 */
    int initManager(void); 

/**
 * Checks if the device manager has been initialized (with @initManager),
 * and in case it wasn't, initializes it.
 * 
 * @return 0 if it was (or has just been) correctly initialized, and -1 if there
 * was an error.
 */
    int checkInit(void); 

/**
 * 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.
 *
 * @return the device to which MIDI events goind to channel chn should be sent. 
 */
    MidiOut *chntodev(int chn) { return device[chn2dev[chn]]; };

/**
 * @return 0 if there was a problem and 1 if everything was OK. Note that the
 * return value is changed after you check it, so you can only check it once.
 */
    int ok(void);

// The following funtion are here to emulate a midi, so that the DeviceManager
// sends the events to the appropiate devices.

/**
 * 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 ).
 * @see #ok to check if there was any problem
 * @see #closeDev
 * @see #initDev
 */
    void openDev        (void);

/**
 * Closes the devices, and /dev/sequencer. 
 *
 * @see #openDev
 */
    void closeDev       (void);

/**
 * Calls @ref MidiOut::initDev in turn in each of the available devices.
 *
 * @see MidiOut::initDev
 */
    void initDev        (void);

/**
 * Sends a Note On MIDI event.
 *
 * @param chn the MIDI channel (0 to 15) to play the note on.
 * @param note the key of the note to play (0 to 127).
 * @param vel the velocity of the note (0 to 127).
 *
 * @see #noteOff
 */
    void noteOn         ( uchar chn, uchar note, uchar vel );

/**
 * Sends a Note Off MIDI event. This is equivalent to send a Note On event with a 
 * vel value of 0.
 *
 * @param chn the MIDI channel (0 to 15) to play the note on.
 * @param note the key of the note to play (0 to 127).
 * @param vel the velocity of the note (0 to 127).
 *
 * @see #noteOn
 */
    void noteOff        ( uchar chn, uchar note, uchar vel );

/**
 * Sends a Key Pressure (or Aftertouch) MIDI event.
 * This event changes the pressure over a key after this key has been played.
 *
 * @param chn the MIDI channel (0 to 15) where the note is being played.
 * @param note the key of the note (0 to 127).
 * @param vel the new velocity (or pressure) of the note (0 to 127).
 */
    void keyPressure    ( uchar chn, uchar note, uchar vel );


/**
 * Changes the patch (instrument) on a MIDI channel.  
 * 
 * @see setPatchesToUse
 *
 * @param chn the MIDI channel (0 to 15) .
 * @param patch the General Midi patch (0 to 127) to use on the channel chn.
 */
    void chnPatchChange ( uchar chn, uchar 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. 
 * 
 * @param chn the MIDI channel (0 to 15) to change.
 * @param vel the velocity (0 to 127) to use on the channel chn.
 */
    void chnPressure    ( uchar chn, uchar vel );

/**
 * Changes the Pitch Bender value on a MIDI channel. This bends the tone of
 * each note played on this channel.
 * 
 * @param chn the MIDI channel (0 to 15) to use.
 * @param lsb @param msb the less significant byte and the most significant
 * byte (0 to 127 each) of the number by which notes will be bend. a 0x4000
 * value means not to bend.
 */
    void chnPitchBender ( uchar chn, uchar lsb,  uchar 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 chn, 1 to ctl and 127 to v.
 *
 * @param chn the MIDI channel (0 to 15) to send the event to.
 * @param ctl the controller (0 to 15) to send.
 * @param v the value (data) of the controller.
 */
    void chnController  ( uchar chn, uchar ctl , uchar v );

/**
 * Sends a SYStem EXclusive message to the default MIDI device (usually,
 * external MIDI synths, as most internal synths do not support sysex messages)
 * 
 * @param data the array of bytes that comform the system exclusive message.
 * Without the initial 0xF0 char, and including the final 0xF7 char (end of
 * exclusive message)
 * @param size the size in bytes of the data to send 
 *
 * @see setDefaultDevice
 */
    void sysEx          ( uchar *data,ulong size);

/**
 * Sets the number of MIDI ticks to wait until the next event is sent. This way,
 * you can schedule notes and events to send to the MIDI device.
 */
    void wait (double ticks);

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

/**
 * Starts the timer. You should call tmrStart before using @ref #wait
 */
    void tmrStart(void);

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

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

/**
 * 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.
 * 
 * @param f if false, it syncronizes by waiting for the buffer to be sent.
 * If true, it forces the synchronization by clearing the buffer inmediately.
 * The "force" method is, of course, not recommended, except in rare situations.
 */ 
    void sync(bool f=0);  

/**
 * Changes the "master" volume of the played events by altering next volume
 * controller events. The parameter 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 maximumi
 * volume, an i value greater than 100 is very probably ignored most of the times.
 */
    void setVolumePercentage(int i);

/**
 * Returns the device to which the MIDI events will be sent.
 *
 * @see #setDefaultDevice
 */
    int defaultDevice(void);

/**
 * 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)
 *
 * @see #defaultDevice
 */
    void 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.
 * 
 * @see GUSOut::setPatchesToUse
 * @see GUSOut::loadPatch 
 * 
 * @return 0 if ok, and -1 if there wasn't enough memory to load the patches
 * in the card's memory.
 */
    int setPatchesToUse(int *patchesused);

/**
 * Returns the filename where the Midi Mapper was loaded from, or "" if no
 * MIDI Mapper is in use.
 *
 * @see #setMidiMap
 */
    char *midiMapFilename(void);

/**
 * Sets a @ref MidiMapper object to use. This object should already have
 * loaded the configuration. See the description of @ref MidiMapper for
 * more information.
 *
 * @see MidiMapper::MidiMapper
 * @see #midiMapFilename
 */
    void setMidiMap(MidiMapper *map);

/**
 * 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.
 *
 * @see #synthDevices
 * @see #setDefaultDevice
 */
    int midiPorts(void) {return n_midi;};
/**
 * Returns the number of internal synthesizers available on the system. Some
 * of these devices will need special configuration, for example, to load
 * sound patches.
 *
 * @see #midiPorts
 * @see #setDefaultDevice
 * @see #setPatchesToUse
 */
    int synthDevices(void) {return n_synths;};
/**
 * Returns the name of the 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.
 */

    char *name(int i);
/**
 * Returns the type of device the 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.
 */
    const char *type(int i);

};

kmid'DeviceManager::DeviceManager() (./kdemultimedia/kmid/player/deviceman.cc:67)

DeviceManager::DeviceManager(int def)
{
default_dev=def;
initialized=0;
_ok=1;
device = NULL;
#ifdef HANDLETIMEINDEVICES
rate=100;
convertrate=10;
#endif
mapper_tmp = NULL;
seqfd=-1;
timerstarted=0;
for (int i=0;i<16;i++) chn2dev[i]=default_dev;
}


kmid'DeviceManager::~DeviceManager() (./kdemultimedia/kmid/player/deviceman.cc:83)

DeviceManager::~DeviceManager(void)
{
    closeDev();
    if (device!=NULL)
    {
        for (int i=0;i<n_midi;i++)
            delete device[i];
        delete device;
        device=NULL;
    }
}


kmid'DeviceManager::ok() (./kdemultimedia/kmid/player/deviceman.cc:95)

int DeviceManager::ok(void)
{
    int r=_ok;
    _ok=1;
    return r;
}


kmid'DeviceManager::checkInit() (./kdemultimedia/kmid/player/deviceman.cc:102)

int DeviceManager::checkInit(void)
{
    if (initialized==0) 
    {
        int r=initManager();
	if (default_dev>=n_total) default_dev=0;
        setMidiMap(mapper_tmp);
        DEBUGPRINTF("check : %d\n",r);
        return r;
    }
    return 0;
}

/*
 midiOut *DeviceManager::chntodev(int chn)
 {
 return device[chn2dev[chn]];
 };
 */


kmid'DeviceManager::initManager() (./kdemultimedia/kmid/player/deviceman.cc:122)

int DeviceManager::initManager(void)
{
    seqfd = open("/dev/sequencer", O_WRONLY | O_NONBLOCK, 0);
    if (seqfd==-1)
    {
        printf("ERROR: Couldn't open /dev/sequencer to get some information\n");
        _ok=0;
        return -1;
    };
    n_synths=0;
    n_midi=0;
    ioctl(seqfd,SNDCTL_SEQ_NRSYNTHS,&n_synths);
    ioctl(seqfd,SNDCTL_SEQ_NRMIDIS,&n_midi);
    n_total=n_midi+n_synths;
    if (n_midi==0) 
    {
        printf("ERROR: There's no midi port\n");
/* This could be a problem if the user don't have a synth neither,
but not having any of both things is unusual */
        //    _ok=0;
        //    return 1;
    }
    
    device=new MidiOut*[n_total];
    midiinfo=new midi_info[n_midi];
    synthinfo=new synth_info[n_synths];
    
    int i;
    for (i=0;i<n_midi;i++)
    {
        midiinfo[i].device=i;
        if (ioctl(seqfd,SNDCTL_MIDI_INFO,&midiinfo[i])!=-1)
        {
#ifdef GENERAL_DEBUG_MESSAGES
            printf("----\n");
            printf("Device : %d\n",i);
            printf("Name : %s\n",midiinfo[i].name);
            printf("Device type : %d\n",midiinfo[i].dev_type);
#endif
        }
        device[i]=new MidiOut(i);
    }
    
    for (i=0;i<n_synths;i++)
    {
        synthinfo[i].device=i;
        if (ioctl(seqfd,SNDCTL_SYNTH_INFO,&synthinfo[i])!=-1)
        {
#ifdef GENERAL_DEBUG_MESSAGES  
            printf("----\n");
            printf("Device : %d\n",i);
            printf("Name : %s\n",synthinfo[i].name);
            switch (synthinfo[i].synth_type)
            {
            case (SYNTH_TYPE_FM) : printf("FM\n");break;
            case (SYNTH_TYPE_SAMPLE) : printf("Sample\n");break;
            case (SYNTH_TYPE_MIDI) : printf("Midi\n");break;
            default : printf("default type\n");break;
            };
            switch (synthinfo[i].synth_subtype)
            {
            case (FM_TYPE_ADLIB) : printf("Adlib\n");break;
            case (FM_TYPE_OPL3) : printf("Opl3\n");break;
            case (MIDI_TYPE_MPU401) : printf("Mpu-401\n");break;
            case (SAMPLE_TYPE_GUS) : printf("Gus\n");break;
            default : printf("default subtype\n");break;
            }
#endif
            if (synthinfo[i].synth_type==SYNTH_TYPE_FM) 
                device[i+n_midi]=new FMOut(i,synthinfo[i].nr_voices);
            else if ((synthinfo[i].synth_type==SYNTH_TYPE_SAMPLE)&&
                     (synthinfo[i].synth_subtype==SAMPLE_TYPE_GUS))
                device[i+n_midi]=new GUSOut(i,synthinfo[i].nr_voices);
            else
                device[i+n_midi]=new SynthOut(i);
        }
    }
    
    close(seqfd);
    
    //#ifdef AT_HOME
    //MidiMapper *map=new MidiMapper("/opt/kde/share/apps/kmid/maps/yamaha790.map");
    //device[0]->useMapper(map);
    //#endif
    
    initialized=1;
    
    return 0;
}


kmid'DeviceManager::openDev() (./kdemultimedia/kmid/player/deviceman.cc:212)

void DeviceManager::openDev(void)
{
    if (checkInit()<0) 
    {
        DEBUGPRINTF("DeviceManager::openDev : Not initialized\n");
        _ok = 0;
        return;
    }
    _ok=1;
    seqfd = open("/dev/sequencer", O_WRONLY | O_NONBLOCK, 0);
    if (seqfd==-1)
    {
        printf("Couldn't open\n");
        _ok=0;
        return;
    }
    _seqbufptr = 0;
    ioctl(seqfd,SNDCTL_SEQ_RESET);
    //ioctl(seqfd,SNDCTL_SEQ_PANIC);
    
#ifndef HANDLETIMEINDEVICES
    rate=0;
    int r=ioctl(seqfd,SNDCTL_SEQ_CTRLRATE,&rate);
    if ((r==-1)||(rate<=0)) rate=HZ;
    
    convertrate=1000/rate;
#endif
    
    DEBUGPRINTF("Opening devices : ");
    for (int i=0;i<n_total;i++) 
    {
        device[i]->openDev(seqfd);
        DEBUGPRINTF("%s ",device[i]->deviceName());
    }
    DEBUGPRINTF("\n");
    for (int i=0;i<n_total;i++) if (!device[i]->ok()) _ok=0;
    if (_ok==0)
    {
        for (int i=0;i<n_total;i++) device[i]->closeDev();
        printf("DeviceMan :: ERROR : Closing devices\n");
        return;
    }
    
#ifdef DEVICEMANDEBUG
    printf("Devices opened\n");
    printf("rate: %d\n",rate);
#endif
}


kmid'DeviceManager::closeDev() (./kdemultimedia/kmid/player/deviceman.cc:261)

void DeviceManager::closeDev(void)
{
    if (seqfd==-1) return;
#ifndef HANDLETIMEINDEVICES
    tmrStop();
#endif
/*
DEBUGPRINTF("Closing devices : ");
if (device!=NULL) for (int i=0;i<n_total;i++) 
    {
    device[i]->initDev();
    DEBUGPRINTF("%s ",device[i]->deviceName());
	
//	device[i]->closeDev();
    };
DEBUGPRINTF("\n");
*/
    close(seqfd);
    seqfd=-1;
}


kmid'DeviceManager::initDev() (./kdemultimedia/kmid/player/deviceman.cc:282)

void DeviceManager::initDev(void)
{
    if (device!=NULL) 
    {
        DEBUGPRINTF("Initializing devices :");
        for (int i=0;i<n_total;i++) 
        {
            device[i]->initDev();
            DEBUGPRINTF("%s ",device[i]->deviceName());
        }
        DEBUGPRINTF("\n");
    }
}


kmid'DeviceManager::noteOn() (./kdemultimedia/kmid/player/deviceman.cc:296)

void DeviceManager::noteOn         ( uchar chn, uchar note, uchar vel )
{
    MidiOut *midi=chntodev(chn);
    midi->noteOn(chn,note,vel);
}

kmid'DeviceManager::noteOff() (./kdemultimedia/kmid/player/deviceman.cc:301)

void DeviceManager::noteOff        ( uchar chn, uchar note, uchar vel )
{
    MidiOut *midi=chntodev(chn);
    midi->noteOff(chn,note,vel);
}

kmid'DeviceManager::keyPressure() (./kdemultimedia/kmid/player/deviceman.cc:306)

void DeviceManager::keyPressure    ( uchar chn, uchar note, uchar vel )
{
    MidiOut *midi=chntodev(chn);
    midi->keyPressure(chn,note,vel);
}

kmid'DeviceManager::chnPatchChange() (./kdemultimedia/kmid/player/deviceman.cc:311)

void DeviceManager::chnPatchChange ( uchar chn, uchar patch )
{
    MidiOut *midi=chntodev(chn);
    midi->chnPatchChange(chn,patch);
}

kmid'DeviceManager::chnPressure() (./kdemultimedia/kmid/player/deviceman.cc:316)

void DeviceManager::chnPressure    ( uchar chn, uchar vel )
{
    MidiOut *midi=chntodev(chn);
    midi->chnPressure(chn,vel);
}

kmid'DeviceManager::chnPitchBender() (./kdemultimedia/kmid/player/deviceman.cc:321)

void DeviceManager::chnPitchBender ( uchar chn, uchar lsb,  uchar msb )
{
    MidiOut *midi=chntodev(chn);
    midi->chnPitchBender(chn,lsb,msb);
}

kmid'DeviceManager::chnController() (./kdemultimedia/kmid/player/deviceman.cc:326)

void DeviceManager::chnController  ( uchar chn, uchar ctl , uchar v )
{
    MidiOut *midi=chntodev(chn);
    midi->chnController(chn,ctl,v);
}

kmid'DeviceManager::sysEx() (./kdemultimedia/kmid/player/deviceman.cc:331)

void DeviceManager::sysEx          ( uchar *data,ulong size)
{
    for (int i=0;i<n_midi;i++)
        device[i]->sysex(data,size);
}


kmid'DeviceManager::wait() (./kdemultimedia/kmid/player/deviceman.cc:337)

void DeviceManager::wait (double ticks)
{
    unsigned long int t=(unsigned long int)(ticks/convertrate);
    if (lastwaittime==t) return;
    lastwaittime=t;
#ifdef HANDLETIMEINDEVICES
    device[default_dev]->wait(ticks);
#else
    //printf("%ld\n",t);
    SEQ_WAIT_TIME(t);
    SEQ_DUMPBUF();
#endif
}


kmid'DeviceManager::tmrSetTempo() (./kdemultimedia/kmid/player/deviceman.cc:351)

void DeviceManager::tmrSetTempo(int v)
{
    //device[default_dev]->tmrSetTempo(v);
    SEQ_SET_TEMPO(v);
    SEQ_DUMPBUF();
}


kmid'DeviceManager::tmrStart() (./kdemultimedia/kmid/player/deviceman.cc:358)

void DeviceManager::tmrStart(void)
{
#ifdef HANDLETIMEINDEVICES
    device[default_dev]->tmrStart();
#else
#ifdef CONTROLTIMER
    if (!timerstarted)
    {
        SEQ_START_TIMER();
        SEQ_DUMPBUF();
        timerstarted=1;
    }
    lastwaittime=0;
#else
    SEQ_START_TIMER();
    SEQ_DUMPBUF();
#endif
#endif
}


kmid'DeviceManager::tmrStop() (./kdemultimedia/kmid/player/deviceman.cc:378)

void DeviceManager::tmrStop(void)
{
#ifdef HANDLETIMEINDEVICES
    device[default_dev]->tmrStop();
#else
#ifdef CONTROLTIMER
    if (timerstarted)
    {
        SEQ_STOP_TIMER();
        SEQ_DUMPBUF();
        timerstarted=0;
    }
#else
    SEQ_STOP_TIMER();
    SEQ_DUMPBUF();
#endif
#endif
}


kmid'DeviceManager::tmrContinue() (./kdemultimedia/kmid/player/deviceman.cc:397)

void DeviceManager::tmrContinue(void)
{
#ifdef HANDLETIMEINDEVICES
    device[default_dev]->tmrContinue();
#else
#ifdef CONTROLTIMER
    if (timerstarted)
    {
        SEQ_CONTINUE_TIMER();
        SEQ_DUMPBUF();
    }
#else
    SEQ_CONTINUE_TIMER();
    SEQ_DUMPBUF();
#endif
#endif
}


kmid'DeviceManager::sync() (./kdemultimedia/kmid/player/deviceman.cc:415)

void DeviceManager::sync(bool f)
{
#ifdef HANDLETIMEINDEVICES
    device[default_dev]->sync(i);
#else
#ifdef DEVICEMANDEBUG
    printf("Sync %d\n",i);
#endif
    if (f) 
    {    
        seqbuf_clean();
        /* If you have any problem, try removing the next 2 lines, 
         I though they would be useful here but the may have side effects */
        ioctl(seqfd,SNDCTL_SEQ_RESET);
        ioctl(seqfd,SNDCTL_SEQ_PANIC);
    }
    else
    {
    seqbuf_dump();
    ioctl(seqfd, SNDCTL_SEQ_SYNC);
    };
#endif
}


kmid'DeviceManager::seqbuf_dump() (./kdemultimedia/kmid/player/deviceman.cc:439)

void DeviceManager::seqbuf_dump (void)
{
    if (_seqbufptr)
    {
        int r=0;
        unsigned char *sb=_seqbuf;
        int w=_seqbufptr;
        r=write (seqfd, _seqbuf, _seqbufptr);
#ifdef DEVICEMANDEBUG
        printf("%d == %d\n",r,w);
        printf("%d\n",(errno==EAGAIN)? 1 : 0);
#endif
        while (((r == -1)&&(errno==EAGAIN))||(r != w))
        {
            if ((r==-1)&&(errno==EAGAIN))
            {
                usleep(1);
            }
            else if ((r>0)&&(r!=w))
            {
                w-=r;
                sb+=r;
            }
            r=write (seqfd, sb, w);
#ifdef DEVICEMANDEBUG
            printf("%d == %d\n",r,w);
            printf("%d\n",(errno==EAGAIN)? 1 : 0);
#endif
        }
    }
    /*
     *   if (_seqbufptr)
     *       if (write (seqfd, _seqbuf, _seqbufptr) == -1)
     *       {
     *           printf("Error writing to /dev/sequencer in deviceManager::seqbuf_dump\n");
     *           perror ("write /dev/sequencer in seqbuf_dump\n");
     *           exit (-1);
     *       }
     */
    _seqbufptr = 0;
}


kmid'DeviceManager::seqbuf_clean() (./kdemultimedia/kmid/player/deviceman.cc:481)

void DeviceManager::seqbuf_clean(void)
{
    _seqbufptr=0;
}



kmid'DeviceManager::name() (./kdemultimedia/kmid/player/deviceman.cc:487)

char *DeviceManager::name(int i)
{
    if (checkInit()<0) {_ok = 0; return NULL;}
    
    if (i<n_midi) return midiinfo[i].name; 
    if (i<n_midi+n_synths) return synthinfo[i-n_midi].name;
    return (char *)"";
}


kmid'DeviceManager::type() (./kdemultimedia/kmid/player/deviceman.cc:496)

const char *DeviceManager::type(int i)
{
    if (checkInit()<0) {_ok = 0; return NULL;}
    
    if (i<n_midi) 
    {
        return "External Midi Port"; 
    }
    if (i<n_midi+n_synths) 
    {
        switch (synthinfo[i-n_midi].synth_subtype)
        {
        case (FM_TYPE_ADLIB) : return "Adlib";break;
        case (FM_TYPE_OPL3) : return "FM";break;
        case (MIDI_TYPE_MPU401) : return "MPU 401";break;
        case (SAMPLE_TYPE_GUS) : return "GUS";break;
        }
        return "";
    }
    return "";
}


kmid'DeviceManager::defaultDevice() (./kdemultimedia/kmid/player/deviceman.cc:518)

int DeviceManager::defaultDevice(void)
{
    return default_dev;
}


kmid'DeviceManager::setDefaultDevice() (./kdemultimedia/kmid/player/deviceman.cc:523)

void DeviceManager::setDefaultDevice(int i)
{
    if (i>=n_total) return; 
    default_dev=i;
    for (int i=0;i<16;i++) chn2dev[i]=default_dev;
}


kmid'DeviceManager::midiMapFilename() (./kdemultimedia/kmid/player/deviceman.cc:530)

char *DeviceManager::midiMapFilename(void)
{
    if (device==NULL) return (char *)"";
    return (device[default_dev]!=NULL) ? 
        device[default_dev]->midiMapFilename() : (char *)"";
}


kmid'DeviceManager::setMidiMap() (./kdemultimedia/kmid/player/deviceman.cc:537)

void DeviceManager::setMidiMap(MidiMapper *map)
{
    if (map==NULL) return;
    mapper_tmp=map;
    if (default_dev>=n_total) {default_dev=0;return;};
    if ((device==NULL)||(device[default_dev]==NULL)) 
		return;
    device[default_dev]->setMidiMapper(map);
}


kmid'DeviceManager::setPatchesToUse() (./kdemultimedia/kmid/player/deviceman.cc:547)

int DeviceManager::setPatchesToUse(int *patchesused)
{
    if (checkInit()<0) return -1;
    
    if ((device[defaultDevice()]->deviceType())==KMID_GUS)
    {
        GUSOut *gus=(GUSOut *)device[defaultDevice()];
        gus->setPatchesToUse(patchesused);
    }
    return 0;
}


kmid'DeviceManager::setVolumePercentage() (./kdemultimedia/kmid/player/deviceman.cc:559)

void DeviceManager::setVolumePercentage(int v)
{
    if (device!=NULL)
    {
        for (int i=0;i<n_total;i++)
        {
            device[i]->setVolumePercentage(v);
        }
    }
}