28 #include "deviceman.h"
33 #include <sys/ioctl.h>
40 #include "midimapper.h"
47 #ifdef HAVE_SYS_STAT_H
51 #ifdef HAVE_ALSA_ASOUNDLIB_H
52 # define HAVE_ALSA_SUPPORT
53 # include <alsa/asoundlib.h>
54 #elif defined(HAVE_SYS_ASOUNDLIB_H)
55 # define HAVE_ALSA_SUPPORT
56 # include <sys/asoundlib.h>
58 #ifdef HAVE_LIBASOUND2
59 # define HAVE_ALSA_SUPPORT
60 # include <sound/asound.h>
61 # include <sound/asequencer.h>
62 #elif defined(HAVE_LIBASOUND)
63 # define HAVE_ALSA_SUPPORT
64 # include <linux/asequencer.h>
69 #include <kinstance.h>
70 #include <tdeglobal.h>
71 #include <tdeconfig.h>
81 #ifdef GENERAL_DEBUG_MESSAGES
82 void DEBUGPRINTF(
const char *format)
87 void DEBUGPRINTF(
const char *format,
int i)
92 void DEBUGPRINTF(
const char *format,
const char *s)
99 void DEBUGPRINTF(
const char *) { }
100 void DEBUGPRINTF(
const char *,
int ) { }
101 void DEBUGPRINTF(
const char *,
const char * ) { }
112 if (!TDEGlobal::_instance) tmp_instance=
new TDEInstance(
"nonKDEapp");
117 if ( default_dev < 0 )
120 if ((config->
readBoolEntry(
"useMidiMapper",
false))&&(!mapurl.isEmpty()))
122 mapper_tmp =
new MidiMapper( mapurl.mid(mapurl.find(
":")+1 ).local8Bit() );
150 for (
int i=0;i<16;i++) chn2dev[i]=default_dev;
158 for (
int i=0;i<n_total;i++)
163 #ifdef HAVE_OSS_SUPPORT
181 if (default_dev>=n_total) default_dev=0;
182 DEBUGPRINTF(
"check : %d\n",r);
188 void DeviceManager::checkAlsa(
void)
190 #ifdef HAVE_SYS_STAT_H
192 stat(
"/proc/asound", &buf);
193 if ((stat(
"/proc/asound", &buf) == 0 ) && (S_ISDIR(buf.st_mode)))
198 #warning "ALSA won't be found at runtime"
209 #ifdef HAVE_OSS_SUPPORT
214 seqfd = open(
"/dev/sequencer", O_WRONLY | O_NONBLOCK, 0);
217 fprintf(stderr,
"ERROR: Couldn't open /dev/sequencer to get some information\n");
221 ioctl(seqfd,SNDCTL_SEQ_NRSYNTHS,&n_synths);
222 ioctl(seqfd,SNDCTL_SEQ_NRMIDIS,&n_midi);
223 n_total=n_midi+n_synths;
228 fprintf(stderr,
"ERROR: There's no midi port\n");
236 midiinfo=
new midi_info[n_midi];
237 synthinfo=
new synth_info[n_synths];
240 for (i=0;i<n_midi;i++)
242 midiinfo[i].device=i;
243 if (ioctl(seqfd,SNDCTL_MIDI_INFO,&midiinfo[i])!=-1)
245 #ifdef GENERAL_DEBUG_MESSAGES
247 printf(
"Device : %d\n",i);
248 printf(
"Name : %s\n",midiinfo[i].
name);
249 printf(
"Device type : %d\n",midiinfo[i].dev_type);
255 for (i=0;i<n_synths;i++)
257 synthinfo[i].device=i;
258 if (ioctl(seqfd,SNDCTL_SYNTH_INFO,&synthinfo[i])!=-1)
260 #ifdef GENERAL_DEBUG_MESSAGES
262 printf(
"Device : %d\n",i);
263 printf(
"Name : %s\n",synthinfo[i].
name);
264 switch (synthinfo[i].synth_type)
266 case (SYNTH_TYPE_FM) : printf(
"FM\n");
break;
267 case (SYNTH_TYPE_SAMPLE) : printf(
"Sample\n");
break;
268 case (SYNTH_TYPE_MIDI) : printf(
"Midi\n");
break;
269 default : printf(
"default type\n");
break;
271 switch (synthinfo[i].synth_subtype)
273 case (FM_TYPE_ADLIB) : printf(
"Adlib\n");
break;
274 case (FM_TYPE_OPL3) : printf(
"Opl3\n");
break;
275 case (MIDI_TYPE_MPU401) : printf(
"Mpu-401\n");
break;
276 case (SAMPLE_TYPE_GUS) : printf(
"Gus\n");
break;
277 default : printf(
"default subtype\n");
break;
280 if (synthinfo[i].synth_type==SYNTH_TYPE_FM)
281 device[i+n_midi]=
new FMOut(i,synthinfo[i].nr_voices);
282 else if ((synthinfo[i].synth_type==SYNTH_TYPE_SAMPLE)&&
283 (synthinfo[i].synth_subtype==SAMPLE_TYPE_GUS))
284 device[i+n_midi]=
new GUSOut(i,synthinfo[i].nr_voices);
307 #ifdef HAVE_ALSA_SUPPORT
309 #ifdef HAVE_LIBASOUND2
311 snd_seq_client_info_t *clienti;
312 snd_seq_client_info_malloc(&clienti);
313 snd_seq_port_info_t *porti;
314 snd_seq_port_info_malloc(&porti);
316 snd_seq_open(&handle,
"hw", SND_SEQ_OPEN_DUPLEX, 0);
317 if (!handle) { printf(
"handle==0\n");
return -1; };
318 snd_seq_system_info_t *info;
319 snd_seq_system_info_malloc(&info);
320 if (!info) { printf(
"info==0\n");
return -1; };
321 snd_seq_system_info(handle, info);
327 device=
new MidiOut*[snd_seq_system_info_get_clients(info)*snd_seq_system_info_get_ports(info)];
328 unsigned int k=SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_WRITE ;
329 for (client=0 ; client<snd_seq_system_info_get_clients(info) ; client++)
331 snd_seq_get_any_client_info(handle, client, clienti);
332 for (port=0 ; port<snd_seq_client_info_get_num_ports(clienti) ; port++)
334 snd_seq_get_any_port_info(handle, client, port, porti);
335 if (( snd_seq_port_info_get_capability(porti) & k ) == k)
337 device[n_midi]=
new AlsaOut(n_midi,client, port, snd_seq_client_info_get_name(clienti), snd_seq_port_info_get_name(porti));
342 snd_seq_client_info_free(clienti);
343 snd_seq_port_info_free(porti);
344 snd_seq_system_info_free(info);
347 snd_seq_client_info_t clienti;
348 snd_seq_port_info_t porti;
350 snd_seq_open(&handle, SND_SEQ_OPEN);
351 if (!handle) { printf(
"handle(2)==0\n");
return -1; };
353 snd_seq_system_info_t info;
354 info.clients=info.ports=0;
355 snd_seq_system_info(handle, &info);
361 device=
new MidiOut*[info.clients*info.ports];
362 unsigned int k=SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_WRITE ;
363 for (client=0 ; client<info.clients ; client++)
365 snd_seq_get_any_client_info(handle, client, &clienti);
366 for (port=0 ; port<clienti.num_ports ; port++)
368 snd_seq_get_any_port_info(handle, client, port, &porti);
369 if (( porti.capability & k ) == k)
371 device[n_midi]=
new AlsaOut(n_midi,client, port, clienti.name, porti.name);
379 snd_seq_close(handle);
384 fprintf(stderr,
"Sorry, this KMid version was compiled without \n");
385 fprintf(stderr,
"ALSA support but you're using ALSA . \n");
386 fprintf(stderr,
"Please compile KMid for yourself or tell the people\n");
387 fprintf(stderr,
"at your Linux distribution to compile it themselves\n");
402 DEBUGPRINTF(
"DeviceManager::openDev : Not initialized\n");
410 #ifdef HAVE_OSS_SUPPORT
411 seqfd = open(
"/dev/sequencer", O_WRONLY | O_NONBLOCK, 0);
414 fprintf(stderr,
"Couldn't open the MIDI sequencer device (/dev/sequencer)\n");
419 ioctl(seqfd,SNDCTL_SEQ_RESET);
422 int r=ioctl(seqfd,SNDCTL_SEQ_CTRLRATE,&m_rate);
423 if ((r==-1)||(m_rate<=0)) m_rate=HZ;
425 convertrate=1000/m_rate;
432 for (
int i=0;i<n_total;i++)
438 for (
int i=0;i<n_total;i++)
if (!device[i]->
ok()) _ok=0;
441 for (
int i=0;i<n_total;i++) device[i]->
closeDev();
454 for (
int i=0;i<n_total;i++)
455 if (device[i]) device[i]->
closeDev();
460 #ifdef HAVE_OSS_SUPPORT
461 if (seqfd==-1)
return;
464 for (
int i=0;i<n_total;i++)
465 if (device[i]) device[i]->
closeDev();
487 for (
int i=0;i<n_total;i++)
490 DEBUGPRINTF(
"%s ",device[i]->deviceName());
499 if (midi) midi->
noteOn(chn,note,vel);
504 if (midi) midi->
noteOff(chn,note,vel);
533 for (
int i=0;i<n_midi;i++)
534 device[i]->sysex(data,size);
539 #ifdef HAVE_ALSA_SUPPORT
540 if (alsa) { ((
AlsaOut *)device[default_dev])->wait(ticks);
return; };
543 #ifdef HAVE_OSS_SUPPORT
544 unsigned long int t=(
unsigned long int)(ticks/convertrate);
545 if (lastwaittime==t)
return;
555 #ifdef HAVE_ALSA_SUPPORT
556 if (alsa) { ((
AlsaOut *)device[default_dev])->tmrSetTempo(v);
return; }
559 #ifdef HAVE_OSS_SUPPORT
566 #ifdef HAVE_ALSA_SUPPORT
571 #ifdef HAVE_ALSA_SUPPORT
572 if (alsa) { ((
AlsaOut *)device[default_dev])->tmrStart(tpcn);
return; }
575 #ifdef HAVE_OSS_SUPPORT
593 #ifdef HAVE_ALSA_SUPPORT
594 if (alsa) { ((
AlsaOut *)device[default_dev])->tmrStop();
return; }
597 #ifdef HAVE_OSS_SUPPORT
614 #ifdef HAVE_ALSA_SUPPORT
615 if (alsa) { ((
AlsaOut *)device[default_dev])->tmrContinue();
return; }
618 #ifdef HAVE_OSS_SUPPORT
622 SEQ_CONTINUE_TIMER();
626 SEQ_CONTINUE_TIMER();
634 #ifdef HAVE_ALSA_SUPPORT
635 if (alsa) { ((
AlsaOut *)device[default_dev])->sync(f); return ; };
638 #ifdef HAVE_OSS_SUPPORT
639 #ifdef DEVICEMANDEBUG
640 printf(
"Sync %d\n",f);
647 ioctl(seqfd,SNDCTL_SEQ_RESET);
648 ioctl(seqfd,SNDCTL_SEQ_PANIC);
653 ioctl(seqfd, SNDCTL_SEQ_SYNC);
658 void DeviceManager::seqbuf_dump (
void)
662 #ifdef HAVE_OSS_SUPPORT
666 unsigned char *sb=_seqbuf;
668 r=write (seqfd, _seqbuf, _seqbufptr);
669 #ifdef DEVICEMANDEBUG
670 printf(
"%d == %d\n",r,w);
671 printf(
"%d\n",(errno==EAGAIN)? 1 : 0);
673 while (((r == -1)&&(errno==EAGAIN))||(r != w))
675 if ((r==-1)&&(errno==EAGAIN))
679 else if ((r>0)&&(r!=w))
684 r=write (seqfd, sb, w);
685 #ifdef DEVICEMANDEBUG
686 printf(
"%d == %d\n",r,w);
687 printf(
"%d\n",(errno==EAGAIN)? 1 : 0);
705 void DeviceManager::seqbuf_clean(
void)
707 #ifdef HAVE_ALSA_SUPPORT
708 if (alsa) { ((
AlsaOut *)device[default_dev])->seqbuf_clean(); return ; }
710 #ifdef HAVE_OSS_SUPPORT
718 #ifdef HAVE_OSS_SUPPORT
719 if (
checkInit()<0) {_ok = 0;
return NULL;}
727 if (i<n_midi)
return midiinfo[i].name;
728 if (i<n_midi+n_synths)
return synthinfo[i-n_midi].name;
736 #ifdef HAVE_OSS_SUPPORT
737 if (
checkInit()<0) {_ok = 0;
return NULL;}
741 if (i<n_midi)
return "ALSA device";
747 return "External Midi Port";
749 if (i<n_midi+n_synths)
751 switch (synthinfo[i-n_midi].synth_subtype)
753 case (FM_TYPE_ADLIB) :
return "Adlib";
break;
754 case (FM_TYPE_OPL3) :
return "FM";
break;
755 case (MIDI_TYPE_MPU401) :
return "MPU 401";
break;
756 case (SAMPLE_TYPE_GUS) :
return "GUS";
break;
771 if (i>=n_total)
return;
773 for (
int i=0;i<16;i++) chn2dev[i]=default_dev;
778 if (device==0L)
return "";
779 if (default_dev>=n_total)
return "";
780 return (device[default_dev]!=NULL) ?
786 if (map==NULL)
return;
788 if (default_dev>=n_total) {default_dev=0;
return;};
789 if ((device==0L)||(device[default_dev]==NULL))
797 if ((device==0L)||(device[default_dev]==NULL))
800 if ((device[default_dev]->deviceType())==KMID_GUS)
812 for (
int i=0;i<n_total;i++)
826 for (
int i=0;i<n_midi;i++)
Sends MIDI events to a MIDI devices using ALSA.
void noteOn(uchar chn, uchar note, uchar vel)
Sends a Note On MIDI event.
int checkInit(void)
Checks if the device manager has been initialized (with initManager), and in case it wasn't,...
void chnPitchBender(uchar chn, uchar lsb, uchar msb)
Changes the Pitch Bender value on a MIDI channel.
void wait(double ms)
Sets the number of milliseconds at which the next event will be sent.
const char * name(int i)
Returns the name of the i-th device .
void chnPatchChange(uchar chn, uchar patch)
Changes the patch (instrument) on a MIDI channel.
int setPatchesToUse(int *patchesused)
Loads the patches you're going to use .
void setDefaultDevice(int i)
Sets the device to send the MIDI events to.
MidiOut * chntodev(int chn)
void chnController(uchar chn, uchar ctl, uchar v)
Sends a Controller event to a MIDI channel.
~DeviceManager(void)
Destructor.
void initDev(void)
Calls MidiOut::initDev() in turn in each of the available devices.
void tmrStart(long int tpcn)
Starts the timer.
int defaultDevice(void)
Returns the device to which the MIDI events will be sent.
void sysEx(uchar *data, ulong size)
Sends a SYStem EXclusive message to the default MIDI device (usually, external MIDI synths,...
void setVolumePercentage(int i)
Changes the "master" volume of the played events by altering next volume controller events.
int initManager(void)
Initializes the MIDI Device Manager object.
void setMidiMap(MidiMapper *map)
Sets a MidiMapper object to use.
const char * type(int i)
Returns the type of device the i-th device is , in a user-friendly string .
void chnPressure(uchar chn, uchar vel)
Changes the Pressure (Aftertouch) on a MIDI channel.
void tmrStop(void)
Stops the timer.
void sync(bool f=0)
Synchronizes with the MIDI buffer.
void noteOff(uchar chn, uchar note, uchar vel)
Sends a Note Off MIDI event.
DeviceManager(int def=-1)
Constructor.
void keyPressure(uchar chn, uchar note, uchar vel)
Sends a Key Pressure (or Aftertouch) MIDI event.
void closeDev(void)
Closes the devices, and /dev/sequencer.
void tmrSetTempo(int v)
Sets the tempo which will be used to convert between ticks and milliseconds.
const char * midiMapFilename(void)
Returns the filename where the Midi Mapper was loaded from, or "" if no MIDI Mapper is in use.
void openDev(void)
Open the devices.
void allNotesOff(void)
Sends an all notes off event.
void setDeviceNumberForChannel(int chn, int dev)
Sets the device number associated with a given channel.
void tmrContinue(void)
Continue the stopped timer .
Gravis Ultrasound synthesizer output class .
void setPatchesToUse(int *patchesused)
See DeviceManager::setPatchesToUse() .
A Midi Mapper class which defines the way MIDI events are translated (or "mapped") to different ones.
External MIDI port output class .
virtual void setVolumePercentage(int volper)
Change all channel volume events multiplying it by this percentage correction Instead of forcing a ch...
virtual void chnPitchBender(uchar chn, uchar lsb, uchar msb)
See DeviceManager::chnPitchBender()
const char * deviceName(void) const
Returns the name and type of this MIDI device.
virtual void noteOn(uchar chn, uchar note, uchar vel)
See DeviceManager::noteOn()
void setMidiMapper(MidiMapper *map)
Sets a MidiMapper object to be used to modify the midi events before sending them.
virtual void chnPatchChange(uchar chn, uchar patch)
See DeviceManager::chnPatchChange()
virtual void initDev()
Initializes the device sending generic standard midi events and controllers, such as changing the pat...
const char * midiMapFilename()
Returns the path to the file where the current used MidiMapper object reads the configuration from,...
virtual void openDev(int sqfd)
Opens the device.
virtual void closeDev()
Closes the device.
virtual void chnPressure(uchar chn, uchar vel)
See DeviceManager::chnPressure()
virtual void keyPressure(uchar chn, uchar note, uchar vel)
See DeviceManager::keyPressure()
virtual void noteOff(uchar chn, uchar note, uchar vel)
See DeviceManager::noteOff()
virtual void chnController(uchar chn, uchar ctl, uchar v)
See DeviceManager::chnController()
Synth (AWE) device output class .
int readNumEntry(const TQString &pKey, int nDefault=0) const
bool readBoolEntry(const TQString &pKey, bool bDefault=false) const
TQString readPathEntry(const TQString &pKey, const TQString &aDefault=TQString::null) const
void setGroup(const TQString &group)