drumstick  1.1.3
alsaclient.cpp
Go to the documentation of this file.
1 /*
2  MIDI Sequencer C++ library
3  Copyright (C) 2006-2019, Pedro Lopez-Cabanillas <plcl@users.sf.net>
4 
5  This library is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (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
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <drumstick/alsaclient.h>
20 #include <drumstick/alsaqueue.h>
21 #include <drumstick/alsaevent.h>
22 #include <QFile>
23 #include <QRegExp>
24 #include <QThread>
25 #include <QReadLocker>
26 #include <QWriteLocker>
27 #if defined(RTKIT_SUPPORT)
28 #include <QDBusConnection>
29 #include <QDBusInterface>
30 #include <sys/types.h>
31 #include <sys/syscall.h>
32 #include <sys/resource.h>
33 #endif
34 #include <pthread.h>
35 
36 #ifndef RLIMIT_RTTIME
37 #define RLIMIT_RTTIME 15
38 #endif
39 
40 #ifndef SCHED_RESET_ON_FORK
41 #define SCHED_RESET_ON_FORK 0x40000000
42 #endif
43 
44 #ifndef DEFAULT_INPUT_TIMEOUT
45 #define DEFAULT_INPUT_TIMEOUT 500
46 #endif
47 
65 namespace drumstick {
66 
186 {
187 public:
188  SequencerInputThread(MidiClient *seq, int timeout)
189  : QThread(),
190  m_MidiClient(seq),
191  m_Wait(timeout),
192  m_Stopped(false),
193  m_RealTime(true) {}
194  virtual ~SequencerInputThread() {}
195  virtual void run();
196  bool stopped();
197  void stop();
198  void setRealtimePriority();
199 
200  MidiClient *m_MidiClient;
201  int m_Wait;
202  bool m_Stopped;
203  bool m_RealTime;
204  QReadWriteLock m_mutex;
205 };
206 
207 class MidiClient::MidiClientPrivate
208 {
209 public:
210  MidiClientPrivate() :
211  m_eventsEnabled(false),
212  m_BlockMode(false),
213  m_NeedRefreshClientList(true),
214  m_OpenMode(SND_SEQ_OPEN_DUPLEX),
215  m_DeviceName("default"),
216  m_SeqHandle(0),
217  m_Thread(0),
218  m_Queue(0),
219  m_handler(0)
220  { }
221 
222  bool m_eventsEnabled;
223  bool m_BlockMode;
224  bool m_NeedRefreshClientList;
225  int m_OpenMode;
226  QString m_DeviceName;
227  snd_seq_t* m_SeqHandle;
228  QPointer<SequencerInputThread> m_Thread;
229  QPointer<MidiQueue> m_Queue;
230  SequencerEventHandler* m_handler;
231 
232  ClientInfo m_Info;
233  ClientInfoList m_ClientList;
234  MidiPortList m_Ports;
235  PortInfoList m_OutputsAvail;
236  PortInfoList m_InputsAvail;
237  QObjectList m_listeners;
238  SystemInfo m_sysInfo;
239  PoolInfo m_poolInfo;
240 };
241 
258  QObject(parent),
259  d(new MidiClientPrivate)
260 { }
261 
268 {
270  detachAllPorts();
271  if (d->m_Queue != 0)
272  delete d->m_Queue;
273  close();
274  freeClients();
275  if (d->m_Thread != 0)
276  delete d->m_Thread;
277  delete d;
278 }
279 
280 
284 snd_seq_t*
286 {
287  return d->m_SeqHandle;
288 }
289 
294 {
295  return (d->m_SeqHandle != NULL);
296 }
297 
302 {
303  return d->m_DeviceName;
304 }
305 
310 {
311  return d->m_OpenMode;
312 }
313 
318 {
319  return d->m_BlockMode;
320 }
321 
326 {
327  return d->m_eventsEnabled;
328 }
329 
334 {
335  d->m_handler = handler;
336 }
337 
338 
348 {
349  if (d->m_Thread == 0) {
350  d->m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
351  d->m_Thread->m_RealTime = enable;
352  }
353 }
354 
361 {
362  if (d->m_Thread == 0)
363  return true;
364  return d->m_Thread->m_RealTime;
365 }
366 
387 void
388 MidiClient::open( const QString deviceName,
389  const int openMode,
390  const bool blockMode)
391 {
392  CHECK_ERROR( snd_seq_open( &d->m_SeqHandle, deviceName.toLocal8Bit().data(),
393  openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) );
394  CHECK_WARNING( snd_seq_get_client_info( d->m_SeqHandle, d->m_Info.m_Info ) );
395  d->m_DeviceName = deviceName;
396  d->m_OpenMode = openMode;
397  d->m_BlockMode = blockMode;
398 }
399 
420 void
421 MidiClient::open( snd_config_t* conf,
422  const QString deviceName,
423  const int openMode,
424  const bool blockMode )
425 {
426  CHECK_ERROR( snd_seq_open_lconf( &d->m_SeqHandle,
427  deviceName.toLocal8Bit().data(),
428  openMode,
429  blockMode ? 0 : SND_SEQ_NONBLOCK,
430  conf ));
431  CHECK_WARNING( snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info));
432  d->m_DeviceName = deviceName;
433  d->m_OpenMode = openMode;
434  d->m_BlockMode = blockMode;
435 }
436 
444 void
446 {
447  if (d->m_SeqHandle != NULL) {
449  CHECK_WARNING(snd_seq_close(d->m_SeqHandle));
450  d->m_SeqHandle = NULL;
451  }
452 }
453 
462 size_t
464 {
465  return snd_seq_get_output_buffer_size(d->m_SeqHandle);
466 }
467 
476 void
478 {
479  if (getOutputBufferSize() != newSize) {
480  CHECK_WARNING(snd_seq_set_output_buffer_size(d->m_SeqHandle, newSize));
481  }
482 }
483 
492 size_t
494 {
495  return snd_seq_get_input_buffer_size(d->m_SeqHandle);
496 }
497 
506 void
508 {
509  if (getInputBufferSize() != newSize) {
510  CHECK_WARNING(snd_seq_set_input_buffer_size(d->m_SeqHandle, newSize));
511  }
512 }
513 
523 void
525 {
526  if (d->m_BlockMode != newValue)
527  {
528  d->m_BlockMode = newValue;
529  if (d->m_SeqHandle != NULL)
530  {
531  CHECK_WARNING(snd_seq_nonblock(d->m_SeqHandle, d->m_BlockMode ? 0 : 1));
532  }
533  }
534 }
535 
544 int
546 {
547  return CHECK_WARNING(snd_seq_client_id(d->m_SeqHandle));
548 }
549 
554 snd_seq_type_t
556 {
557  return snd_seq_type(d->m_SeqHandle);
558 }
559 
580 void
582 {
583  do {
584  int err = 0;
585  snd_seq_event_t* evp = NULL;
586  SequencerEvent* event = NULL;
587  err = snd_seq_event_input(d->m_SeqHandle, &evp);
588  if ((err >= 0) && (evp != NULL)) {
589  switch (evp->type) {
590 
591  case SND_SEQ_EVENT_NOTE:
592  event = new NoteEvent(evp);
593  break;
594 
595  case SND_SEQ_EVENT_NOTEON:
596  event = new NoteOnEvent(evp);
597  break;
598 
599  case SND_SEQ_EVENT_NOTEOFF:
600  event = new NoteOffEvent(evp);
601  break;
602 
603  case SND_SEQ_EVENT_KEYPRESS:
604  event = new KeyPressEvent(evp);
605  break;
606 
607  case SND_SEQ_EVENT_CONTROLLER:
608  case SND_SEQ_EVENT_CONTROL14:
609  case SND_SEQ_EVENT_REGPARAM:
610  case SND_SEQ_EVENT_NONREGPARAM:
611  event = new ControllerEvent(evp);
612  break;
613 
614  case SND_SEQ_EVENT_PGMCHANGE:
615  event = new ProgramChangeEvent(evp);
616  break;
617 
618  case SND_SEQ_EVENT_CHANPRESS:
619  event = new ChanPressEvent(evp);
620  break;
621 
622  case SND_SEQ_EVENT_PITCHBEND:
623  event = new PitchBendEvent(evp);
624  break;
625 
626  case SND_SEQ_EVENT_SYSEX:
627  event = new SysExEvent(evp);
628  break;
629 
630  case SND_SEQ_EVENT_PORT_SUBSCRIBED:
631  case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
632  event = new SubscriptionEvent(evp);
633  break;
634 
635  case SND_SEQ_EVENT_PORT_CHANGE:
636  case SND_SEQ_EVENT_PORT_EXIT:
637  case SND_SEQ_EVENT_PORT_START:
638  event = new PortEvent(evp);
639  d->m_NeedRefreshClientList = true;
640  break;
641 
642  case SND_SEQ_EVENT_CLIENT_CHANGE:
643  case SND_SEQ_EVENT_CLIENT_EXIT:
644  case SND_SEQ_EVENT_CLIENT_START:
645  event = new ClientEvent(evp);
646  d->m_NeedRefreshClientList = true;
647  break;
648 
649  case SND_SEQ_EVENT_SONGPOS:
650  case SND_SEQ_EVENT_SONGSEL:
651  case SND_SEQ_EVENT_QFRAME:
652  case SND_SEQ_EVENT_TIMESIGN:
653  case SND_SEQ_EVENT_KEYSIGN:
654  event = new ValueEvent(evp);
655  break;
656 
657  case SND_SEQ_EVENT_SETPOS_TICK:
658  case SND_SEQ_EVENT_SETPOS_TIME:
659  case SND_SEQ_EVENT_QUEUE_SKEW:
660  event = new QueueControlEvent(evp);
661  break;
662 
663  case SND_SEQ_EVENT_TEMPO:
664  event = new TempoEvent(evp);
665  break;
666 
667  default:
668  event = new SequencerEvent(evp);
669  break;
670  }
671  // first, process the callback (if any)
672  if (d->m_handler != NULL) {
673  d->m_handler->handleSequencerEvent(event->clone());
674  } else {
675  // second, process the event listeners
676  if (d->m_eventsEnabled) {
677  QObjectList::Iterator it;
678  for(it=d->m_listeners.begin(); it!=d->m_listeners.end(); ++it) {
679  QObject* sub = (*it);
680  QCoreApplication::postEvent(sub, event->clone());
681  }
682  } else {
683  // finally, process signals
684  emit eventReceived(event->clone());
685  }
686  }
687  delete event;
688  }
689  }
690  while (snd_seq_event_input_pending(d->m_SeqHandle, 0) > 0);
691 }
692 
696 void
698 {
699  if (d->m_Thread == 0) {
700  d->m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
701  }
702  d->m_Thread->start( d->m_Thread->m_RealTime ?
703  QThread::TimeCriticalPriority : QThread::InheritPriority );
704 }
705 
709 void
711 {
712  int counter = 0;
713  if (d->m_Thread != 0) {
714  if (d->m_Thread->isRunning()) {
715  d->m_Thread->stop();
716  while (!d->m_Thread->wait(500) && (counter < 10)) {
717  counter++;
718  }
719  if (!d->m_Thread->isFinished()) {
720  d->m_Thread->terminate();
721  }
722  }
723  delete d->m_Thread;
724  }
725 }
726 
730 void
732 {
733  ClientInfo cInfo;
734  freeClients();
735  cInfo.setClient(-1);
736  while (snd_seq_query_next_client(d->m_SeqHandle, cInfo.m_Info) >= 0) {
737  cInfo.readPorts(this);
738  d->m_ClientList.append(cInfo);
739  }
740  d->m_NeedRefreshClientList = false;
741 }
742 
746 void
748 {
749  d->m_ClientList.clear();
750 }
751 
758 {
759  if (d->m_NeedRefreshClientList)
760  readClients();
761  ClientInfoList lst = d->m_ClientList; // copy
762  return lst;
763 }
764 
769 ClientInfo&
771 {
772  snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info);
773  return d->m_Info;
774 }
775 
783 void
785 {
786  d->m_Info = val;
787  snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
788 }
789 
793 void
795 {
796  if (d->m_SeqHandle != NULL) {
797  snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
798  }
799 }
800 
805 QString
807 {
808  return d->m_Info.getName();
809 }
810 
816 QString
817 MidiClient::getClientName(const int clientId)
818 {
819  ClientInfoList::Iterator it;
820  if (d->m_NeedRefreshClientList)
821  readClients();
822  for (it = d->m_ClientList.begin(); it != d->m_ClientList.end(); ++it) {
823  if ((*it).getClientId() == clientId) {
824  return (*it).getName();
825  }
826  }
827  return QString();
828 }
829 
834 void
835 MidiClient::setClientName(QString const& newName)
836 {
837  if (newName != d->m_Info.getName()) {
838  d->m_Info.setName(newName);
839  applyClientInfo();
840  }
841 }
842 
849 {
850  return d->m_Ports;
851 }
852 
857 MidiPort*
859 {
860  MidiPort* port = new MidiPort(this);
861  port->attach(this);
862  return port;
863 }
864 
869 void
871 {
872  if (d->m_SeqHandle != NULL) {
873  CHECK_ERROR(snd_seq_create_port(d->m_SeqHandle, port->m_Info.m_Info));
874  d->m_Ports.push_back(port);
875  }
876 }
877 
882 void
884 {
885  if (d->m_SeqHandle != NULL) {
886  if(port->getPortInfo()->getClient() == getClientId())
887  {
888  return;
889  }
890  CHECK_ERROR(snd_seq_delete_port(d->m_SeqHandle, port->getPortInfo()->getPort()));
891  port->setMidiClient(NULL);
892 
893  MidiPortList::iterator it;
894  for(it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it)
895  {
896  if ((*it)->getPortInfo()->getPort() == port->getPortInfo()->getPort())
897  {
898  d->m_Ports.erase(it);
899  break;
900  }
901  }
902  }
903 }
904 
909 {
910  if (d->m_SeqHandle != NULL) {
911  MidiPortList::iterator it;
912  for (it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it) {
913  CHECK_ERROR(snd_seq_delete_port(d->m_SeqHandle, (*it)->getPortInfo()->getPort()));
914  (*it)->setMidiClient(NULL);
915  d->m_Ports.erase(it);
916  }
917  }
918 }
919 
924 void
926 {
927  snd_seq_set_client_event_filter(d->m_SeqHandle, evtype);
928 }
929 
935 bool
937 {
938  return d->m_Info.getBroadcastFilter();
939 }
940 
946 void
948 {
949  d->m_Info.setBroadcastFilter(newValue);
950  applyClientInfo();
951 }
952 
958 bool
960 {
961  return d->m_Info.getErrorBounce();
962 }
963 
969 void
971 {
972  d->m_Info.setErrorBounce(newValue);
973  applyClientInfo();
974 }
975 
987 void
988 MidiClient::output(SequencerEvent* ev, bool async, int timeout)
989 {
990  int npfds;
991  pollfd* pfds;
992  if (async) {
993  CHECK_WARNING(snd_seq_event_output(d->m_SeqHandle, ev->getHandle()));
994  } else {
995  npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
996  pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
997  snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
998  while (snd_seq_event_output(d->m_SeqHandle, ev->getHandle()) < 0)
999  {
1000  poll(pfds, npfds, timeout);
1001  }
1002  }
1003 }
1004 
1016 void MidiClient::outputDirect(SequencerEvent* ev, bool async, int timeout)
1017 {
1018  int npfds;
1019  pollfd* pfds;
1020  if (async) {
1021  CHECK_WARNING(snd_seq_event_output_direct(d->m_SeqHandle, ev->getHandle()));
1022  } else {
1023  npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1024  pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
1025  snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1026  while (snd_seq_event_output_direct(d->m_SeqHandle, ev->getHandle()) < 0)
1027  {
1028  poll(pfds, npfds, timeout);
1029  }
1030  }
1031 }
1032 
1041 void
1043 {
1044  CHECK_WARNING(snd_seq_event_output_buffer(d->m_SeqHandle, ev->getHandle()));
1045 }
1046 
1058 void MidiClient::drainOutput(bool async, int timeout)
1059 {
1060  int npfds;
1061  pollfd* pfds;
1062  if (async) {
1063  CHECK_WARNING(snd_seq_drain_output(d->m_SeqHandle));
1064  } else {
1065  npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1066  pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
1067  snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1068  while (snd_seq_drain_output(d->m_SeqHandle) < 0)
1069  {
1070  poll(pfds, npfds, timeout);
1071  }
1072  }
1073 }
1074 
1080 void
1082 {
1083  snd_seq_sync_output_queue(d->m_SeqHandle);
1084 }
1085 
1091 MidiQueue*
1093 {
1094  if (d->m_Queue == NULL) {
1095  createQueue();
1096  }
1097  return d->m_Queue;
1098 }
1099 
1104 MidiQueue*
1106 {
1107  if (d->m_Queue != NULL) {
1108  delete d->m_Queue;
1109  }
1110  d->m_Queue = new MidiQueue(this, this);
1111  return d->m_Queue;
1112 }
1113 
1120 MidiQueue*
1121 MidiClient::createQueue(QString const& queueName )
1122 {
1123  if (d->m_Queue != NULL) {
1124  delete d->m_Queue;
1125  }
1126  d->m_Queue = new MidiQueue(this, queueName, this);
1127  return d->m_Queue;
1128 }
1129 
1137 MidiQueue*
1139 {
1140  if (d->m_Queue != NULL) {
1141  delete d->m_Queue;
1142  }
1143  d->m_Queue = new MidiQueue(this, queue_id, this);
1144  return d->m_Queue;
1145 }
1146 
1154 MidiQueue*
1155 MidiClient::useQueue(const QString& name)
1156 {
1157  if (d->m_Queue != NULL) {
1158  delete d->m_Queue;
1159  }
1160  int queue_id = getQueueId(name);
1161  if ( queue_id >= 0) {
1162  d->m_Queue = new MidiQueue(this, queue_id, this);
1163  }
1164  return d->m_Queue;
1165 }
1166 
1173 MidiQueue*
1175 {
1176  if (d->m_Queue != NULL) {
1177  delete d->m_Queue;
1178  }
1179  queue->setParent(this);
1180  d->m_Queue = queue;
1181  return d->m_Queue;
1182 }
1183 
1188 QList<int>
1190 {
1191  int q, err, max;
1192  QList<int> queues;
1193  snd_seq_queue_info_t* qinfo;
1194  snd_seq_queue_info_alloca(&qinfo);
1195  max = getSystemInfo().getMaxQueues();
1196  for ( q = 0; q < max; ++q ) {
1197  err = snd_seq_get_queue_info(d->m_SeqHandle, q, qinfo);
1198  if (err == 0) {
1199  queues.append(q);
1200  }
1201  }
1202  return queues;
1203 }
1204 
1213 MidiClient::filterPorts(unsigned int filter)
1214 {
1215  PortInfoList result;
1216  ClientInfoList::ConstIterator itc;
1217  PortInfoList::ConstIterator itp;
1218 
1219  if (d->m_NeedRefreshClientList)
1220  readClients();
1221 
1222  for (itc = d->m_ClientList.constBegin(); itc != d->m_ClientList.constEnd(); ++itc) {
1223  ClientInfo ci = (*itc);
1224  if ((ci.getClientId() == SND_SEQ_CLIENT_SYSTEM) ||
1225  (ci.getClientId() == d->m_Info.getClientId()))
1226  continue;
1227  PortInfoList lstPorts = ci.getPorts();
1228  for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) {
1229  PortInfo pi = (*itp);
1230  unsigned int cap = pi.getCapability();
1231  if ( ((filter & cap) != 0) &&
1232  ((SND_SEQ_PORT_CAP_NO_EXPORT & cap) == 0) ) {
1233  result.append(pi);
1234  }
1235  }
1236  }
1237  return result;
1238 }
1239 
1243 void
1245 {
1246  d->m_InputsAvail.clear();
1247  d->m_OutputsAvail.clear();
1248  d->m_InputsAvail = filterPorts( SND_SEQ_PORT_CAP_READ |
1249  SND_SEQ_PORT_CAP_SUBS_READ );
1250  d->m_OutputsAvail = filterPorts( SND_SEQ_PORT_CAP_WRITE |
1251  SND_SEQ_PORT_CAP_SUBS_WRITE );
1252 }
1253 
1260 {
1261  d->m_NeedRefreshClientList = true;
1263  return d->m_InputsAvail;
1264 }
1265 
1272 {
1273  d->m_NeedRefreshClientList = true;
1275  return d->m_OutputsAvail;
1276 }
1277 
1284 void
1286 {
1287  d->m_listeners.append(listener);
1288 }
1289 
1295 void
1297 {
1298  d->m_listeners.removeAll(listener);
1299 }
1300 
1307 void
1309 {
1310  if (bEnabled != d->m_eventsEnabled) {
1311  d->m_eventsEnabled = bEnabled;
1312  }
1313 }
1314 
1319 SystemInfo&
1321 {
1322  snd_seq_system_info(d->m_SeqHandle, d->m_sysInfo.m_Info);
1323  return d->m_sysInfo;
1324 }
1325 
1330 PoolInfo&
1332 {
1333  snd_seq_get_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info);
1334  return d->m_poolInfo;
1335 }
1336 
1341 void
1343 {
1344  d->m_poolInfo = info;
1345  CHECK_WARNING(snd_seq_set_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info));
1346 }
1347 
1352 void
1354 {
1355  CHECK_WARNING(snd_seq_reset_pool_input(d->m_SeqHandle));
1356 }
1357 
1362 void
1364 {
1365  CHECK_WARNING(snd_seq_reset_pool_output(d->m_SeqHandle));
1366 }
1367 
1372 void
1374 {
1375  CHECK_WARNING(snd_seq_set_client_pool_input(d->m_SeqHandle, size));
1376 }
1377 
1382 void
1384 {
1385  CHECK_WARNING(snd_seq_set_client_pool_output(d->m_SeqHandle, size));
1386 }
1387 
1392 void
1394 {
1395  CHECK_WARNING(snd_seq_set_client_pool_output_room(d->m_SeqHandle, size));
1396 }
1397 
1402 void
1404 {
1405  CHECK_WARNING(snd_seq_drop_input(d->m_SeqHandle));
1406 }
1407 
1412 void
1414 {
1415  CHECK_WARNING(snd_seq_drop_input_buffer(d->m_SeqHandle));
1416 }
1417 
1425 void
1427 {
1428  CHECK_WARNING(snd_seq_drop_output(d->m_SeqHandle));
1429 }
1430 
1438 void
1440 {
1441  CHECK_WARNING(snd_seq_drop_output_buffer(d->m_SeqHandle));
1442 }
1443 
1450 void
1452 {
1453  CHECK_WARNING(snd_seq_remove_events(d->m_SeqHandle, spec->m_Info));
1454 }
1455 
1462 {
1463  snd_seq_event_t* ev;
1464  if (CHECK_WARNING(snd_seq_extract_output(d->m_SeqHandle, &ev) == 0)) {
1465  return new SequencerEvent(ev);
1466  }
1467  return NULL;
1468 }
1469 
1475 int
1477 {
1478  return snd_seq_event_output_pending(d->m_SeqHandle);
1479 }
1480 
1494 int
1496 {
1497  return snd_seq_event_input_pending(d->m_SeqHandle, fetch ? 1 : 0);
1498 }
1499 
1506 int
1507 MidiClient::getQueueId(const QString& name)
1508 {
1509  return snd_seq_query_named_queue(d->m_SeqHandle, name.toLocal8Bit().data());
1510 }
1511 
1517 int
1519 {
1520  return snd_seq_poll_descriptors_count(d->m_SeqHandle, events);
1521 }
1522 
1536 int
1537 MidiClient::pollDescriptors( struct pollfd *pfds, unsigned int space,
1538  short events )
1539 {
1540  return snd_seq_poll_descriptors(d->m_SeqHandle, pfds, space, events);
1541 }
1542 
1549 unsigned short
1550 MidiClient::pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
1551 {
1552  unsigned short revents;
1553  CHECK_WARNING( snd_seq_poll_descriptors_revents( d->m_SeqHandle,
1554  pfds, nfds,
1555  &revents ));
1556  return revents;
1557 }
1558 
1563 const char *
1565 {
1566  return snd_seq_name(d->m_SeqHandle);
1567 }
1568 
1573 void
1575 {
1576  CHECK_WARNING(snd_seq_set_client_name(d->m_SeqHandle, name));
1577 }
1578 
1586 int
1588  unsigned int caps,
1589  unsigned int type )
1590 {
1591  return CHECK_WARNING( snd_seq_create_simple_port( d->m_SeqHandle,
1592  name, caps, type ));
1593 }
1594 
1599 void
1601 {
1602  CHECK_WARNING( snd_seq_delete_simple_port( d->m_SeqHandle, port ));
1603 }
1604 
1611 void
1612 MidiClient::connectFrom(int myport, int client, int port)
1613 {
1614  CHECK_WARNING( snd_seq_connect_from(d->m_SeqHandle, myport, client, port ));
1615 }
1616 
1623 void
1624 MidiClient::connectTo(int myport, int client, int port)
1625 {
1626  CHECK_WARNING( snd_seq_connect_to(d->m_SeqHandle, myport, client, port ));
1627 }
1628 
1635 void
1636 MidiClient::disconnectFrom(int myport, int client, int port)
1637 {
1638  CHECK_WARNING( snd_seq_disconnect_from(d->m_SeqHandle, myport, client, port ));
1639 }
1640 
1647 void
1648 MidiClient::disconnectTo(int myport, int client, int port)
1649 {
1650  CHECK_WARNING( snd_seq_disconnect_to(d->m_SeqHandle, myport, client, port ));
1651 }
1652 
1664 bool
1665 MidiClient::parseAddress( const QString& straddr, snd_seq_addr& addr )
1666 {
1667  bool ok(false);
1668  QString testClient, testPort;
1669  ClientInfoList::ConstIterator cit;
1670  int pos = straddr.indexOf(':');
1671  if (pos > -1) {
1672  testClient = straddr.left(pos);
1673  testPort = straddr.mid(pos+1);
1674  } else {
1675  testClient = straddr;
1676  testPort = '0';
1677  }
1678  addr.client = testClient.toInt(&ok);
1679  if (ok)
1680  addr.port = testPort.toInt(&ok);
1681  if (!ok) {
1682  if (d->m_NeedRefreshClientList)
1683  readClients();
1684  for ( cit = d->m_ClientList.constBegin();
1685  cit != d->m_ClientList.constEnd(); ++cit ) {
1686  ClientInfo ci = *cit;
1687  if (testClient.compare(ci.getName(), Qt::CaseInsensitive) == 0) {
1688  addr.client = ci.getClientId();
1689  addr.port = testPort.toInt(&ok);
1690  return ok;
1691  }
1692  }
1693  }
1694  return ok;
1695 }
1696 
1701 bool
1703 {
1704  QReadLocker locker(&m_mutex);
1705  return m_Stopped;
1706 }
1707 
1711 void
1713 {
1714  QWriteLocker locker(&m_mutex);
1715  m_Stopped = true;
1716 }
1717 
1718 #if defined(RTKIT_SUPPORT)
1719 static pid_t _gettid(void) {
1720  return (pid_t) ::syscall(SYS_gettid);
1721 }
1722 #endif
1723 
1724 void
1725 MidiClient::SequencerInputThread::setRealtimePriority()
1726 {
1727  struct sched_param p;
1728  int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK;
1729  quint32 priority = 6;
1730 #if defined(RTKIT_SUPPORT)
1731  bool ok;
1732  quint32 max_prio;
1733  quint64 thread;
1734  struct rlimit old_limit, new_limit;
1735  long long max_rttime;
1736 #endif
1737 
1738  ::memset(&p, 0, sizeof(p));
1739  p.sched_priority = priority;
1740  rt = ::pthread_setschedparam(::pthread_self(), policy, &p);
1741  if (rt != 0) {
1742 #if defined(RTKIT_SUPPORT)
1743  const QString rtkit_service =
1744  QLatin1String("org.freedesktop.RealtimeKit1");
1745  const QString rtkit_path =
1746  QLatin1String("/org/freedesktop/RealtimeKit1");
1747  const QString rtkit_iface = rtkit_service;
1748  thread = _gettid();
1749  QDBusConnection bus = QDBusConnection::systemBus();
1750  QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus);
1751  QVariant maxRTPrio = realtimeKit.property("MaxRealtimePriority");
1752  max_prio = maxRTPrio.toUInt(&ok);
1753  if (!ok) {
1754  qWarning() << "invalid property RealtimeKit.MaxRealtimePriority";
1755  return;
1756  }
1757  if (priority > max_prio)
1758  priority = max_prio;
1759  QVariant maxRTNSec = realtimeKit.property("RTTimeNSecMax");
1760  max_rttime = maxRTNSec.toLongLong(&ok);
1761  if (!ok || max_rttime < 0) {
1762  qWarning() << "invalid property RealtimeKit.RTTimeNSecMax";
1763  return;
1764  }
1765  new_limit.rlim_cur = new_limit.rlim_max = max_rttime;
1766  rt = ::getrlimit(RLIMIT_RTTIME, &old_limit);
1767  if (rt < 0) {
1768  qWarning() << "getrlimit() failed. err=" << rt << ::strerror(rt);
1769  return;
1770  }
1771  rt = ::setrlimit(RLIMIT_RTTIME, &new_limit);
1772  if ( rt < 0) {
1773  qWarning() << "setrlimit() failed, err=" << rt << ::strerror(rt);
1774  return;
1775  }
1776  QDBusMessage reply = realtimeKit.call("MakeThreadRealtime", thread, priority);
1777  if (reply.type() == QDBusMessage::ErrorMessage )
1778  qWarning() << "error returned by RealtimeKit.MakeThreadRealtime:"
1779  << reply.errorMessage();
1780 #endif
1781  } else {
1782  qWarning() << "pthread_setschedparam() failed, err="
1783  << rt << ::strerror(rt);
1784  }
1785 }
1786 
1790 void
1792 {
1793  unsigned long npfd;
1794  pollfd* pfd;
1795  if ( priority() == TimeCriticalPriority )
1796  setRealtimePriority();
1797 
1798  if (m_MidiClient != NULL) {
1799  npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN);
1800  pfd = (pollfd *) alloca(npfd * sizeof(pollfd));
1801  try
1802  {
1803  snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN);
1804  while (!stopped() && (m_MidiClient != NULL))
1805  {
1806  int rt = poll(pfd, npfd, m_Wait);
1807  if (rt > 0) {
1808  m_MidiClient->doEvents();
1809  }
1810  }
1811  }
1812  catch (...)
1813  {
1814  qWarning() << "exception in input thread";
1815  }
1816  }
1817 }
1818 
1823 {
1824  snd_seq_client_info_malloc(&m_Info);
1825 }
1826 
1832 {
1833  snd_seq_client_info_malloc(&m_Info);
1834  snd_seq_client_info_copy(m_Info, other.m_Info);
1835  m_Ports = other.m_Ports;
1836 }
1837 
1842 ClientInfo::ClientInfo(snd_seq_client_info_t* other)
1843 {
1844  snd_seq_client_info_malloc(&m_Info);
1845  snd_seq_client_info_copy(m_Info, other);
1846 }
1847 
1854 {
1855  snd_seq_client_info_malloc(&m_Info);
1856  snd_seq_get_any_client_info(seq->getHandle(), id, m_Info);
1857 }
1858 
1863 {
1864  freePorts();
1865  snd_seq_client_info_free(m_Info);
1866 }
1867 
1872 ClientInfo*
1874 {
1875  return new ClientInfo(m_Info);
1876 }
1877 
1883 ClientInfo&
1885 {
1886  snd_seq_client_info_copy(m_Info, other.m_Info);
1887  m_Ports = other.m_Ports;
1888  return *this;
1889 }
1890 
1895 int
1897 {
1898  return snd_seq_client_info_get_client(m_Info);
1899 }
1900 
1905 snd_seq_client_type_t
1907 {
1908  return snd_seq_client_info_get_type(m_Info);
1909 }
1910 
1915 QString
1917 {
1918  return QString(snd_seq_client_info_get_name(m_Info));
1919 }
1920 
1925 bool
1927 {
1928  return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0);
1929 }
1930 
1935 bool
1937 {
1938  return (snd_seq_client_info_get_error_bounce(m_Info) != 0);
1939 }
1940 
1946 const unsigned char*
1948 {
1949  return snd_seq_client_info_get_event_filter(m_Info);
1950 }
1951 
1956 int
1958 {
1959  return snd_seq_client_info_get_num_ports(m_Info);
1960 }
1961 
1966 int
1968 {
1969  return snd_seq_client_info_get_event_lost(m_Info);
1970 }
1971 
1976 void
1978 {
1979  snd_seq_client_info_set_client(m_Info, client);
1980 }
1981 
1986 void
1987 ClientInfo::setName(QString name)
1988 {
1989  snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data());
1990 }
1991 
1996 void
1998 {
1999  snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0);
2000 }
2001 
2006 void
2008 {
2009  snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0);
2010 }
2011 
2017 void
2018 ClientInfo::setEventFilter(unsigned char *filter)
2019 {
2020  snd_seq_client_info_set_event_filter(m_Info, filter);
2021 }
2022 
2027 void
2029 {
2030  PortInfo info;
2031  freePorts();
2032  info.setClient(getClientId());
2033  info.setClientName(getName());
2034  info.setPort(-1);
2035  while (snd_seq_query_next_port(seq->getHandle(), info.m_Info) >= 0) {
2036  info.readSubscribers(seq);
2037  m_Ports.append(info);
2038  }
2039 }
2040 
2044 void
2046 {
2047  m_Ports.clear();
2048 }
2049 
2056 {
2057  PortInfoList lst = m_Ports; // copy
2058  return lst;
2059 }
2060 
2065 int
2067 {
2068  return snd_seq_client_info_sizeof();
2069 }
2070 
2071 #if SND_LIB_VERSION > 0x010010
2072 
2077 void
2078 ClientInfo::addFilter(int eventType)
2079 {
2080  snd_seq_client_info_event_filter_add(m_Info, eventType);
2081 }
2082 
2088 bool
2089 ClientInfo::isFiltered(int eventType)
2090 {
2091  return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0);
2092 }
2093 
2097 void
2098 ClientInfo::clearFilter()
2099 {
2100  snd_seq_client_info_event_filter_clear(m_Info);
2101 }
2102 
2107 void
2108 ClientInfo::removeFilter(int eventType)
2109 {
2110  snd_seq_client_info_event_filter_del(m_Info, eventType);
2111 }
2112 #endif
2113 
2118 {
2119  snd_seq_system_info_malloc(&m_Info);
2120 }
2121 
2127 {
2128  snd_seq_system_info_malloc(&m_Info);
2129  snd_seq_system_info_copy(m_Info, other.m_Info);
2130 }
2131 
2136 SystemInfo::SystemInfo(snd_seq_system_info_t* other)
2137 {
2138  snd_seq_system_info_malloc(&m_Info);
2139  snd_seq_system_info_copy(m_Info, other);
2140 }
2141 
2147 {
2148  snd_seq_system_info_malloc(&m_Info);
2149  snd_seq_system_info(seq->getHandle(), m_Info);
2150 }
2151 
2156 {
2157  snd_seq_system_info_free(m_Info);
2158 }
2159 
2164 SystemInfo*
2166 {
2167  return new SystemInfo(m_Info);
2168 }
2169 
2175 SystemInfo&
2177 {
2178  snd_seq_system_info_copy(m_Info, other.m_Info);
2179  return *this;
2180 }
2181 
2187 {
2188  return snd_seq_system_info_get_clients(m_Info);
2189 }
2190 
2196 {
2197  return snd_seq_system_info_get_ports(m_Info);
2198 }
2199 
2205 {
2206  return snd_seq_system_info_get_queues(m_Info);
2207 }
2208 
2214 {
2215  return snd_seq_system_info_get_channels(m_Info);
2216 }
2217 
2223 {
2224  return snd_seq_system_info_get_cur_queues(m_Info);
2225 }
2226 
2232 {
2233  return snd_seq_system_info_get_cur_clients(m_Info);
2234 }
2235 
2241 {
2242  return snd_seq_system_info_sizeof();
2243 }
2244 
2249 {
2250  snd_seq_client_pool_malloc(&m_Info);
2251 }
2252 
2258 {
2259  snd_seq_client_pool_malloc(&m_Info);
2260  snd_seq_client_pool_copy(m_Info, other.m_Info);
2261 }
2262 
2267 PoolInfo::PoolInfo(snd_seq_client_pool_t* other)
2268 {
2269  snd_seq_client_pool_malloc(&m_Info);
2270  snd_seq_client_pool_copy(m_Info, other);
2271 }
2272 
2278 {
2279  snd_seq_client_pool_malloc(&m_Info);
2280  snd_seq_get_client_pool(seq->getHandle(), m_Info);
2281 }
2282 
2287 {
2288  snd_seq_client_pool_free(m_Info);
2289 }
2290 
2295 PoolInfo*
2297 {
2298  return new PoolInfo(m_Info);
2299 }
2300 
2307 {
2308  snd_seq_client_pool_copy(m_Info, other.m_Info);
2309  return *this;
2310 }
2311 
2316 int
2318 {
2319  return snd_seq_client_pool_get_client(m_Info);
2320 }
2321 
2326 int
2328 {
2329  return snd_seq_client_pool_get_input_free(m_Info);
2330 }
2331 
2336 int
2338 {
2339  return snd_seq_client_pool_get_input_pool(m_Info);
2340 }
2341 
2346 int
2348 {
2349  return snd_seq_client_pool_get_output_free(m_Info);
2350 }
2351 
2356 int
2358 {
2359  return snd_seq_client_pool_get_output_pool(m_Info);
2360 }
2361 
2367 int
2369 {
2370  return snd_seq_client_pool_get_output_room(m_Info);
2371 }
2372 
2377 void
2379 {
2380  snd_seq_client_pool_set_input_pool(m_Info, size);
2381 }
2382 
2387 void
2389 {
2390  snd_seq_client_pool_set_output_pool(m_Info, size);
2391 }
2392 
2399 void
2401 {
2402  snd_seq_client_pool_set_output_room(m_Info, size);
2403 }
2404 
2409 int
2411 {
2412  return snd_seq_client_pool_sizeof();
2413 }
2414 
2415 #if SND_LIB_VERSION > 0x010004
2416 
2421 QString
2422 getRuntimeALSALibraryVersion()
2423 {
2424  return QString(snd_asoundlib_version());
2425 }
2426 
2432 int
2433 getRuntimeALSALibraryNumber()
2434 {
2435  QRegExp rx("(\\d+)");
2436  QString str = getRuntimeALSALibraryVersion();
2437  bool ok;
2438  int pos = 0, result = 0, j = 0;
2439  while ((pos = rx.indexIn(str, pos)) != -1 && j < 3) {
2440  int v = rx.cap(1).toInt(&ok);
2441  if (ok) {
2442  result <<= 8;
2443  result += v;
2444  }
2445  pos += rx.matchedLength();
2446  j++;
2447  }
2448  return result;
2449 }
2450 #endif // SND_LIB_VERSION > 0x010004
2451 
2457 QString
2459 {
2460  QRegExp rx(".*Driver Version.*([\\d\\.]+).*");
2461  QString s;
2462  QFile f("/proc/asound/version");
2463  if (f.open(QFile::ReadOnly)) {
2464  QTextStream str(&f);
2465  if (rx.exactMatch(str.readLine().trimmed()))
2466  s = rx.cap(1);
2467  }
2468  return s;
2469 }
2470 
2476 int
2478 {
2479  QRegExp rx("(\\d+)");
2480  QString str = getRuntimeALSADriverVersion();
2481  bool ok;
2482  int pos = 0, result = 0, j = 0;
2483  while ((pos = rx.indexIn(str, pos)) != -1 && j < 3) {
2484  int v = rx.cap(1).toInt(&ok);
2485  if (ok) {
2486  result <<= 8;
2487  result += v;
2488  }
2489  pos += rx.matchedLength();
2490  j++;
2491  }
2492  return result;
2493 }
2494 
2495 } /* namespace drumstick */
drumstick::PoolInfo::getInputPool
int getInputPool()
Gets the input pool size.
Definition: alsaclient.cpp:2337
drumstick::getRuntimeALSADriverNumber
int getRuntimeALSADriverNumber()
Gets the runtime ALSA drivers version number.
Definition: alsaclient.cpp:2477
drumstick::MidiClient::setEventsEnabled
void setEventsEnabled(const bool bEnabled)
Enables the notification of received SequencerEvent instances to the listeners registered with addLis...
Definition: alsaclient.cpp:1308
drumstick::MidiClient::output
void output(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event using the library output buffer.
Definition: alsaclient.cpp:988
drumstick::MidiClient::SequencerInputThread::stop
void stop()
Stops the input thread.
Definition: alsaclient.cpp:1712
QObject
The QObject class is the base class of all Qt objects.
CHECK_WARNING
#define CHECK_WARNING(x)
This macro calls the check warning function.
Definition: drumstickcommon.h:145
drumstick::MidiClient::~MidiClient
virtual ~MidiClient()
Destructor.
Definition: alsaclient.cpp:267
drumstick::MidiClient::extractOutput
SequencerEvent * extractOutput()
Extracts (and removes) the first event in the output buffer.
Definition: alsaclient.cpp:1461
drumstick::MidiClient::synchronizeOutput
void synchronizeOutput()
Wait until all sent events are processed.
Definition: alsaclient.cpp:1081
drumstick::MidiClient::dropInputBuffer
void dropInputBuffer()
Remove all events on user-space input buffer.
Definition: alsaclient.cpp:1413
drumstick::ClientInfo::getNumPorts
int getNumPorts()
Gets the client's port count.
Definition: alsaclient.cpp:1957
drumstick::PoolInfo::getClientId
int getClientId()
Gets the client ID for this object.
Definition: alsaclient.cpp:2317
drumstick::ClientInfo::setName
void setName(QString name)
Sets the client name.
Definition: alsaclient.cpp:1987
drumstick::MidiClient::getAvailableOutputs
PortInfoList getAvailableOutputs()
Gets the available user output ports in the system.
Definition: alsaclient.cpp:1271
drumstick::MidiClient::createSimplePort
int createSimplePort(const char *name, unsigned int caps, unsigned int type)
Create an ALSA sequencer port, without using MidiPort.
Definition: alsaclient.cpp:1587
drumstick::MidiClient::setErrorBounce
void setErrorBounce(bool newValue)
Sets the error-bounce usage of the client.
Definition: alsaclient.cpp:970
drumstick::MidiClient::open
void open(const QString deviceName="default", const int openMode=SND_SEQ_OPEN_DUPLEX, const bool blockMode=false)
Open the sequencer device.
Definition: alsaclient.cpp:388
drumstick::MidiClient::connectTo
void connectTo(int myport, int client, int port)
Subscribe one port to another arbitrary sequencer client:port.
Definition: alsaclient.cpp:1624
drumstick::MidiClient::eventReceived
void eventReceived(SequencerEvent *ev)
Signal emitted when an event is received.
drumstick::MidiClient::getBlockMode
bool getBlockMode()
Returns the last block mode used in open()
Definition: alsaclient.cpp:317
drumstick::MidiClient::getPollDescriptorsCount
int getPollDescriptorsCount(short events)
Returns the number of poll descriptors.
Definition: alsaclient.cpp:1518
drumstick::MidiClient::createQueue
MidiQueue * createQueue()
Create and return a new MidiQueue associated to this client.
Definition: alsaclient.cpp:1105
drumstick::MidiClient::close
void close()
Close the sequencer device.
Definition: alsaclient.cpp:445
drumstick::MidiClient::isOpened
bool isOpened()
Returns true if the sequencer is opened.
Definition: alsaclient.cpp:293
drumstick::PoolInfo::PoolInfo
PoolInfo()
Default constructor.
Definition: alsaclient.cpp:2248
drumstick::MidiClient::getThisClientInfo
ClientInfo & getThisClientInfo()
Gets the ClientInfo object holding data about this client.
Definition: alsaclient.cpp:770
drumstick::MidiPort::getPortInfo
PortInfo * getPortInfo()
Gets the PortInfo object pointer.
Definition: alsaport.cpp:570
drumstick::ClientInfo::getSizeOfInfo
int getSizeOfInfo() const
Gets the size of the internal object.
Definition: alsaclient.cpp:2066
drumstick::MidiClient::addListener
void addListener(QObject *listener)
Adds a QObject to the listeners list.
Definition: alsaclient.cpp:1285
drumstick::MidiClient::parseAddress
bool parseAddress(const QString &straddr, snd_seq_addr &result)
Parse a text address representation, returning an ALSA address record.
Definition: alsaclient.cpp:1665
drumstick::ControllerEvent
Event representing a MIDI control change event.
Definition: alsaevent.h:283
drumstick::MidiClient::disconnectTo
void disconnectTo(int myport, int client, int port)
Unsubscribe one port to another arbitrary sequencer client:port.
Definition: alsaclient.cpp:1648
drumstick::MidiClient::getHandle
snd_seq_t * getHandle()
Returns the sequencer handler managed by ALSA.
Definition: alsaclient.cpp:285
drumstick::MidiClient::getBroadcastFilter
bool getBroadcastFilter()
Gets the broadcast filter usage of the client.
Definition: alsaclient.cpp:936
drumstick::MidiClient::doEvents
void doEvents()
Dispatch the events received from the Sequencer.
Definition: alsaclient.cpp:581
drumstick::MidiClient::createPort
MidiPort * createPort()
Create and attach a new MidiPort instance to this client.
Definition: alsaclient.cpp:858
drumstick::MidiClient::stopSequencerInput
void stopSequencerInput()
Stops reading events from the ALSA sequencer.
Definition: alsaclient.cpp:710
drumstick::MidiClient::portAttach
void portAttach(MidiPort *port)
Attach a MidiPort instance to this client.
Definition: alsaclient.cpp:870
drumstick::MidiClient::setOutputBufferSize
void setOutputBufferSize(size_t newSize)
Sets the size of the library output buffer for the ALSA client.
Definition: alsaclient.cpp:477
drumstick::MidiClient::updateAvailablePorts
void updateAvailablePorts()
Update the internal lists of user ports.
Definition: alsaclient.cpp:1244
drumstick::SysExEvent
Event representing a MIDI system exclusive event.
Definition: alsaevent.h:401
drumstick::MidiClient::outputPending
int outputPending()
Returns the size of pending events on the output buffer.
Definition: alsaclient.cpp:1476
drumstick::MidiClient::useQueue
MidiQueue * useQueue(int queue_id)
Create a new MidiQueue instance using a queue already existing in the system, associating it to the c...
Definition: alsaclient.cpp:1138
drumstick::PortInfo::setPort
void setPort(int port)
Set the port number.
Definition: alsaport.cpp:285
drumstick::SequencerEvent
Base class for the event's hierarchy.
Definition: alsaevent.h:53
alsaevent.h
Classes managing ALSA Sequencer events.
drumstick::ClientEvent
ALSA Event representing a change on some ALSA sequencer client on the system.
Definition: alsaevent.h:554
drumstick::MidiClient::realTimeInputEnabled
bool realTimeInputEnabled()
Return the real-time priority setting for the MIDI input thread.
Definition: alsaclient.cpp:360
drumstick::SystemInfo::~SystemInfo
virtual ~SystemInfo()
Destructor.
Definition: alsaclient.cpp:2155
drumstick::ClientInfo::freePorts
void freePorts()
Release the ports list.
Definition: alsaclient.cpp:2045
drumstick::ClientInfo::getClientType
snd_seq_client_type_t getClientType()
Gets the client's type.
Definition: alsaclient.cpp:1906
drumstick::MidiClient::freeClients
void freeClients()
Releases the list of ALSA sequencer's clients.
Definition: alsaclient.cpp:747
drumstick::ClientInfo::setClient
void setClient(int client)
Sets the client identifier number.
Definition: alsaclient.cpp:1977
drumstick::ClientInfo::getEventFilter
const unsigned char * getEventFilter() __attribute__((deprecated))
Gets the client's event filter.
Definition: alsaclient.cpp:1947
drumstick::MidiClient::setPoolOutputRoom
void setPoolOutputRoom(int size)
Sets the room size of the client's output pool.
Definition: alsaclient.cpp:1393
drumstick::ClientInfo::~ClientInfo
virtual ~ClientInfo()
Destructor.
Definition: alsaclient.cpp:1862
drumstick::ClientInfo::setBroadcastFilter
void setBroadcastFilter(bool val)
Sets the broadcast filter.
Definition: alsaclient.cpp:1997
drumstick::MidiClient::_setClientName
void _setClientName(const char *name)
Sets the client name.
Definition: alsaclient.cpp:1574
drumstick::MidiClient::getPoolInfo
PoolInfo & getPoolInfo()
Gets a PoolInfo instance with an updated state of the client memory pool.
Definition: alsaclient.cpp:1331
drumstick::MidiClient::getMidiPorts
MidiPortList getMidiPorts() const
Gets the list of MidiPort instances belonging to this client.
Definition: alsaclient.cpp:848
drumstick::MidiClient::getInputBufferSize
size_t getInputBufferSize()
Gets the size of the library input buffer for the ALSA client.
Definition: alsaclient.cpp:493
drumstick::PortInfo::readSubscribers
void readSubscribers(MidiClient *seq)
Obtains the port subscribers lists.
Definition: alsaport.cpp:430
drumstick::PoolInfo::setOutputPool
void setOutputPool(int size)
Sets the output pool size.
Definition: alsaclient.cpp:2388
drumstick::SystemInfo::SystemInfo
SystemInfo()
Default constructor.
Definition: alsaclient.cpp:2117
drumstick::getRuntimeALSADriverVersion
QString getRuntimeALSADriverVersion()
Gets the runtime ALSA drivers version string.
Definition: alsaclient.cpp:2458
drumstick::ProgramChangeEvent
Event representing a MIDI program change event.
Definition: alsaevent.h:322
drumstick::ClientInfo::getErrorBounce
bool getErrorBounce()
Gets the client's error bounce.
Definition: alsaclient.cpp:1936
drumstick::SystemInfo::getMaxClients
int getMaxClients()
Get the system's maximum number of clients.
Definition: alsaclient.cpp:2186
drumstick::MidiClient
Client management.
Definition: alsaclient.h:198
drumstick::MidiClient::setHandler
void setHandler(SequencerEventHandler *handler)
Sets a sequencer event handler enabling the callback delivery mode.
Definition: alsaclient.cpp:333
drumstick::MidiPort::setMidiClient
void setMidiClient(MidiClient *seq)
Sets the MidiClient.
Definition: alsaport.cpp:599
drumstick::MidiClient::drainOutput
void drainOutput(bool async=false, int timeout=-1)
Drain the library output buffer.
Definition: alsaclient.cpp:1058
drumstick::SystemInfo::getSizeOfInfo
int getSizeOfInfo() const
Get the system's info object size.
Definition: alsaclient.cpp:2240
drumstick::PoolInfo
Sequencer Pool information.
Definition: alsaclient.h:138
drumstick::PortInfo::getClient
int getClient()
Gets the client number.
Definition: alsaport.cpp:144
alsaqueue.h
Classes managing ALSA Sequencer queues.
drumstick::MidiClient::setClientName
void setClientName(QString const &newName)
Changes the public name of the ALSA sequencer client.
Definition: alsaclient.cpp:835
drumstick::PortEvent
ALSA Event representing a change on some ALSA sequencer port on the system.
Definition: alsaevent.h:569
drumstick::MidiClient::setPoolInfo
void setPoolInfo(const PoolInfo &info)
Applies (updates) the client's PoolInfo data into the system.
Definition: alsaclient.cpp:1342
drumstick::PoolInfo::getOutputPool
int getOutputPool()
Gets the output pool size.
Definition: alsaclient.cpp:2357
drumstick::ClientInfo::setEventFilter
void setEventFilter(unsigned char *filter) __attribute__((deprecated))
Sets the event filter.
Definition: alsaclient.cpp:2018
drumstick::SystemInfo::getMaxPorts
int getMaxPorts()
Get the system's maximum number of ports.
Definition: alsaclient.cpp:2195
drumstick::SubscriptionEvent
ALSA Event representing a subscription between two ALSA clients and ports.
Definition: alsaevent.h:528
drumstick::NoteEvent
Class representing a note event with duration.
Definition: alsaevent.h:211
drumstick::PoolInfo::setInputPool
void setInputPool(int size)
Set the input pool size.
Definition: alsaclient.cpp:2378
drumstick::MidiClient::inputPending
int inputPending(bool fetch)
Gets the size of the events on the input buffer.
Definition: alsaclient.cpp:1495
drumstick::ClientInfo::getPorts
PortInfoList getPorts() const
Gets the ports list.
Definition: alsaclient.cpp:2055
drumstick::MidiClient::getOpenMode
int getOpenMode()
Returns the last open mode used in open()
Definition: alsaclient.cpp:309
drumstick::PoolInfo::getInputFree
int getInputFree()
Gets the available size on input pool.
Definition: alsaclient.cpp:2327
drumstick::PoolInfo::getOutputFree
int getOutputFree()
Gets the available size on output pool.
Definition: alsaclient.cpp:2347
drumstick::MidiClient::setRealTimeInput
void setRealTimeInput(bool enabled)
Enables real-time priority for the MIDI input thread.
Definition: alsaclient.cpp:347
drumstick::SystemInfo::getCurrentClients
int getCurrentClients()
Get the system's current number of clients.
Definition: alsaclient.cpp:2231
drumstick::PoolInfo::getOutputRoom
int getOutputRoom()
Gets the output room size.
Definition: alsaclient.cpp:2368
drumstick::MidiClient::getClientName
QString getClientName()
Gets the client's public name.
Definition: alsaclient.cpp:806
drumstick::PortInfoList
QList< PortInfo > PortInfoList
List of port information objects.
Definition: alsaport.h:111
drumstick::PoolInfo::setOutputRoom
void setOutputRoom(int size)
Sets the output room size.
Definition: alsaclient.cpp:2400
drumstick::MidiClient::SequencerInputThread::stopped
bool stopped()
Returns true or false depending on the input thread state.
Definition: alsaclient.cpp:1702
drumstick::ClientInfo::readPorts
void readPorts(MidiClient *seq)
Read the client ports.
Definition: alsaclient.cpp:2028
drumstick::SystemInfo::operator=
SystemInfo & operator=(const SystemInfo &other)
Assignment operator.
Definition: alsaclient.cpp:2176
drumstick::MidiClient::deleteSimplePort
void deleteSimplePort(int port)
Remove an ALSA sequencer port.
Definition: alsaclient.cpp:1600
drumstick::ClientInfo::getEventLost
int getEventLost()
Gets the number of lost events.
Definition: alsaclient.cpp:1967
drumstick::MidiClient::setThisClientInfo
void setThisClientInfo(const ClientInfo &val)
Sets the data supplied by the ClientInfo object into the ALSA sequencer client.
Definition: alsaclient.cpp:784
drumstick::MidiClient::getAvailableQueues
QList< int > getAvailableQueues()
Get a list of the existing queues.
Definition: alsaclient.cpp:1189
drumstick::ClientInfo::getBroadcastFilter
bool getBroadcastFilter()
Gets the client's broadcast filter.
Definition: alsaclient.cpp:1926
drumstick::SequencerEventHandler
Sequencer events handler.
Definition: alsaclient.h:175
drumstick::MidiClient::getSystemInfo
SystemInfo & getSystemInfo()
Gets a SystemInfo instance with the updated state of the system.
Definition: alsaclient.cpp:1320
drumstick::MidiClient::getOutputBufferSize
size_t getOutputBufferSize()
Gets the size of the library output buffer for the ALSA client.
Definition: alsaclient.cpp:463
drumstick::ClientInfo::setErrorBounce
void setErrorBounce(bool val)
Sets the error bounce.
Definition: alsaclient.cpp:2007
drumstick::MidiClient::getQueue
MidiQueue * getQueue()
Get the MidiQueue instance associated to this client.
Definition: alsaclient.cpp:1092
drumstick::MidiClient::SequencerInputThread
This class manages event input from the ALSA sequencer.
Definition: alsaclient.cpp:186
drumstick::RemoveEvents
Auxiliary class to remove events from an ALSA queue.
Definition: alsaevent.h:586
drumstick::MidiClient::setPoolOutput
void setPoolOutput(int size)
Sets the size of the client's output pool.
Definition: alsaclient.cpp:1383
drumstick::MidiClient::resetPoolInput
void resetPoolInput()
Resets the client input pool.
Definition: alsaclient.cpp:1353
drumstick::MidiClient::getAvailableClients
ClientInfoList getAvailableClients()
Gets the list of clients from the ALSA sequencer.
Definition: alsaclient.cpp:757
drumstick::MidiClient::getSequencerType
snd_seq_type_t getSequencerType()
Returns the type snd_seq_type_t of the given sequencer handle.
Definition: alsaclient.cpp:555
CHECK_ERROR
#define CHECK_ERROR(x)
This macro calls the check error function.
Definition: drumstickcommon.h:139
drumstick::MidiClient::startSequencerInput
void startSequencerInput()
Starts reading events from the ALSA sequencer.
Definition: alsaclient.cpp:697
drumstick::ValueEvent
Generic event having a value property.
Definition: alsaevent.h:494
drumstick::MidiClient::MidiClient
MidiClient(QObject *parent=0)
Constructor.
Definition: alsaclient.cpp:257
drumstick::MidiClient::setBroadcastFilter
void setBroadcastFilter(bool newValue)
Sets the broadcast filter usage of the client.
Definition: alsaclient.cpp:947
drumstick::SystemInfo::getCurrentQueues
int getCurrentQueues()
Get the system's current number of queues.
Definition: alsaclient.cpp:2222
drumstick::MidiClient::resetPoolOutput
void resetPoolOutput()
Resets the client output pool.
Definition: alsaclient.cpp:1363
drumstick::MidiClient::dropOutput
void dropOutput()
Clears the client's output buffer and and remove events in sequencer queue.
Definition: alsaclient.cpp:1426
drumstick::MidiClient::setInputBufferSize
void setInputBufferSize(size_t newSize)
Sets the size of the library input buffer for the ALSA client.
Definition: alsaclient.cpp:507
drumstick::KeyPressEvent
Event representing a MIDI key pressure, or polyphonic after-touch event.
Definition: alsaevent.h:268
drumstick::MidiClient::connectFrom
void connectFrom(int myport, int client, int port)
Subscribe one port from another arbitrary sequencer client:port.
Definition: alsaclient.cpp:1612
drumstick::MidiClient::dropOutputBuffer
void dropOutputBuffer()
Removes all events on the library output buffer.
Definition: alsaclient.cpp:1439
drumstick::ClientInfo::getClientId
int getClientId()
Gets the client's numeric identifier.
Definition: alsaclient.cpp:1896
drumstick::MidiPort::attach
void attach(MidiClient *seq)
Attach the port to a MidiClient instance.
Definition: alsaport.cpp:1096
drumstick::MidiClient::removeEvents
void removeEvents(const RemoveEvents *spec)
Removes events on input/output buffers and pools.
Definition: alsaclient.cpp:1451
drumstick::PortInfo
Port information container.
Definition: alsaport.h:40
drumstick::MidiClient::pollDescriptors
int pollDescriptors(struct pollfd *pfds, unsigned int space, short events)
Get poll descriptors.
Definition: alsaclient.cpp:1537
drumstick::PortInfo::getPort
int getPort()
Gets the port number.
Definition: alsaport.cpp:155
drumstick::ClientInfo::operator=
ClientInfo & operator=(const ClientInfo &other)
Assignment operator.
Definition: alsaclient.cpp:1884
drumstick::PortInfo::getCapability
unsigned int getCapability()
Gets the capabilities bitmap.
Definition: alsaport.cpp:188
drumstick::MidiClient::SequencerInputThread::run
virtual void run()
Main input thread process loop.
Definition: alsaclient.cpp:1791
alsaclient.h
Classes managing ALSA Sequencer clients.
drumstick::MidiClient::detachAllPorts
void detachAllPorts()
Detach all the ports belonging to this client.
Definition: alsaclient.cpp:908
drumstick::ClientInfo::ClientInfo
ClientInfo()
Default constructor.
Definition: alsaclient.cpp:1822
drumstick::MidiPortList
QList< MidiPort * > MidiPortList
List of Ports instances.
Definition: alsaport.h:214
drumstick::MidiClient::pollDescriptorsRevents
unsigned short pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
Gets the number of returned events from poll descriptors.
Definition: alsaclient.cpp:1550
drumstick::SequencerEvent::getHandle
snd_seq_event_t * getHandle()
Gets the handle of the event.
Definition: alsaevent.h:122
drumstick::MidiClient::getDeviceName
QString getDeviceName()
Returns the name of the sequencer device.
Definition: alsaclient.cpp:301
drumstick::PitchBendEvent
Event representing a MIDI bender, or pitch wheel event.
Definition: alsaevent.h:341
drumstick::PoolInfo::operator=
PoolInfo & operator=(const PoolInfo &other)
Assignment operator.
Definition: alsaclient.cpp:2306
drumstick::MidiQueue
Queue management.
Definition: alsaqueue.h:188
drumstick::MidiClient::getErrorBounce
bool getErrorBounce()
Get the error-bounce usage of the client.
Definition: alsaclient.cpp:959
drumstick::MidiPort
Port management.
Definition: alsaport.h:119
drumstick::MidiClient::setPoolInput
void setPoolInput(int size)
Sets the size of the client's input pool.
Definition: alsaclient.cpp:1373
drumstick::MidiClient::readClients
void readClients()
Reads the ALSA sequencer's clients list.
Definition: alsaclient.cpp:731
drumstick::ClientInfo::clone
ClientInfo * clone()
Clone the client info object.
Definition: alsaclient.cpp:1873
drumstick::ClientInfoList
QList< ClientInfo > ClientInfoList
List of sequencer client information.
Definition: alsaclient.h:98
drumstick::MidiClient::removeListener
void removeListener(QObject *listener)
Removes a QObject listener from the listeners list.
Definition: alsaclient.cpp:1296
drumstick::NoteOnEvent
Event representing a note-on MIDI event.
Definition: alsaevent.h:238
drumstick::SystemInfo
System information.
Definition: alsaclient.h:107
drumstick::PortInfo::setClientName
void setClientName(QString name)
Sets the client name.
Definition: alsaport.h:98
drumstick::MidiClient::applyClientInfo
void applyClientInfo()
This internal method applies the ClientInfo data to the ALSA sequencer client.
Definition: alsaclient.cpp:794
drumstick::MidiClient::dropInput
void dropInput()
Clears the client's input buffer and and remove events in sequencer queue.
Definition: alsaclient.cpp:1403
drumstick::ClientInfo::getName
QString getName()
Gets the client's name.
Definition: alsaclient.cpp:1916
drumstick::QueueControlEvent
ALSA Event representing a queue control command.
Definition: alsaevent.h:455
QThread
The QThread class provides platform-independent threads.
drumstick::MidiClient::getClientId
int getClientId()
Gets the client ID.
Definition: alsaclient.cpp:545
drumstick::PoolInfo::clone
PoolInfo * clone()
Clone the pool info obeject.
Definition: alsaclient.cpp:2296
drumstick::TempoEvent
ALSA Event representing a tempo change for an ALSA queue.
Definition: alsaevent.h:513
drumstick::SystemInfo::getMaxChannels
int getMaxChannels()
Get the system's maximum number of channels.
Definition: alsaclient.cpp:2213
drumstick::NoteOffEvent
Event representing a note-off MIDI event.
Definition: alsaevent.h:253
drumstick::MidiClient::outputBuffer
void outputBuffer(SequencerEvent *ev)
Output an event using the library output buffer, without draining the buffer.
Definition: alsaclient.cpp:1042
drumstick::MidiClient::getAvailableInputs
PortInfoList getAvailableInputs()
Gets the available user input ports in the system.
Definition: alsaclient.cpp:1259
drumstick::MidiClient::getEventsEnabled
bool getEventsEnabled() const
Returns true if the events mode of delivery has been enabled.
Definition: alsaclient.cpp:325
drumstick::PoolInfo::~PoolInfo
virtual ~PoolInfo()
Destructor.
Definition: alsaclient.cpp:2286
drumstick::SystemInfo::clone
SystemInfo * clone()
Clone the system info object.
Definition: alsaclient.cpp:2165
drumstick::MidiClient::portDetach
void portDetach(MidiPort *port)
Detach a MidiPort instance from this client.
Definition: alsaclient.cpp:883
drumstick::MidiClient::setBlockMode
void setBlockMode(bool newValue)
Change the blocking mode of the client.
Definition: alsaclient.cpp:524
drumstick::MidiClient::outputDirect
void outputDirect(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event directly to the sequencer.
Definition: alsaclient.cpp:1016
drumstick::MidiClient::disconnectFrom
void disconnectFrom(int myport, int client, int port)
Unsubscribe one port from another arbitrary sequencer client:port.
Definition: alsaclient.cpp:1636
drumstick::ChanPressEvent
Event representing a MIDI channel pressure or after-touch event.
Definition: alsaevent.h:360
drumstick::SystemInfo::getMaxQueues
int getMaxQueues()
Get the system's maximum number of queues.
Definition: alsaclient.cpp:2204
drumstick::MidiClient::_getDeviceName
const char * _getDeviceName()
Gets the internal sequencer device name.
Definition: alsaclient.cpp:1564
drumstick::MidiClient::addEventFilter
void addEventFilter(int evtype)
Add an event filter to the client.
Definition: alsaclient.cpp:925
drumstick::MidiClient::getQueueId
int getQueueId(const QString &name)
Gets the queue's numeric identifier corresponding to the provided name.
Definition: alsaclient.cpp:1507
drumstick::PoolInfo::getSizeOfInfo
int getSizeOfInfo() const
Gets the size of the client pool object.
Definition: alsaclient.cpp:2410
drumstick::MidiClient::filterPorts
PortInfoList filterPorts(unsigned int filter)
Gets a list of the available user ports in the system, filtered by the given bitmap of desired capabi...
Definition: alsaclient.cpp:1213
drumstick::PortInfo::setClient
void setClient(int client)
Sets the client number.
Definition: alsaport.cpp:274
drumstick::ClientInfo
Client information.
Definition: alsaclient.h:50