drumstick  0.5.0
alsaclient.cpp
Go to the documentation of this file.
1 /*
2  MIDI Sequencer C++ library
3  Copyright (C) 2006-2010, 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 along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 
20 #include "alsaclient.h"
21 #include "alsaqueue.h"
22 #include "alsaevent.h"
23 #include <QFile>
24 #include <QRegExp>
25 #include <QThread>
26 #include <QReadLocker>
27 #include <QWriteLocker>
28 #if defined(RTKIT_SUPPORT)
29 #include <QDBusConnection>
30 #include <QDBusInterface>
31 #include <sys/types.h>
32 #include <sys/syscall.h>
33 #include <sys/resource.h>
34 #endif
35 #include <pthread.h>
36 
37 #ifndef RLIMIT_RTTIME
38 #define RLIMIT_RTTIME 15
39 #endif
40 
41 #ifndef SCHED_RESET_ON_FORK
42 #define SCHED_RESET_ON_FORK 0x40000000
43 #endif
44 
45 #ifndef DEFAULT_INPUT_TIMEOUT
46 #define DEFAULT_INPUT_TIMEOUT 500
47 #endif
48 
66 namespace drumstick {
67 
330 {
331 public:
332  SequencerInputThread(MidiClient *seq, int timeout)
333  : QThread(),
334  m_MidiClient(seq),
335  m_Wait(timeout),
336  m_Stopped(false),
337  m_RealTime(true) {}
338  virtual ~SequencerInputThread() {}
339  virtual void run();
340  bool stopped();
341  void stop();
342  void setRealtimePriority();
343 
344  MidiClient *m_MidiClient;
345  int m_Wait;
346  bool m_Stopped;
347  bool m_RealTime;
348  QReadWriteLock m_mutex;
349 };
350 
367  QObject(parent),
368  m_eventsEnabled(false),
369  m_BlockMode(false),
370  m_NeedRefreshClientList(true),
371  m_OpenMode(SND_SEQ_OPEN_DUPLEX),
372  m_DeviceName("default"),
373  m_SeqHandle(NULL),
374  m_Thread(NULL),
375  m_Queue(NULL),
376  m_handler(NULL)
377 { }
378 
385 {
387  detachAllPorts();
388  if (m_Queue != NULL)
389  delete m_Queue;
390  close();
391  freeClients();
392  if (m_Thread != NULL)
393  delete m_Thread;
394 }
395 
405 {
406  if (m_Thread == 0) {
407  m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
408  m_Thread->m_RealTime = enable;
409  }
410 }
411 
418 {
419  if (m_Thread == 0)
420  return true;
421  return m_Thread->m_RealTime;
422 }
423 
444 void
445 MidiClient::open( const QString deviceName,
446  const int openMode,
447  const bool blockMode)
448 {
449  CHECK_ERROR( snd_seq_open( &m_SeqHandle, deviceName.toLocal8Bit().data(),
450  openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) );
451  CHECK_WARNING( snd_seq_get_client_info( m_SeqHandle, m_Info.m_Info ) );
452  m_DeviceName = deviceName;
453  m_OpenMode = openMode;
454  m_BlockMode = blockMode;
455 }
456 
477 void
478 MidiClient::open( snd_config_t* conf,
479  const QString deviceName,
480  const int openMode,
481  const bool blockMode )
482 {
483  CHECK_ERROR( snd_seq_open_lconf( &m_SeqHandle,
484  deviceName.toLocal8Bit().data(),
485  openMode,
486  blockMode ? 0 : SND_SEQ_NONBLOCK,
487  conf ));
488  CHECK_WARNING( snd_seq_get_client_info(m_SeqHandle, m_Info.m_Info));
489  m_DeviceName = deviceName;
490  m_OpenMode = openMode;
491  m_BlockMode = blockMode;
492 }
493 
501 void
503 {
504  if (m_SeqHandle != NULL) {
506  CHECK_WARNING(snd_seq_close(m_SeqHandle));
507  m_SeqHandle = NULL;
508  }
509 }
510 
519 size_t
521 {
522  return snd_seq_get_output_buffer_size(m_SeqHandle);
523 }
524 
533 void
535 {
536  if (getOutputBufferSize() != newSize) {
537  CHECK_WARNING(snd_seq_set_output_buffer_size(m_SeqHandle, newSize));
538  }
539 }
540 
549 size_t
551 {
552  return snd_seq_get_input_buffer_size(m_SeqHandle);
553 }
554 
563 void
565 {
566  if (getInputBufferSize() != newSize) {
567  CHECK_WARNING(snd_seq_set_input_buffer_size(m_SeqHandle, newSize));
568  }
569 }
570 
580 void
582 {
583  if (m_BlockMode != newValue)
584  {
585  m_BlockMode = newValue;
586  if (m_SeqHandle != NULL)
587  {
588  CHECK_WARNING(snd_seq_nonblock(m_SeqHandle, m_BlockMode ? 0 : 1));
589  }
590  }
591 }
592 
601 int
603 {
604  return CHECK_WARNING(snd_seq_client_id(m_SeqHandle));
605 }
606 
611 snd_seq_type_t
613 {
614  return snd_seq_type(m_SeqHandle);
615 }
616 
637 void
639 {
640  do {
641  int err = 0;
642  snd_seq_event_t* evp = NULL;
643  SequencerEvent* event = NULL;
644  err = snd_seq_event_input(m_SeqHandle, &evp);
645  if ((err >= 0) && (evp != NULL)) {
646  switch (evp->type) {
647 
648  case SND_SEQ_EVENT_NOTE:
649  event = new NoteEvent(evp);
650  break;
651 
652  case SND_SEQ_EVENT_NOTEON:
653  event = new NoteOnEvent(evp);
654  break;
655 
656  case SND_SEQ_EVENT_NOTEOFF:
657  event = new NoteOffEvent(evp);
658  break;
659 
660  case SND_SEQ_EVENT_KEYPRESS:
661  event = new KeyPressEvent(evp);
662  break;
663 
664  case SND_SEQ_EVENT_CONTROLLER:
665  case SND_SEQ_EVENT_CONTROL14:
666  case SND_SEQ_EVENT_REGPARAM:
667  case SND_SEQ_EVENT_NONREGPARAM:
668  event = new ControllerEvent(evp);
669  break;
670 
671  case SND_SEQ_EVENT_PGMCHANGE:
672  event = new ProgramChangeEvent(evp);
673  break;
674 
675  case SND_SEQ_EVENT_CHANPRESS:
676  event = new ChanPressEvent(evp);
677  break;
678 
679  case SND_SEQ_EVENT_PITCHBEND:
680  event = new PitchBendEvent(evp);
681  break;
682 
683  case SND_SEQ_EVENT_SYSEX:
684  event = new SysExEvent(evp);
685  break;
686 
687  case SND_SEQ_EVENT_PORT_SUBSCRIBED:
688  case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
689  event = new SubscriptionEvent(evp);
690  break;
691 
692  case SND_SEQ_EVENT_PORT_CHANGE:
693  case SND_SEQ_EVENT_PORT_EXIT:
694  case SND_SEQ_EVENT_PORT_START:
695  event = new PortEvent(evp);
696  m_NeedRefreshClientList = true;
697  break;
698 
699  case SND_SEQ_EVENT_CLIENT_CHANGE:
700  case SND_SEQ_EVENT_CLIENT_EXIT:
701  case SND_SEQ_EVENT_CLIENT_START:
702  event = new ClientEvent(evp);
703  m_NeedRefreshClientList = true;
704  break;
705 
706  case SND_SEQ_EVENT_SONGPOS:
707  case SND_SEQ_EVENT_SONGSEL:
708  case SND_SEQ_EVENT_QFRAME:
709  case SND_SEQ_EVENT_TIMESIGN:
710  case SND_SEQ_EVENT_KEYSIGN:
711  event = new ValueEvent(evp);
712  break;
713 
714  case SND_SEQ_EVENT_SETPOS_TICK:
715  case SND_SEQ_EVENT_SETPOS_TIME:
716  case SND_SEQ_EVENT_QUEUE_SKEW:
717  event = new QueueControlEvent(evp);
718  break;
719 
720  case SND_SEQ_EVENT_TEMPO:
721  event = new TempoEvent(evp);
722  break;
723 
724  default:
725  event = new SequencerEvent(evp);
726  break;
727  }
728  // first, process the callback (if any)
729  if (m_handler != NULL) {
730  m_handler->handleSequencerEvent(event->clone());
731  } else {
732  // second, process the event listeners
733  if (m_eventsEnabled) {
734  QObjectList::Iterator it;
735  for(it=m_listeners.begin(); it!=m_listeners.end(); ++it) {
736  QObject* sub = (*it);
737  QApplication::postEvent(sub, event->clone());
738  }
739  } else {
740  // finally, process signals
741  emit eventReceived(event->clone());
742  }
743  }
744  delete event;
745  }
746  }
747  while (snd_seq_event_input_pending(m_SeqHandle, 0) > 0);
748 }
749 
753 void
755 {
756  if (m_Thread == 0) {
757  m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
758  }
759  m_Thread->start( m_Thread->m_RealTime ?
760  QThread::TimeCriticalPriority : QThread::InheritPriority );
761 }
762 
766 void
768 {
769  int counter = 0;
770  if (m_Thread != 0) {
771  if (m_Thread->isRunning()) {
772  m_Thread->stop();
773  while (!m_Thread->wait(500) && (counter < 10)) {
774  counter++;
775  }
776  if (!m_Thread->isFinished()) {
777  m_Thread->terminate();
778  }
779  }
780  delete m_Thread;
781  }
782 }
783 
787 void
789 {
790  ClientInfo cInfo;
791  freeClients();
792  cInfo.setClient(-1);
793  while (snd_seq_query_next_client(m_SeqHandle, cInfo.m_Info) >= 0) {
794  cInfo.readPorts(this);
795  m_ClientList.append(cInfo);
796  }
797  m_NeedRefreshClientList = false;
798 }
799 
803 void
805 {
806  m_ClientList.clear();
807 }
808 
815 {
816  if (m_NeedRefreshClientList)
817  readClients();
818  ClientInfoList lst = m_ClientList; // copy
819  return lst;
820 }
821 
826 ClientInfo&
828 {
829  snd_seq_get_client_info(m_SeqHandle, m_Info.m_Info);
830  return m_Info;
831 }
832 
840 void
842 {
843  m_Info = val;
844  snd_seq_set_client_info(m_SeqHandle, m_Info.m_Info);
845 }
846 
850 void
852 {
853  if (m_SeqHandle != NULL) {
854  snd_seq_set_client_info(m_SeqHandle, m_Info.m_Info);
855  }
856 }
857 
862 QString
864 {
865  return m_Info.getName();
866 }
867 
873 QString
874 MidiClient::getClientName(const int clientId)
875 {
876  ClientInfoList::Iterator it;
877  if (m_NeedRefreshClientList)
878  readClients();
879  for (it = m_ClientList.begin(); it != m_ClientList.end(); ++it) {
880  if ((*it).getClientId() == clientId) {
881  return (*it).getName();
882  }
883  }
884  return QString();
885 }
886 
891 void
892 MidiClient::setClientName(QString const& newName)
893 {
894  if (newName != m_Info.getName()) {
895  m_Info.setName(newName);
896  applyClientInfo();
897  }
898 }
899 
906 {
907  return m_Ports;
908 }
909 
914 MidiPort*
916 {
917  MidiPort* port = new MidiPort(this);
918  port->attach(this);
919  return port;
920 }
921 
926 void
928 {
929  if (m_SeqHandle != NULL) {
930  CHECK_ERROR(snd_seq_create_port(m_SeqHandle, port->m_Info.m_Info));
931  m_Ports.push_back(port);
932  }
933 }
934 
939 void
941 {
942  if (m_SeqHandle != NULL) {
943  if(port->getPortInfo()->getClient() == getClientId())
944  {
945  return;
946  }
947  CHECK_ERROR(snd_seq_delete_port(m_SeqHandle, port->getPortInfo()->getPort()));
948  port->setMidiClient(NULL);
949 
950  MidiPortList::iterator it;
951  for(it = m_Ports.begin(); it != m_Ports.end(); ++it)
952  {
953  if ((*it)->getPortInfo()->getPort() == port->getPortInfo()->getPort())
954  {
955  m_Ports.erase(it);
956  break;
957  }
958  }
959  }
960 }
961 
966 {
967  if (m_SeqHandle != NULL) {
968  MidiPortList::iterator it;
969  for (it = m_Ports.begin(); it != m_Ports.end(); ++it) {
970  CHECK_ERROR(snd_seq_delete_port(m_SeqHandle, (*it)->getPortInfo()->getPort()));
971  (*it)->setMidiClient(NULL);
972  m_Ports.erase(it);
973  }
974  }
975 }
976 
981 void
983 {
984  snd_seq_set_client_event_filter(m_SeqHandle, evtype);
985 }
986 
992 bool
994 {
995  return m_Info.getBroadcastFilter();
996 }
997 
1003 void
1005 {
1006  m_Info.setBroadcastFilter(newValue);
1007  applyClientInfo();
1008 }
1009 
1015 bool
1017 {
1018  return m_Info.getErrorBounce();
1019 }
1020 
1026 void
1028 {
1029  m_Info.setErrorBounce(newValue);
1030  applyClientInfo();
1031 }
1032 
1044 void
1045 MidiClient::output(SequencerEvent* ev, bool async, int timeout)
1046 {
1047  int npfds;
1048  pollfd* pfds;
1049  if (async) {
1050  CHECK_WARNING(snd_seq_event_output(m_SeqHandle, ev->getHandle()));
1051  } else {
1052  npfds = snd_seq_poll_descriptors_count(m_SeqHandle, POLLOUT);
1053  pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
1054  snd_seq_poll_descriptors(m_SeqHandle, pfds, npfds, POLLOUT);
1055  while (snd_seq_event_output(m_SeqHandle, ev->getHandle()) < 0)
1056  {
1057  poll(pfds, npfds, timeout);
1058  }
1059  }
1060 }
1061 
1073 void MidiClient::outputDirect(SequencerEvent* ev, bool async, int timeout)
1074 {
1075  int npfds;
1076  pollfd* pfds;
1077  if (async) {
1078  CHECK_WARNING(snd_seq_event_output_direct(m_SeqHandle, ev->getHandle()));
1079  } else {
1080  npfds = snd_seq_poll_descriptors_count(m_SeqHandle, POLLOUT);
1081  pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
1082  snd_seq_poll_descriptors(m_SeqHandle, pfds, npfds, POLLOUT);
1083  while (snd_seq_event_output_direct(m_SeqHandle, ev->getHandle()) < 0)
1084  {
1085  poll(pfds, npfds, timeout);
1086  }
1087  }
1088 }
1089 
1098 void
1100 {
1101  CHECK_WARNING(snd_seq_event_output_buffer(m_SeqHandle, ev->getHandle()));
1102 }
1103 
1115 void MidiClient::drainOutput(bool async, int timeout)
1116 {
1117  int npfds;
1118  pollfd* pfds;
1119  if (async) {
1120  CHECK_WARNING(snd_seq_drain_output(m_SeqHandle));
1121  } else {
1122  npfds = snd_seq_poll_descriptors_count(m_SeqHandle, POLLOUT);
1123  pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
1124  snd_seq_poll_descriptors(m_SeqHandle, pfds, npfds, POLLOUT);
1125  while (snd_seq_drain_output(m_SeqHandle) < 0)
1126  {
1127  poll(pfds, npfds, timeout);
1128  }
1129  }
1130 }
1131 
1137 void
1139 {
1140  snd_seq_sync_output_queue(m_SeqHandle);
1141 }
1142 
1148 MidiQueue*
1150 {
1151  if (m_Queue == NULL) {
1152  createQueue();
1153  }
1154  return m_Queue;
1155 }
1156 
1161 MidiQueue*
1163 {
1164  if (m_Queue != NULL) {
1165  delete m_Queue;
1166  }
1167  m_Queue = new MidiQueue(this, this);
1168  return m_Queue;
1169 }
1170 
1177 MidiQueue*
1178 MidiClient::createQueue(QString const& queueName )
1179 {
1180  if (m_Queue != NULL) {
1181  delete m_Queue;
1182  }
1183  m_Queue = new MidiQueue(this, queueName, this);
1184  return m_Queue;
1185 }
1186 
1194 MidiQueue*
1196 {
1197  if (m_Queue != NULL) {
1198  delete m_Queue;
1199  }
1200  m_Queue = new MidiQueue(this, queue_id, this);
1201  return m_Queue;
1202 }
1203 
1211 MidiQueue*
1212 MidiClient::useQueue(const QString& name)
1213 {
1214  if (m_Queue != NULL) {
1215  delete m_Queue;
1216  }
1217  int queue_id = getQueueId(name);
1218  if ( queue_id >= 0) {
1219  m_Queue = new MidiQueue(this, queue_id, this);
1220  }
1221  return m_Queue;
1222 }
1223 
1230 MidiQueue*
1232 {
1233  if (m_Queue != NULL) {
1234  delete m_Queue;
1235  }
1236  queue->setParent(this);
1237  m_Queue = queue;
1238  return m_Queue;
1239 }
1240 
1245 QList<int>
1247 {
1248  int q, err, max;
1249  QList<int> queues;
1250  snd_seq_queue_info_t* qinfo;
1251  snd_seq_queue_info_alloca(&qinfo);
1252  max = getSystemInfo().getMaxQueues();
1253  for ( q = 0; q < max; ++q ) {
1254  err = snd_seq_get_queue_info(m_SeqHandle, q, qinfo);
1255  if (err == 0) {
1256  queues.append(q);
1257  }
1258  }
1259  return queues;
1260 }
1261 
1270 MidiClient::filterPorts(unsigned int filter)
1271 {
1272  PortInfoList result;
1273  ClientInfoList::ConstIterator itc;
1274  PortInfoList::ConstIterator itp;
1275 
1276  if (m_NeedRefreshClientList)
1277  readClients();
1278 
1279  for (itc = m_ClientList.constBegin(); itc != m_ClientList.constEnd(); ++itc) {
1280  ClientInfo ci = (*itc);
1281  if ((ci.getClientId() == SND_SEQ_CLIENT_SYSTEM) ||
1282  (ci.getClientId() == m_Info.getClientId()))
1283  continue;
1284  PortInfoList lstPorts = ci.getPorts();
1285  for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) {
1286  PortInfo pi = (*itp);
1287  unsigned int cap = pi.getCapability();
1288  if ( ((filter & cap) != 0) &&
1289  ((SND_SEQ_PORT_CAP_NO_EXPORT & cap) == 0) ) {
1290  result.append(pi);
1291  }
1292  }
1293  }
1294  return result;
1295 }
1296 
1300 void
1302 {
1303  m_InputsAvail.clear();
1304  m_OutputsAvail.clear();
1305  m_InputsAvail = filterPorts( SND_SEQ_PORT_CAP_READ |
1306  SND_SEQ_PORT_CAP_SUBS_READ );
1307  m_OutputsAvail = filterPorts( SND_SEQ_PORT_CAP_WRITE |
1308  SND_SEQ_PORT_CAP_SUBS_WRITE );
1309 }
1310 
1317 {
1318  m_NeedRefreshClientList = true;
1320  return m_InputsAvail;
1321 }
1322 
1329 {
1330  m_NeedRefreshClientList = true;
1332  return m_OutputsAvail;
1333 }
1334 
1341 void
1343 {
1344  m_listeners.append(listener);
1345 }
1346 
1352 void
1354 {
1355  m_listeners.removeAll(listener);
1356 }
1357 
1364 void
1366 {
1367  if (bEnabled != m_eventsEnabled) {
1368  m_eventsEnabled = bEnabled;
1369  }
1370 }
1371 
1376 SystemInfo&
1378 {
1379  snd_seq_system_info(m_SeqHandle, m_sysInfo.m_Info);
1380  return m_sysInfo;
1381 }
1382 
1387 PoolInfo&
1389 {
1390  snd_seq_get_client_pool(m_SeqHandle, m_poolInfo.m_Info);
1391  return m_poolInfo;
1392 }
1393 
1398 void
1400 {
1401  m_poolInfo = info;
1402  CHECK_WARNING(snd_seq_set_client_pool(m_SeqHandle, m_poolInfo.m_Info));
1403 }
1404 
1409 void
1411 {
1412  CHECK_WARNING(snd_seq_reset_pool_input(m_SeqHandle));
1413 }
1414 
1419 void
1421 {
1422  CHECK_WARNING(snd_seq_reset_pool_output(m_SeqHandle));
1423 }
1424 
1429 void
1431 {
1432  CHECK_WARNING(snd_seq_set_client_pool_input(m_SeqHandle, size));
1433 }
1434 
1439 void
1441 {
1442  CHECK_WARNING(snd_seq_set_client_pool_output(m_SeqHandle, size));
1443 }
1444 
1449 void
1451 {
1452  CHECK_WARNING(snd_seq_set_client_pool_output_room(m_SeqHandle, size));
1453 }
1454 
1459 void
1461 {
1462  CHECK_WARNING(snd_seq_drop_input(m_SeqHandle));
1463 }
1464 
1469 void
1471 {
1472  CHECK_WARNING(snd_seq_drop_input_buffer(m_SeqHandle));
1473 }
1474 
1482 void
1484 {
1485  CHECK_WARNING(snd_seq_drop_output(m_SeqHandle));
1486 }
1487 
1495 void
1497 {
1498  CHECK_WARNING(snd_seq_drop_output_buffer(m_SeqHandle));
1499 }
1500 
1507 void
1509 {
1510  CHECK_WARNING(snd_seq_remove_events(m_SeqHandle, spec->m_Info));
1511 }
1512 
1519 {
1520  snd_seq_event_t* ev;
1521  if (CHECK_WARNING(snd_seq_extract_output(m_SeqHandle, &ev) == 0)) {
1522  return new SequencerEvent(ev);
1523  }
1524  return NULL;
1525 }
1526 
1532 int
1534 {
1535  return snd_seq_event_output_pending(m_SeqHandle);
1536 }
1537 
1551 int
1553 {
1554  return snd_seq_event_input_pending(m_SeqHandle, fetch ? 1 : 0);
1555 }
1556 
1563 int
1564 MidiClient::getQueueId(const QString& name)
1565 {
1566  return snd_seq_query_named_queue(m_SeqHandle, name.toLocal8Bit().data());
1567 }
1568 
1574 int
1576 {
1577  return snd_seq_poll_descriptors_count(m_SeqHandle, events);
1578 }
1579 
1593 int
1594 MidiClient::pollDescriptors( struct pollfd *pfds, unsigned int space,
1595  short events )
1596 {
1597  return snd_seq_poll_descriptors(m_SeqHandle, pfds, space, events);
1598 }
1599 
1606 unsigned short
1607 MidiClient::pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
1608 {
1609  unsigned short revents;
1610  CHECK_WARNING( snd_seq_poll_descriptors_revents( m_SeqHandle,
1611  pfds, nfds,
1612  &revents ));
1613  return revents;
1614 }
1615 
1620 const char *
1622 {
1623  return snd_seq_name(m_SeqHandle);
1624 }
1625 
1630 void
1632 {
1633  CHECK_WARNING(snd_seq_set_client_name(m_SeqHandle, name));
1634 }
1635 
1643 int
1645  unsigned int caps,
1646  unsigned int type )
1647 {
1648  return CHECK_WARNING( snd_seq_create_simple_port( m_SeqHandle,
1649  name, caps, type ));
1650 }
1651 
1656 void
1658 {
1659  CHECK_WARNING( snd_seq_delete_simple_port( m_SeqHandle, port ));
1660 }
1661 
1668 void
1669 MidiClient::connectFrom(int myport, int client, int port)
1670 {
1671  CHECK_WARNING( snd_seq_connect_from(m_SeqHandle, myport, client, port ));
1672 }
1673 
1680 void
1681 MidiClient::connectTo(int myport, int client, int port)
1682 {
1683  CHECK_WARNING( snd_seq_connect_to(m_SeqHandle, myport, client, port ));
1684 }
1685 
1692 void
1693 MidiClient::disconnectFrom(int myport, int client, int port)
1694 {
1695  CHECK_WARNING( snd_seq_disconnect_from(m_SeqHandle, myport, client, port ));
1696 }
1697 
1704 void
1705 MidiClient::disconnectTo(int myport, int client, int port)
1706 {
1707  CHECK_WARNING( snd_seq_disconnect_to(m_SeqHandle, myport, client, port ));
1708 }
1709 
1721 bool
1722 MidiClient::parseAddress( const QString& straddr, snd_seq_addr& addr )
1723 {
1724  bool ok(false);
1725  QString testClient, testPort;
1726  ClientInfoList::ConstIterator cit;
1727  int pos = straddr.indexOf(':');
1728  if (pos > -1) {
1729  testClient = straddr.left(pos);
1730  testPort = straddr.mid(pos+1);
1731  } else {
1732  testClient = straddr;
1733  testPort = '0';
1734  }
1735  addr.client = testClient.toInt(&ok);
1736  if (ok)
1737  addr.port = testPort.toInt(&ok);
1738  if (!ok) {
1739  if (m_NeedRefreshClientList)
1740  readClients();
1741  for ( cit = m_ClientList.constBegin();
1742  cit != m_ClientList.constEnd(); ++cit ) {
1743  ClientInfo ci = *cit;
1744  if (testClient.compare(ci.getName(), Qt::CaseInsensitive) == 0) {
1745  addr.client = ci.getClientId();
1746  addr.port = testPort.toInt(&ok);
1747  return ok;
1748  }
1749  }
1750  }
1751  return ok;
1752 }
1753 
1758 bool
1760 {
1761  QReadLocker locker(&m_mutex);
1762  return m_Stopped;
1763 }
1764 
1768 void
1770 {
1771  QWriteLocker locker(&m_mutex);
1772  m_Stopped = true;
1773 }
1774 
1775 #if defined(RTKIT_SUPPORT)
1776 static pid_t _gettid(void) {
1777  return (pid_t) ::syscall(SYS_gettid);
1778 }
1779 #endif
1780 
1781 void
1782 MidiClient::SequencerInputThread::setRealtimePriority()
1783 {
1784  struct sched_param p;
1785  int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK;
1786  quint32 priority = 6;
1787 #if defined(RTKIT_SUPPORT)
1788  bool ok;
1789  quint32 max_prio;
1790  quint64 thread;
1791  struct rlimit old_limit, new_limit;
1792  long long max_rttime;
1793 #endif
1794 
1795  ::memset(&p, 0, sizeof(p));
1796  p.sched_priority = priority;
1797  rt = ::pthread_setschedparam(::pthread_self(), policy, &p);
1798  if (rt != 0) {
1799 #if defined(RTKIT_SUPPORT)
1800  const QString rtkit_service =
1801  QLatin1String("org.freedesktop.RealtimeKit1");
1802  const QString rtkit_path =
1803  QLatin1String("/org/freedesktop/RealtimeKit1");
1804  const QString rtkit_iface = rtkit_service;
1805  thread = _gettid();
1806  QDBusConnection bus = QDBusConnection::systemBus();
1807  QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus);
1808  QVariant maxRTPrio = realtimeKit.property("MaxRealtimePriority");
1809  max_prio = maxRTPrio.toUInt(&ok);
1810  if (!ok) {
1811  qWarning() << "invalid property RealtimeKit.MaxRealtimePriority";
1812  return;
1813  }
1814  if (priority > max_prio)
1815  priority = max_prio;
1816  QVariant maxRTNSec = realtimeKit.property("RTTimeNSecMax");
1817  max_rttime = maxRTNSec.toLongLong(&ok);
1818  if (!ok || max_rttime < 0) {
1819  qWarning() << "invalid property RealtimeKit.RTTimeNSecMax";
1820  return;
1821  }
1822  new_limit.rlim_cur = new_limit.rlim_max = max_rttime;
1823  rt = ::getrlimit(RLIMIT_RTTIME, &old_limit);
1824  if (rt < 0) {
1825  qWarning() << "getrlimit() failed. err=" << rt << ::strerror(rt);
1826  return;
1827  }
1828  rt = ::setrlimit(RLIMIT_RTTIME, &new_limit);
1829  if ( rt < 0) {
1830  qWarning() << "setrlimit() failed, err=" << rt << ::strerror(rt);
1831  return;
1832  }
1833  QDBusMessage reply = realtimeKit.call("MakeThreadRealtime", thread, priority);
1834  if (reply.type() == QDBusMessage::ErrorMessage )
1835  qWarning() << "error returned by RealtimeKit.MakeThreadRealtime:"
1836  << reply.errorMessage();
1837 #else
1838  qWarning() << "pthread_setschedparam() failed, err="
1839  << rt << ::strerror(rt);
1840 #endif
1841  }
1842 }
1843 
1847 void
1849 {
1850  unsigned long npfd;
1851  pollfd* pfd;
1852  if ( priority() == TimeCriticalPriority )
1853  setRealtimePriority();
1854 
1855  if (m_MidiClient != NULL) {
1856  npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN);
1857  pfd = (pollfd *) alloca(npfd * sizeof(pollfd));
1858  try
1859  {
1860  snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN);
1861  while (!stopped() && (m_MidiClient != NULL))
1862  {
1863  int rt = poll(pfd, npfd, m_Wait);
1864  if (rt > 0) {
1865  m_MidiClient->doEvents();
1866  }
1867  }
1868  }
1869  catch (...)
1870  {
1871  qWarning() << "exception in input thread";
1872  }
1873  }
1874 }
1875 
1880 {
1881  snd_seq_client_info_malloc(&m_Info);
1882 }
1883 
1889 {
1890  snd_seq_client_info_malloc(&m_Info);
1891  snd_seq_client_info_copy(m_Info, other.m_Info);
1892  m_Ports = other.m_Ports;
1893 }
1894 
1899 ClientInfo::ClientInfo(snd_seq_client_info_t* other)
1900 {
1901  snd_seq_client_info_malloc(&m_Info);
1902  snd_seq_client_info_copy(m_Info, other);
1903 }
1904 
1911 {
1912  snd_seq_client_info_malloc(&m_Info);
1913  snd_seq_get_any_client_info(seq->getHandle(), id, m_Info);
1914 }
1915 
1920 {
1921  freePorts();
1922  snd_seq_client_info_free(m_Info);
1923 }
1924 
1929 ClientInfo*
1931 {
1932  return new ClientInfo(m_Info);
1933 }
1934 
1940 ClientInfo&
1942 {
1943  snd_seq_client_info_copy(m_Info, other.m_Info);
1944  m_Ports = other.m_Ports;
1945  return *this;
1946 }
1947 
1952 int
1954 {
1955  return snd_seq_client_info_get_client(m_Info);
1956 }
1957 
1962 snd_seq_client_type_t
1964 {
1965  return snd_seq_client_info_get_type(m_Info);
1966 }
1967 
1972 QString
1974 {
1975  return QString(snd_seq_client_info_get_name(m_Info));
1976 }
1977 
1982 bool
1984 {
1985  return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0);
1986 }
1987 
1992 bool
1994 {
1995  return (snd_seq_client_info_get_error_bounce(m_Info) != 0);
1996 }
1997 
2003 const unsigned char*
2005 {
2006  return snd_seq_client_info_get_event_filter(m_Info);
2007 }
2008 
2013 int
2015 {
2016  return snd_seq_client_info_get_num_ports(m_Info);
2017 }
2018 
2023 int
2025 {
2026  return snd_seq_client_info_get_event_lost(m_Info);
2027 }
2028 
2033 void
2035 {
2036  snd_seq_client_info_set_client(m_Info, client);
2037 }
2038 
2043 void
2044 ClientInfo::setName(QString name)
2045 {
2046  snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data());
2047 }
2048 
2053 void
2055 {
2056  snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0);
2057 }
2058 
2063 void
2065 {
2066  snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0);
2067 }
2068 
2074 void
2075 ClientInfo::setEventFilter(unsigned char *filter)
2076 {
2077  snd_seq_client_info_set_event_filter(m_Info, filter);
2078 }
2079 
2084 void
2086 {
2087  PortInfo info;
2088  freePorts();
2089  info.setClient(getClientId());
2090  info.setClientName(getName());
2091  info.setPort(-1);
2092  while (snd_seq_query_next_port(seq->getHandle(), info.m_Info) >= 0) {
2093  info.readSubscribers(seq);
2094  m_Ports.append(info);
2095  }
2096 }
2097 
2101 void
2103 {
2104  m_Ports.clear();
2105 }
2106 
2113 {
2114  PortInfoList lst = m_Ports; // copy
2115  return lst;
2116 }
2117 
2122 int
2124 {
2125  return snd_seq_client_info_sizeof();
2126 }
2127 
2128 #if SND_LIB_VERSION > 0x010010
2129 
2134 void
2135 ClientInfo::addFilter(int eventType)
2136 {
2137  snd_seq_client_info_event_filter_add(m_Info, eventType);
2138 }
2139 
2145 bool
2146 ClientInfo::isFiltered(int eventType)
2147 {
2148  return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0);
2149 }
2150 
2154 void
2155 ClientInfo::clearFilter()
2156 {
2157  snd_seq_client_info_event_filter_clear(m_Info);
2158 }
2159 
2164 void
2165 ClientInfo::removeFilter(int eventType)
2166 {
2167  snd_seq_client_info_event_filter_del(m_Info, eventType);
2168 }
2169 #endif
2170 
2175 {
2176  snd_seq_system_info_malloc(&m_Info);
2177 }
2178 
2184 {
2185  snd_seq_system_info_malloc(&m_Info);
2186  snd_seq_system_info_copy(m_Info, other.m_Info);
2187 }
2188 
2193 SystemInfo::SystemInfo(snd_seq_system_info_t* other)
2194 {
2195  snd_seq_system_info_malloc(&m_Info);
2196  snd_seq_system_info_copy(m_Info, other);
2197 }
2198 
2204 {
2205  snd_seq_system_info_malloc(&m_Info);
2206  snd_seq_system_info(seq->getHandle(), m_Info);
2207 }
2208 
2213 {
2214  snd_seq_system_info_free(m_Info);
2215 }
2216 
2221 SystemInfo*
2223 {
2224  return new SystemInfo(m_Info);
2225 }
2226 
2232 SystemInfo&
2234 {
2235  snd_seq_system_info_copy(m_Info, other.m_Info);
2236  return *this;
2237 }
2238 
2244 {
2245  return snd_seq_system_info_get_clients(m_Info);
2246 }
2247 
2253 {
2254  return snd_seq_system_info_get_ports(m_Info);
2255 }
2256 
2262 {
2263  return snd_seq_system_info_get_queues(m_Info);
2264 }
2265 
2271 {
2272  return snd_seq_system_info_get_channels(m_Info);
2273 }
2274 
2280 {
2281  return snd_seq_system_info_get_cur_queues(m_Info);
2282 }
2283 
2289 {
2290  return snd_seq_system_info_get_cur_clients(m_Info);
2291 }
2292 
2298 {
2299  return snd_seq_system_info_sizeof();
2300 }
2301 
2306 {
2307  snd_seq_client_pool_malloc(&m_Info);
2308 }
2309 
2315 {
2316  snd_seq_client_pool_malloc(&m_Info);
2317  snd_seq_client_pool_copy(m_Info, other.m_Info);
2318 }
2319 
2324 PoolInfo::PoolInfo(snd_seq_client_pool_t* other)
2325 {
2326  snd_seq_client_pool_malloc(&m_Info);
2327  snd_seq_client_pool_copy(m_Info, other);
2328 }
2329 
2335 {
2336  snd_seq_client_pool_malloc(&m_Info);
2337  snd_seq_get_client_pool(seq->getHandle(), m_Info);
2338 }
2339 
2344 {
2345  snd_seq_client_pool_free(m_Info);
2346 }
2347 
2352 PoolInfo*
2354 {
2355  return new PoolInfo(m_Info);
2356 }
2357 
2364 {
2365  snd_seq_client_pool_copy(m_Info, other.m_Info);
2366  return *this;
2367 }
2368 
2373 int
2375 {
2376  return snd_seq_client_pool_get_client(m_Info);
2377 }
2378 
2383 int
2385 {
2386  return snd_seq_client_pool_get_input_free(m_Info);
2387 }
2388 
2393 int
2395 {
2396  return snd_seq_client_pool_get_input_pool(m_Info);
2397 }
2398 
2403 int
2405 {
2406  return snd_seq_client_pool_get_output_free(m_Info);
2407 }
2408 
2413 int
2415 {
2416  return snd_seq_client_pool_get_output_pool(m_Info);
2417 }
2418 
2424 int
2426 {
2427  return snd_seq_client_pool_get_output_room(m_Info);
2428 }
2429 
2434 void
2436 {
2437  snd_seq_client_pool_set_input_pool(m_Info, size);
2438 }
2439 
2444 void
2446 {
2447  snd_seq_client_pool_set_output_pool(m_Info, size);
2448 }
2449 
2456 void
2458 {
2459  snd_seq_client_pool_set_output_room(m_Info, size);
2460 }
2461 
2466 int
2468 {
2469  return snd_seq_client_pool_sizeof();
2470 }
2471 
2472 #if SND_LIB_VERSION > 0x010004
2473 
2478 QString
2479 getRuntimeALSALibraryVersion()
2480 {
2481  return QString(snd_asoundlib_version());
2482 }
2483 
2489 int
2490 getRuntimeALSALibraryNumber()
2491 {
2492  QRegExp rx("(\\d+)");
2493  QString str = getRuntimeALSALibraryVersion();
2494  bool ok;
2495  int pos = 0, result = 0, j = 0;
2496  while ((pos = rx.indexIn(str, pos)) != -1 && j < 3) {
2497  int v = rx.cap(1).toInt(&ok);
2498  if (ok) {
2499  result <<= 8;
2500  result += v;
2501  }
2502  pos += rx.matchedLength();
2503  j++;
2504  }
2505  return result;
2506 }
2507 #endif // SND_LIB_VERSION > 0x010004
2508 
2514 QString
2516 {
2517  QRegExp rx(".*Driver Version ([\\d\\.]+).*");
2518  QString s;
2519  QFile f("/proc/asound/version");
2520  if (f.open(QFile::ReadOnly)) {
2521  QTextStream str(&f);
2522  if (rx.exactMatch(str.readLine().trimmed()))
2523  s = rx.cap(1);
2524  }
2525  return s;
2526 }
2527 
2533 int
2535 {
2536  QRegExp rx("(\\d+)");
2537  QString str = getRuntimeALSADriverVersion();
2538  bool ok;
2539  int pos = 0, result = 0, j = 0;
2540  while ((pos = rx.indexIn(str, pos)) != -1 && j < 3) {
2541  int v = rx.cap(1).toInt(&ok);
2542  if (ok) {
2543  result <<= 8;
2544  result += v;
2545  }
2546  pos += rx.matchedLength();
2547  j++;
2548  }
2549  return result;
2550 }
2551 
2552 } /* namespace drumstick */
drumstick::PoolInfo::getInputPool
int getInputPool()
Gets the input pool size.
Definition: alsaclient.cpp:2394
drumstick::MidiClient::setEventsEnabled
void setEventsEnabled(const bool bEnabled)
Enables the notification of received SequencerEvent instances to the listeners registered with addLis...
Definition: alsaclient.cpp:1365
drumstick::MidiClient::output
void output(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event using the library output buffer.
Definition: alsaclient.cpp:1045
drumstick::MidiClient::SequencerInputThread::stop
void stop()
Stops the input thread.
Definition: alsaclient.cpp:1769
QObject
CHECK_WARNING
#define CHECK_WARNING(x)
This macro calls the check warning function.
Definition: drumstickcommon.h:146
drumstick::MidiClient::~MidiClient
virtual ~MidiClient()
Destructor.
Definition: alsaclient.cpp:384
drumstick::MidiClient::extractOutput
SequencerEvent * extractOutput()
Extracts (and removes) the first event in the output buffer.
Definition: alsaclient.cpp:1518
drumstick::MidiClient::synchronizeOutput
void synchronizeOutput()
Wait until all sent events are processed.
Definition: alsaclient.cpp:1138
drumstick::MidiClient::dropInputBuffer
void dropInputBuffer()
Remove all events on user-space input buffer.
Definition: alsaclient.cpp:1470
drumstick::ClientInfo::getNumPorts
int getNumPorts()
Gets the client's port count.
Definition: alsaclient.cpp:2014
drumstick::PoolInfo::getClientId
int getClientId()
Gets the client ID for this object.
Definition: alsaclient.cpp:2374
drumstick::ClientInfo::setName
void setName(QString name)
Sets the client name.
Definition: alsaclient.cpp:2044
drumstick::MidiClient::getAvailableOutputs
PortInfoList getAvailableOutputs()
Gets the available user output ports in the system.
Definition: alsaclient.cpp:1328
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:1644
drumstick::MidiClient::setErrorBounce
void setErrorBounce(bool newValue)
Sets the error-bounce usage of the client.
Definition: alsaclient.cpp:1027
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:445
drumstick::MidiClient::connectTo
void connectTo(int myport, int client, int port)
Subscribe one port to another arbitrary sequencer client:port.
Definition: alsaclient.cpp:1681
drumstick::MidiClient::eventReceived
void eventReceived(SequencerEvent *ev)
Signal emitted when an event is received.
drumstick::MidiClient::getPollDescriptorsCount
int getPollDescriptorsCount(short events)
Returns the number of poll descriptors.
Definition: alsaclient.cpp:1575
drumstick::MidiClient::createQueue
MidiQueue * createQueue()
Create and return a new MidiQueue associated to this client.
Definition: alsaclient.cpp:1162
drumstick::getRuntimeALSADriverNumber
DRUMSTICK_EXPORT int getRuntimeALSADriverNumber()
Gets the runtime ALSA drivers version number.
Definition: alsaclient.cpp:2534
drumstick::MidiClient::close
void close()
Close the sequencer device.
Definition: alsaclient.cpp:502
drumstick::PoolInfo::PoolInfo
PoolInfo()
Default constructor.
Definition: alsaclient.cpp:2305
drumstick::MidiClient::getThisClientInfo
ClientInfo & getThisClientInfo()
Gets the ClientInfo object holding data about this client.
Definition: alsaclient.cpp:827
drumstick::MidiPort::getPortInfo
PortInfo * getPortInfo()
Gets the PortInfo object pointer.
Definition: alsaport.cpp:571
drumstick::ClientInfo::getSizeOfInfo
int getSizeOfInfo() const
Gets the size of the internal object.
Definition: alsaclient.cpp:2123
drumstick::MidiClient::addListener
void addListener(QObject *listener)
Adds a QObject to the listeners list.
Definition: alsaclient.cpp:1342
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:1722
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:1705
drumstick::MidiClient::getBroadcastFilter
bool getBroadcastFilter()
Gets the broadcast filter usage of the client.
Definition: alsaclient.cpp:993
drumstick::MidiClient::doEvents
void doEvents()
Dispatch the events received from the Sequencer.
Definition: alsaclient.cpp:638
drumstick::MidiClient::createPort
MidiPort * createPort()
Create and attach a new MidiPort instance to this client.
Definition: alsaclient.cpp:915
drumstick::MidiClient::stopSequencerInput
void stopSequencerInput()
Stops reading events from the ALSA sequencer.
Definition: alsaclient.cpp:767
drumstick::MidiClient::portAttach
void portAttach(MidiPort *port)
Attach a MidiPort instance to this client.
Definition: alsaclient.cpp:927
drumstick::MidiClient::setOutputBufferSize
void setOutputBufferSize(size_t newSize)
Sets the size of the library output buffer for the ALSA client.
Definition: alsaclient.cpp:534
drumstick::MidiClient::updateAvailablePorts
void updateAvailablePorts()
Update the internal lists of user ports.
Definition: alsaclient.cpp:1301
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:1533
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:1195
drumstick::PortInfo::setPort
void setPort(int port)
Set the port number.
Definition: alsaport.cpp:286
drumstick::SequencerEvent
Base class for the event's hierarchy.
Definition: alsaevent.h:53
alsaevent.h
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:417
drumstick::SystemInfo::~SystemInfo
virtual ~SystemInfo()
Destructor.
Definition: alsaclient.cpp:2212
drumstick::ClientInfo::freePorts
void freePorts()
Release the ports list.
Definition: alsaclient.cpp:2102
drumstick::ClientInfo::getClientType
snd_seq_client_type_t getClientType()
Gets the client's type.
Definition: alsaclient.cpp:1963
drumstick::MidiClient::freeClients
void freeClients()
Releases the list of ALSA sequencer's clients.
Definition: alsaclient.cpp:804
drumstick::ClientInfo::setClient
void setClient(int client)
Sets the client identifier number.
Definition: alsaclient.cpp:2034
drumstick::ClientInfo::getEventFilter
const unsigned char * getEventFilter() __attribute__((deprecated))
Gets the client's event filter.
Definition: alsaclient.cpp:2004
drumstick::MidiClient::setPoolOutputRoom
void setPoolOutputRoom(int size)
Sets the room size of the client's output pool.
Definition: alsaclient.cpp:1450
drumstick::ClientInfo::~ClientInfo
virtual ~ClientInfo()
Destructor.
Definition: alsaclient.cpp:1919
drumstick::ClientInfo::setBroadcastFilter
void setBroadcastFilter(bool val)
Sets the broadcast filter.
Definition: alsaclient.cpp:2054
drumstick::MidiClient::_setClientName
void _setClientName(const char *name)
Sets the client name.
Definition: alsaclient.cpp:1631
drumstick::MidiClient::getPoolInfo
PoolInfo & getPoolInfo()
Gets a PoolInfo instance with an updated state of the client memory pool.
Definition: alsaclient.cpp:1388
drumstick::SequencerEventHandler::handleSequencerEvent
virtual void handleSequencerEvent(SequencerEvent *ev)=0
Callback function to be implemented by the derived class.
drumstick::MidiClient::getMidiPorts
MidiPortList getMidiPorts() const
Gets the list of MidiPort instances belonging to this client.
Definition: alsaclient.cpp:905
drumstick::MidiClient::getInputBufferSize
size_t getInputBufferSize()
Gets the size of the library input buffer for the ALSA client.
Definition: alsaclient.cpp:550
drumstick::PortInfo::readSubscribers
void readSubscribers(MidiClient *seq)
Obtains the port subscribers lists.
Definition: alsaport.cpp:431
drumstick::PoolInfo::setOutputPool
void setOutputPool(int size)
Sets the output pool size.
Definition: alsaclient.cpp:2445
drumstick::SystemInfo::SystemInfo
SystemInfo()
Default constructor.
Definition: alsaclient.cpp:2174
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:1993
drumstick::SystemInfo::getMaxClients
int getMaxClients()
Get the system's maximum number of clients.
Definition: alsaclient.cpp:2243
drumstick::MidiClient
Client management.
Definition: alsaclient.h:198
drumstick::MidiPort::setMidiClient
void setMidiClient(MidiClient *seq)
Sets the MidiClient.
Definition: alsaport.cpp:600
drumstick::MidiClient::drainOutput
void drainOutput(bool async=false, int timeout=-1)
Drain the library output buffer.
Definition: alsaclient.cpp:1115
drumstick::SystemInfo::getSizeOfInfo
int getSizeOfInfo() const
Get the system's info object size.
Definition: alsaclient.cpp:2297
drumstick::PoolInfo
Sequencer Pool information.
Definition: alsaclient.h:138
drumstick::PortInfo::getClient
int getClient()
Gets the client number.
Definition: alsaport.cpp:145
alsaqueue.h
drumstick::MidiClient::setClientName
void setClientName(QString const &newName)
Changes the public name of the ALSA sequencer client.
Definition: alsaclient.cpp:892
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:1399
drumstick::PoolInfo::getOutputPool
int getOutputPool()
Gets the output pool size.
Definition: alsaclient.cpp:2414
drumstick::ClientInfo::setEventFilter
void setEventFilter(unsigned char *filter) __attribute__((deprecated))
Sets the event filter.
Definition: alsaclient.cpp:2075
drumstick::SystemInfo::getMaxPorts
int getMaxPorts()
Get the system's maximum number of ports.
Definition: alsaclient.cpp:2252
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:2435
drumstick::MidiClient::inputPending
int inputPending(bool fetch)
Gets the size of the events on the input buffer.
Definition: alsaclient.cpp:1552
drumstick::ClientInfo::getPorts
PortInfoList getPorts() const
Gets the ports list.
Definition: alsaclient.cpp:2112
drumstick::PoolInfo::getInputFree
int getInputFree()
Gets the available size on input pool.
Definition: alsaclient.cpp:2384
drumstick::PoolInfo::getOutputFree
int getOutputFree()
Gets the available size on output pool.
Definition: alsaclient.cpp:2404
drumstick::MidiClient::setRealTimeInput
void setRealTimeInput(bool enabled)
Enables real-time priority for the MIDI input thread.
Definition: alsaclient.cpp:404
drumstick::SystemInfo::getCurrentClients
int getCurrentClients()
Get the system's current number of clients.
Definition: alsaclient.cpp:2288
drumstick::PoolInfo::getOutputRoom
int getOutputRoom()
Gets the output room size.
Definition: alsaclient.cpp:2425
drumstick::MidiClient::getHandle
snd_seq_t * getHandle()
Returns the sequencer handler managed by ALSA.
Definition: alsaclient.h:235
drumstick::MidiClient::getClientName
QString getClientName()
Gets the client's public name.
Definition: alsaclient.cpp:863
drumstick::PortInfoList
QList< PortInfo > PortInfoList
List of port information objects.
Definition: alsaport.h:112
drumstick::PoolInfo::setOutputRoom
void setOutputRoom(int size)
Sets the output room size.
Definition: alsaclient.cpp:2457
drumstick::MidiClient::SequencerInputThread::stopped
bool stopped()
Returns true or false depending on the input thread state.
Definition: alsaclient.cpp:1759
drumstick::ClientInfo::readPorts
void readPorts(MidiClient *seq)
Read the client ports.
Definition: alsaclient.cpp:2085
drumstick::SystemInfo::operator=
SystemInfo & operator=(const SystemInfo &other)
Assignment operator.
Definition: alsaclient.cpp:2233
drumstick::MidiClient::deleteSimplePort
void deleteSimplePort(int port)
Remove an ALSA sequencer port.
Definition: alsaclient.cpp:1657
drumstick::ClientInfo::getEventLost
int getEventLost()
Gets the number of lost events.
Definition: alsaclient.cpp:2024
drumstick::MidiClient::setThisClientInfo
void setThisClientInfo(const ClientInfo &val)
Sets the data supplied by the ClientInfo object into the ALSA sequencer client.
Definition: alsaclient.cpp:841
drumstick::MidiClient::getAvailableQueues
QList< int > getAvailableQueues()
Get a list of the existing queues.
Definition: alsaclient.cpp:1246
drumstick::ClientInfo::getBroadcastFilter
bool getBroadcastFilter()
Gets the client's broadcast filter.
Definition: alsaclient.cpp:1983
drumstick::MidiClient::getSystemInfo
SystemInfo & getSystemInfo()
Gets a SystemInfo instance with the updated state of the system.
Definition: alsaclient.cpp:1377
drumstick::MidiClient::getOutputBufferSize
size_t getOutputBufferSize()
Gets the size of the library output buffer for the ALSA client.
Definition: alsaclient.cpp:520
drumstick::ClientInfo::setErrorBounce
void setErrorBounce(bool val)
Sets the error bounce.
Definition: alsaclient.cpp:2064
drumstick::MidiClient::getQueue
MidiQueue * getQueue()
Get the MidiQueue instance associated to this client.
Definition: alsaclient.cpp:1149
drumstick::MidiClient::SequencerInputThread
This class manages event input from the ALSA sequencer.
Definition: alsaclient.cpp:329
drumstick::RemoveEvents
Auxiliary class to remove events from an ALSA queue.
Definition: alsaevent.h:586
drumstick::getRuntimeALSADriverVersion
DRUMSTICK_EXPORT QString getRuntimeALSADriverVersion()
Gets the runtime ALSA drivers version string.
Definition: alsaclient.cpp:2515
drumstick::MidiClient::setPoolOutput
void setPoolOutput(int size)
Sets the size of the client's output pool.
Definition: alsaclient.cpp:1440
drumstick::MidiClient::resetPoolInput
void resetPoolInput()
Resets the client input pool.
Definition: alsaclient.cpp:1410
drumstick::MidiClient::getAvailableClients
ClientInfoList getAvailableClients()
Gets the list of clients from the ALSA sequencer.
Definition: alsaclient.cpp:814
drumstick::MidiClient::getSequencerType
snd_seq_type_t getSequencerType()
Returns the type snd_seq_type_t of the given sequencer handle.
Definition: alsaclient.cpp:612
CHECK_ERROR
#define CHECK_ERROR(x)
This macro calls the check error function.
Definition: drumstickcommon.h:140
drumstick::MidiClient::startSequencerInput
void startSequencerInput()
Starts reading events from the ALSA sequencer.
Definition: alsaclient.cpp:754
drumstick::ValueEvent
Generic event having a value property.
Definition: alsaevent.h:494
drumstick::MidiClient::MidiClient
MidiClient(QObject *parent=0)
Constructor.
Definition: alsaclient.cpp:366
drumstick::MidiClient::setBroadcastFilter
void setBroadcastFilter(bool newValue)
Sets the broadcast filter usage of the client.
Definition: alsaclient.cpp:1004
drumstick::SystemInfo::getCurrentQueues
int getCurrentQueues()
Get the system's current number of queues.
Definition: alsaclient.cpp:2279
drumstick::MidiClient::resetPoolOutput
void resetPoolOutput()
Resets the client output pool.
Definition: alsaclient.cpp:1420
drumstick::MidiClient::dropOutput
void dropOutput()
Clears the client's output buffer and and remove events in sequencer queue.
Definition: alsaclient.cpp:1483
drumstick::MidiClient::setInputBufferSize
void setInputBufferSize(size_t newSize)
Sets the size of the library input buffer for the ALSA client.
Definition: alsaclient.cpp:564
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:1669
drumstick::MidiClient::dropOutputBuffer
void dropOutputBuffer()
Removes all events on the library output buffer.
Definition: alsaclient.cpp:1496
drumstick::ClientInfo::getClientId
int getClientId()
Gets the client's numeric identifier.
Definition: alsaclient.cpp:1953
drumstick::MidiPort::attach
void attach(MidiClient *seq)
Attach the port to a MidiClient instance.
Definition: alsaport.cpp:1097
drumstick::MidiClient::removeEvents
void removeEvents(const RemoveEvents *spec)
Removes events on input/output buffers and pools.
Definition: alsaclient.cpp:1508
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:1594
drumstick::PortInfo::getPort
int getPort()
Gets the port number.
Definition: alsaport.cpp:156
drumstick::ClientInfo::operator=
ClientInfo & operator=(const ClientInfo &other)
Assignment operator.
Definition: alsaclient.cpp:1941
drumstick::PortInfo::getCapability
unsigned int getCapability()
Gets the capabilities bitmap.
Definition: alsaport.cpp:189
drumstick::MidiClient::SequencerInputThread::run
virtual void run()
Main input thread process loop.
Definition: alsaclient.cpp:1848
alsaclient.h
drumstick::MidiClient::detachAllPorts
void detachAllPorts()
Detach all the ports belonging to this client.
Definition: alsaclient.cpp:965
drumstick::ClientInfo::ClientInfo
ClientInfo()
Default constructor.
Definition: alsaclient.cpp:1879
drumstick::MidiPortList
QList< MidiPort * > MidiPortList
List of Ports instances.
Definition: alsaport.h:215
drumstick::MidiClient::pollDescriptorsRevents
unsigned short pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
Gets the number of returned events from poll descriptors.
Definition: alsaclient.cpp:1607
drumstick::SequencerEvent::getHandle
snd_seq_event_t * getHandle()
Gets the handle of the event.
Definition: alsaevent.h:123
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:2363
drumstick::MidiQueue
Queue management.
Definition: alsaqueue.h:188
drumstick::MidiClient::getErrorBounce
bool getErrorBounce()
Get the error-bounce usage of the client.
Definition: alsaclient.cpp:1016
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:1430
drumstick::MidiClient::readClients
void readClients()
Reads the ALSA sequencer's clients list.
Definition: alsaclient.cpp:788
drumstick::ClientInfo::clone
ClientInfo * clone()
Clone the client info object.
Definition: alsaclient.cpp:1930
drumstick::ClientInfoList
QList< ClientInfo > ClientInfoList
List of sequencer client information.
Definition: alsaclient.h:99
drumstick::MidiClient::removeListener
void removeListener(QObject *listener)
Removes a QObject listener from the listeners list.
Definition: alsaclient.cpp:1353
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:99
drumstick::MidiClient::applyClientInfo
void applyClientInfo()
This internal method applies the ClientInfo data to the ALSA sequencer client.
Definition: alsaclient.cpp:851
drumstick::MidiClient::dropInput
void dropInput()
Clears the client's input buffer and and remove events in sequencer queue.
Definition: alsaclient.cpp:1460
drumstick::ClientInfo::getName
QString getName()
Gets the client's name.
Definition: alsaclient.cpp:1973
drumstick::QueueControlEvent
ALSA Event representing a queue control command.
Definition: alsaevent.h:455
QThread
drumstick::MidiClient::getClientId
int getClientId()
Gets the client ID.
Definition: alsaclient.cpp:602
drumstick::PoolInfo::clone
PoolInfo * clone()
Clone the pool info obeject.
Definition: alsaclient.cpp:2353
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:2270
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:1099
drumstick::MidiClient::getAvailableInputs
PortInfoList getAvailableInputs()
Gets the available user input ports in the system.
Definition: alsaclient.cpp:1316
drumstick::PoolInfo::~PoolInfo
virtual ~PoolInfo()
Destructor.
Definition: alsaclient.cpp:2343
drumstick::SystemInfo::clone
SystemInfo * clone()
Clone the system info object.
Definition: alsaclient.cpp:2222
drumstick::MidiClient::portDetach
void portDetach(MidiPort *port)
Detach a MidiPort instance from this client.
Definition: alsaclient.cpp:940
drumstick::MidiClient::setBlockMode
void setBlockMode(bool newValue)
Change the blocking mode of the client.
Definition: alsaclient.cpp:581
drumstick::MidiClient::outputDirect
void outputDirect(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event directly to the sequencer.
Definition: alsaclient.cpp:1073
drumstick::MidiClient::disconnectFrom
void disconnectFrom(int myport, int client, int port)
Unsubscribe one port from another arbitrary sequencer client:port.
Definition: alsaclient.cpp:1693
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:2261
drumstick::MidiClient::_getDeviceName
const char * _getDeviceName()
Gets the internal sequencer device name.
Definition: alsaclient.cpp:1621
drumstick::MidiClient::addEventFilter
void addEventFilter(int evtype)
Add an event filter to the client.
Definition: alsaclient.cpp:982
drumstick::MidiClient::getQueueId
int getQueueId(const QString &name)
Gets the queue's numeric identifier corresponding to the provided name.
Definition: alsaclient.cpp:1564
drumstick::PoolInfo::getSizeOfInfo
int getSizeOfInfo() const
Gets the size of the client pool object.
Definition: alsaclient.cpp:2467
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:1270
drumstick::PortInfo::setClient
void setClient(int client)
Sets the client number.
Definition: alsaport.cpp:275
drumstick::ClientInfo
Client information.
Definition: alsaclient.h:50