summaryrefslogtreecommitdiffstats
path: root/libtdemid/deviceman.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtdemid/deviceman.cc')
-rw-r--r--libtdemid/deviceman.cc830
1 files changed, 830 insertions, 0 deletions
diff --git a/libtdemid/deviceman.cc b/libtdemid/deviceman.cc
new file mode 100644
index 000000000..c7649f5a5
--- /dev/null
+++ b/libtdemid/deviceman.cc
@@ -0,0 +1,830 @@
+/**************************************************************************
+
+ deviceman.cc - The device manager, that hides the use of midiOut
+ 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.
+
+ $Id$
+
+ Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>
+
+***************************************************************************/
+#include "deviceman.h"
+#include "midiout.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include "sndcard.h"
+#include "synthout.h"
+#include "fmout.h"
+#include "gusout.h"
+#include "alsaout.h"
+#include "midimapper.h"
+#include "midispec.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_ALSA_ASOUNDLIB_H
+# define HAVE_ALSA_SUPPORT
+# include <alsa/asoundlib.h>
+#elif defined(HAVE_SYS_ASOUNDLIB_H)
+# define HAVE_ALSA_SUPPORT
+# include <sys/asoundlib.h>
+#else
+#ifdef HAVE_LIBASOUND2
+# define HAVE_ALSA_SUPPORT
+# include <sound/asound.h>
+# include <sound/asequencer.h>
+#elif defined(HAVE_LIBASOUND)
+# define HAVE_ALSA_SUPPORT
+# include <linux/asequencer.h>
+#endif
+#endif
+
+#if 1
+#include <kinstance.h>
+#include <kglobal.h>
+#include <kconfig.h>
+#endif
+
+//#define DEVICEMANDEBUG
+//#define GENERAL_DEBUG_MESSAGES
+
+SEQ_DEFINEBUF (4096);
+
+#define CONTROLTIMER
+
+#ifdef GENERAL_DEBUG_MESSAGES
+void DEBUGPRINTF(const char *format)
+{
+ printf(format);
+}
+
+void DEBUGPRINTF(const char *format,int i)
+{
+ printf(format,i);
+}
+
+void DEBUGPRINTF(const char *format,const char *s)
+{
+ printf(format,s);
+}
+
+#else
+
+void DEBUGPRINTF(const char *) { }
+void DEBUGPRINTF(const char *,int ) { }
+void DEBUGPRINTF(const char *,const char * ) { }
+
+#endif
+
+
+DeviceManager::DeviceManager(int def)
+{
+#if 1
+ if (def==-1)
+ {
+ TDEInstance *tmp_instance=0L;
+ if (!TDEGlobal::_instance) tmp_instance=new TDEInstance("nonKDEapp");
+ TDEConfig *config = new TDEConfig("kcmmidirc", true);
+
+ config->setGroup("Configuration");
+ default_dev=config->readNumEntry("midiDevice",0);
+ if ( default_dev < 0 )
+ default_dev=0;
+ TQString mapurl(config->readPathEntry("mapFilename"));
+ if ((config->readBoolEntry("useMidiMapper", false))&&(!mapurl.isEmpty()))
+ {
+ mapper_tmp = new MidiMapper( mapurl.mid(mapurl.find(":")+1 ).local8Bit() );
+ }
+ else
+ mapper_tmp = 0L;
+
+ delete config;
+ delete tmp_instance;
+ }
+ else
+#endif
+ {
+ default_dev = def;
+ mapper_tmp = 0L;
+ }
+
+ initialized=0;
+ _ok=1;
+ alsa=false;
+ device = 0L;
+ m_rate=0;
+ convertrate=10;
+ seqfd=-1;
+ timerstarted=0;
+ n_midi=0;
+ n_synths=0;
+ n_total=0;
+ midiinfo=0L;
+ synthinfo=0L;
+ for (int i=0;i<16;i++) chn2dev[i]=default_dev;
+}
+
+DeviceManager::~DeviceManager(void)
+{
+ closeDev();
+ if (device)
+ {
+ for (int i=0;i<n_total;i++)
+ delete device[i];
+ delete[] device;
+ device=0L;
+ }
+#ifdef HAVE_OSS_SUPPORT
+ delete[] midiinfo;
+ delete[] synthinfo;
+#endif
+}
+
+int DeviceManager::ok(void)
+{
+ int r=_ok;
+ _ok=1;
+ return r;
+}
+
+int DeviceManager::checkInit(void)
+{
+ if (initialized==0)
+ {
+ int r=initManager();
+ if (default_dev>=n_total) default_dev=0;
+ DEBUGPRINTF("check : %d\n",r);
+ return r;
+ }
+ return 0;
+}
+
+void DeviceManager::checkAlsa(void)
+{
+#ifdef HAVE_SYS_STAT_H
+ struct stat buf;
+ stat("/proc/asound", &buf);
+ if ((stat("/proc/asound", &buf) == 0 ) && (S_ISDIR(buf.st_mode)))
+ alsa=true;
+ else
+ alsa=false;
+#else
+#warning "ALSA won't be found at runtime"
+ alsa=false;
+#endif
+}
+
+int DeviceManager::initManager(void)
+{
+ checkAlsa();
+
+ if (!alsa) // We are using OSS
+ {
+#ifdef HAVE_OSS_SUPPORT
+ n_synths=0;
+ n_midi=0;
+ n_total=0;
+
+ seqfd = open("/dev/sequencer", O_WRONLY | O_NONBLOCK, 0);
+ if (seqfd==-1)
+ {
+ fprintf(stderr,"ERROR: Couldn't open /dev/sequencer to get some information\n");
+ _ok=0;
+ return -1;
+ }
+ ioctl(seqfd,SNDCTL_SEQ_NRSYNTHS,&n_synths);
+ ioctl(seqfd,SNDCTL_SEQ_NRMIDIS,&n_midi);
+ n_total=n_midi+n_synths;
+
+
+ if (n_midi==0)
+ {
+ fprintf(stderr,"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);
+#else // There's no OSS support and ALSA wasn't detected
+ // It must be one of those systems coolo is using :-)
+
+ n_synths=0;
+ n_midi=0;
+ n_total=0;
+ device=0L;
+ midiinfo=0L;
+ synthinfo=0L;
+
+#endif
+
+ }
+ else
+ { // We are using ALSA
+
+#ifdef HAVE_ALSA_SUPPORT
+ int client, port;
+#ifdef HAVE_LIBASOUND2
+ snd_seq_t *handle=0;
+ snd_seq_client_info_t *clienti;
+ snd_seq_client_info_malloc(&clienti);
+ snd_seq_port_info_t *porti;
+ snd_seq_port_info_malloc(&porti);
+
+ snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0);
+ if (!handle) { printf("handle==0\n"); return -1; };
+ snd_seq_system_info_t *info;
+ snd_seq_system_info_malloc(&info);
+ if (!info) { printf("info==0\n"); return -1; };
+ snd_seq_system_info(handle, info);
+
+ n_total=0;
+ n_midi=0;
+ n_synths=0;
+
+ device=new MidiOut*[snd_seq_system_info_get_clients(info)*snd_seq_system_info_get_ports(info)];
+ unsigned int k=SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_WRITE ;
+ for (client=0 ; client<snd_seq_system_info_get_clients(info) ; client++)
+ {
+ snd_seq_get_any_client_info(handle, client, clienti);
+ for (port=0 ; port<snd_seq_client_info_get_num_ports(clienti) ; port++)
+ {
+ snd_seq_get_any_port_info(handle, client, port, porti);
+ if (( snd_seq_port_info_get_capability(porti) & k ) == k)
+ {
+ device[n_midi]=new AlsaOut(n_midi,client, port, snd_seq_client_info_get_name(clienti), snd_seq_port_info_get_name(porti));
+ n_midi++;
+ };
+ }
+ }
+ snd_seq_client_info_free(clienti);
+ snd_seq_port_info_free(porti);
+ snd_seq_system_info_free(info);
+#else
+ snd_seq_t *handle=0;
+ snd_seq_client_info_t clienti;
+ snd_seq_port_info_t porti;
+
+ snd_seq_open(&handle, SND_SEQ_OPEN);
+ if (!handle) { printf("handle(2)==0\n"); return -1; };
+
+ snd_seq_system_info_t info;
+ info.clients=info.ports=0;
+ snd_seq_system_info(handle, &info);
+
+ n_total=0;
+ n_midi=0;
+ n_synths=0;
+
+ device=new MidiOut*[info.clients*info.ports];
+ unsigned int k=SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_WRITE ;
+ for (client=0 ; client<info.clients ; client++)
+ {
+ snd_seq_get_any_client_info(handle, client, &clienti);
+ for (port=0 ; port<clienti.num_ports ; port++)
+ {
+ snd_seq_get_any_port_info(handle, client, port, &porti);
+ if (( porti.capability & k ) == k)
+ {
+ device[n_midi]=new AlsaOut(n_midi,client, port, clienti.name, porti.name);
+ n_midi++;
+ };
+ }
+ }
+#endif
+ n_total=n_midi;
+
+ snd_seq_close(handle);
+#else
+
+ // Note: Please don't add i18n for the text below, thanks :)
+
+ fprintf(stderr,"Sorry, this KMid version was compiled without \n");
+ fprintf(stderr,"ALSA support but you're using ALSA . \n");
+ fprintf(stderr,"Please compile KMid for yourself or tell the people\n");
+ fprintf(stderr,"at your Linux distribution to compile it themselves\n");
+#endif
+ }
+
+ if (mapper_tmp!=0L) setMidiMap(mapper_tmp);
+
+ initialized=1;
+
+ return 0;
+}
+
+void DeviceManager::openDev(void)
+{
+ if (checkInit()<0)
+ {
+ DEBUGPRINTF("DeviceManager::openDev : Not initialized\n");
+ _ok = 0;
+ return;
+ }
+ _ok=1;
+
+ if (!alsa)
+ {
+#ifdef HAVE_OSS_SUPPORT
+ seqfd = open("/dev/sequencer", O_WRONLY | O_NONBLOCK, 0);
+ if (seqfd==-1)
+ {
+ fprintf(stderr,"Couldn't open the MIDI sequencer device (/dev/sequencer)\n");
+ _ok=0;
+ return;
+ }
+ _seqbufptr = 0;
+ ioctl(seqfd,SNDCTL_SEQ_RESET);
+ //ioctl(seqfd,SNDCTL_SEQ_PANIC);
+ m_rate=0;
+ int r=ioctl(seqfd,SNDCTL_SEQ_CTRLRATE,&m_rate);
+ if ((r==-1)||(m_rate<=0)) m_rate=HZ;
+
+ convertrate=1000/m_rate;
+
+#endif
+ }
+ else seqfd=0L; // ALSA
+
+// 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();
+// DEBUGPRINTF("DeviceMan :: ERROR : Closing devices\n");
+ return;
+ }
+
+// DEBUGPRINTF("Devices opened\n");
+}
+
+void DeviceManager::closeDev(void)
+{
+ if (alsa)
+ {
+ if (device)
+ for (int i=0;i<n_total;i++)
+ if (device[i]) device[i]->closeDev();
+
+ return;
+ }
+
+#ifdef HAVE_OSS_SUPPORT
+ if (seqfd==-1) return;
+ tmrStop();
+ if (device)
+ for (int i=0;i<n_total;i++)
+ if (device[i]) device[i]->closeDev();
+ /*
+ 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;
+#endif
+}
+
+void DeviceManager::initDev(void)
+{
+ if (device!=0L)
+ {
+// DEBUGPRINTF("Initializing devices :");
+ for (int i=0;i<n_total;i++)
+ {
+ device[i]->initDev();
+ DEBUGPRINTF("%s ",device[i]->deviceName());
+ }
+ DEBUGPRINTF("\n");
+ }
+}
+
+void DeviceManager::noteOn ( uchar chn, uchar note, uchar vel )
+{
+ MidiOut *midi=chntodev(chn);
+ if (midi) midi->noteOn(chn,note,vel);
+}
+void DeviceManager::noteOff ( uchar chn, uchar note, uchar vel )
+{
+ MidiOut *midi=chntodev(chn);
+ if (midi) midi->noteOff(chn,note,vel);
+}
+void DeviceManager::keyPressure ( uchar chn, uchar note, uchar vel )
+{
+ MidiOut *midi=chntodev(chn);
+ if (midi) midi->keyPressure(chn,note,vel);
+}
+void DeviceManager::chnPatchChange ( uchar chn, uchar patch )
+{
+ MidiOut *midi=chntodev(chn);
+ if (midi) midi->chnPatchChange(chn,patch);
+}
+void DeviceManager::chnPressure ( uchar chn, uchar vel )
+{
+ MidiOut *midi=chntodev(chn);
+ if (midi) midi->chnPressure(chn,vel);
+}
+void DeviceManager::chnPitchBender ( uchar chn, uchar lsb, uchar msb )
+{
+ MidiOut *midi=chntodev(chn);
+ if (midi) midi->chnPitchBender(chn,lsb,msb);
+}
+void DeviceManager::chnController ( uchar chn, uchar ctl , uchar v )
+{
+ MidiOut *midi=chntodev(chn);
+ if (midi) midi->chnController(chn,ctl,v);
+}
+void DeviceManager::sysEx ( uchar *data,ulong size)
+{
+ for (int i=0;i<n_midi;i++)
+ device[i]->sysex(data,size);
+}
+
+void DeviceManager::wait (double ticks)
+{
+#ifdef HAVE_ALSA_SUPPORT
+ if (alsa) { ((AlsaOut *)device[default_dev])->wait(ticks); return; };
+#endif
+
+#ifdef HAVE_OSS_SUPPORT
+ unsigned long int t=(unsigned long int)(ticks/convertrate);
+ if (lastwaittime==t) return;
+ lastwaittime=t;
+ SEQ_WAIT_TIME(t);
+ SEQ_DUMPBUF();
+#endif
+}
+
+//void DeviceManager::tmrSetTempo(int v)
+void DeviceManager::tmrSetTempo(int v)
+{
+#ifdef HAVE_ALSA_SUPPORT
+ if (alsa) { ((AlsaOut *)device[default_dev])->tmrSetTempo(v); return; }
+#endif
+
+#ifdef HAVE_OSS_SUPPORT
+ SEQ_SET_TEMPO(v);
+ SEQ_DUMPBUF();
+#endif
+}
+
+void DeviceManager::tmrStart(long int
+#ifdef HAVE_ALSA_SUPPORT
+tpcn /*name the argument only if it is used*/
+#endif
+)
+{
+#ifdef HAVE_ALSA_SUPPORT
+ if (alsa) { ((AlsaOut *)device[default_dev])->tmrStart(tpcn); return; }
+#endif
+
+#ifdef HAVE_OSS_SUPPORT
+#ifdef CONTROLTIMER
+ if (!timerstarted)
+ {
+ SEQ_START_TIMER();
+ SEQ_DUMPBUF();
+ timerstarted=1;
+ }
+ lastwaittime=0;
+#else
+ SEQ_START_TIMER();
+ SEQ_DUMPBUF();
+#endif
+#endif
+}
+
+void DeviceManager::tmrStop(void)
+{
+#ifdef HAVE_ALSA_SUPPORT
+ if (alsa) { ((AlsaOut *)device[default_dev])->tmrStop(); return; }
+#endif
+
+#ifdef HAVE_OSS_SUPPORT
+#ifdef CONTROLTIMER
+ if (timerstarted)
+ {
+ SEQ_STOP_TIMER();
+ SEQ_DUMPBUF();
+ timerstarted=0;
+ }
+#else
+ SEQ_STOP_TIMER();
+ SEQ_DUMPBUF();
+#endif
+#endif
+}
+
+void DeviceManager::tmrContinue(void)
+{
+#ifdef HAVE_ALSA_SUPPORT
+ if (alsa) { ((AlsaOut *)device[default_dev])->tmrContinue(); return; }
+#endif
+
+#ifdef HAVE_OSS_SUPPORT
+#ifdef CONTROLTIMER
+ if (timerstarted)
+ {
+ SEQ_CONTINUE_TIMER();
+ SEQ_DUMPBUF();
+ }
+#else
+ SEQ_CONTINUE_TIMER();
+ SEQ_DUMPBUF();
+#endif
+#endif
+}
+
+void DeviceManager::sync(bool f)
+{
+#ifdef HAVE_ALSA_SUPPORT
+ if (alsa) { ((AlsaOut *)device[default_dev])->sync(f); return ; };
+#endif
+
+#ifdef HAVE_OSS_SUPPORT
+#ifdef DEVICEMANDEBUG
+ printf("Sync %d\n",f);
+#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
+}
+
+void DeviceManager::seqbuf_dump (void)
+{
+ if (!alsa)
+ {
+#ifdef HAVE_OSS_SUPPORT
+ 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;
+#endif
+ }
+}
+
+void DeviceManager::seqbuf_clean(void)
+{
+#ifdef HAVE_ALSA_SUPPORT
+ if (alsa)
+ ((AlsaOut *)device[default_dev])->seqbuf_clean();
+ else
+#endif
+#ifdef HAVE_OSS_SUPPORT
+ _seqbufptr=0;
+#endif
+}
+
+
+const char *DeviceManager::name(int i)
+{
+#ifdef HAVE_OSS_SUPPORT
+ if (checkInit()<0) {_ok = 0; return NULL;}
+
+ if (alsa)
+ {
+ if (i<n_midi) return device[i]->deviceName();
+ }
+ else
+ {
+ if (i<n_midi) return midiinfo[i].name;
+ if (i<n_midi+n_synths) return synthinfo[i-n_midi].name;
+ };
+#endif
+ return (char *)"";
+}
+
+const char *DeviceManager::type(int i)
+{
+#ifdef HAVE_OSS_SUPPORT
+ if (checkInit()<0) {_ok = 0; return NULL;}
+
+ if (alsa)
+ {
+ if (i<n_midi) return "ALSA device";
+ }
+ else
+ {
+ 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;
+ }
+ }
+ }
+#endif
+ return "";
+}
+
+int DeviceManager::defaultDevice(void)
+{
+ return default_dev;
+}
+
+void DeviceManager::setDefaultDevice(int i)
+{
+ if (i>=n_total) return;
+ default_dev=i;
+ for (int i=0;i<16;i++) chn2dev[i]=default_dev;
+}
+
+const char *DeviceManager::midiMapFilename(void)
+{
+ if (device==0L) return "";
+ if (default_dev>=n_total) return "";
+ return (device[default_dev]!=NULL) ?
+ device[default_dev]->midiMapFilename() : "";
+}
+
+void DeviceManager::setMidiMap(MidiMapper *map)
+{
+ if (map==NULL) return;
+ mapper_tmp=map;
+ if (default_dev>=n_total) {default_dev=0;return;};
+ if ((device==0L)||(device[default_dev]==NULL))
+ return;
+ device[default_dev]->setMidiMapper(map);
+}
+
+int DeviceManager::setPatchesToUse(int *patchesused)
+{
+ if (checkInit()<0) return -1;
+ if ((device==0L)||(device[default_dev]==NULL))
+ return 0;
+
+ if ((device[default_dev]->deviceType())==KMID_GUS)
+ {
+ GUSOut *gus=(GUSOut *)device[default_dev];
+ gus->setPatchesToUse(patchesused);
+ }
+ return 0;
+}
+
+void DeviceManager::setVolumePercentage(int v)
+{
+ if (device!=0L)
+ {
+ for (int i=0;i<n_total;i++)
+ {
+ device[i]->setVolumePercentage(v);
+ }
+ }
+}
+
+void DeviceManager::setDeviceNumberForChannel(int chn, int dev)
+{
+ chn2dev[chn]=dev;
+}
+
+void DeviceManager::allNotesOff(void)
+{
+ for (int i=0;i<n_midi;i++)
+ device[i]->allNotesOff();
+}