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
53
59
65
66namespace drumstick {
67
210
325
330{
331public:
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{
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
444void
445MidiClient::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
477void
478MidiClient::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
501void
503{
504 if (m_SeqHandle != NULL) {
506 CHECK_WARNING(snd_seq_close(m_SeqHandle));
507 m_SeqHandle = NULL;
508 }
509}
510
519size_t
521{
522 return snd_seq_get_output_buffer_size(m_SeqHandle);
523}
524
533void
535{
536 if (getOutputBufferSize() != newSize) {
537 CHECK_WARNING(snd_seq_set_output_buffer_size(m_SeqHandle, newSize));
538 }
539}
540
549size_t
551{
552 return snd_seq_get_input_buffer_size(m_SeqHandle);
553}
554
563void
565{
566 if (getInputBufferSize() != newSize) {
567 CHECK_WARNING(snd_seq_set_input_buffer_size(m_SeqHandle, newSize));
568 }
569}
570
580void
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
601int
603{
604 return CHECK_WARNING(snd_seq_client_id(m_SeqHandle));
605}
606
611snd_seq_type_t
613{
614 return snd_seq_type(m_SeqHandle);
615}
616
637void
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
753void
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
766void
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
787void
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
803void
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
828{
829 snd_seq_get_client_info(m_SeqHandle, m_Info.m_Info);
830 return m_Info;
831}
832
840void
842{
843 m_Info = val;
844 snd_seq_set_client_info(m_SeqHandle, m_Info.m_Info);
845}
846
850void
852{
853 if (m_SeqHandle != NULL) {
854 snd_seq_set_client_info(m_SeqHandle, m_Info.m_Info);
855 }
856}
857
862QString
864{
865 return m_Info.getName();
866}
867
873QString
874MidiClient::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
891void
892MidiClient::setClientName(QString const& newName)
893{
894 if (newName != m_Info.getName()) {
895 m_Info.setName(newName);
897 }
898}
899
906{
907 return m_Ports;
908}
909
916{
917 MidiPort* port = new MidiPort(this);
918 port->attach(this);
919 return port;
920}
921
926void
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
939void
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
981void
983{
984 snd_seq_set_client_event_filter(m_SeqHandle, evtype);
985}
986
992bool
994{
995 return m_Info.getBroadcastFilter();
996}
997
1003void
1005{
1006 m_Info.setBroadcastFilter(newValue);
1008}
1009
1015bool
1017{
1018 return m_Info.getErrorBounce();
1019}
1020
1026void
1028{
1029 m_Info.setErrorBounce(newValue);
1031}
1032
1044void
1045MidiClient::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
1073void 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
1098void
1100{
1101 CHECK_WARNING(snd_seq_event_output_buffer(m_SeqHandle, ev->getHandle()));
1102}
1103
1115void 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
1137void
1139{
1140 snd_seq_sync_output_queue(m_SeqHandle);
1141}
1142
1148MidiQueue*
1150{
1151 if (m_Queue == NULL) {
1152 createQueue();
1153 }
1154 return m_Queue;
1155}
1156
1161MidiQueue*
1163{
1164 if (m_Queue != NULL) {
1165 delete m_Queue;
1166 }
1167 m_Queue = new MidiQueue(this, this);
1168 return m_Queue;
1169}
1170
1177MidiQueue*
1178MidiClient::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
1194MidiQueue*
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
1211MidiQueue*
1212MidiClient::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
1230MidiQueue*
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
1245QList<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
1270MidiClient::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
1300void
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
1341void
1343{
1344 m_listeners.append(listener);
1345}
1346
1352void
1354{
1355 m_listeners.removeAll(listener);
1356}
1357
1364void
1366{
1367 if (bEnabled != m_eventsEnabled) {
1368 m_eventsEnabled = bEnabled;
1369 }
1370}
1371
1378{
1379 snd_seq_system_info(m_SeqHandle, m_sysInfo.m_Info);
1380 return m_sysInfo;
1381}
1382
1387PoolInfo&
1389{
1390 snd_seq_get_client_pool(m_SeqHandle, m_poolInfo.m_Info);
1391 return m_poolInfo;
1392}
1393
1398void
1400{
1401 m_poolInfo = info;
1402 CHECK_WARNING(snd_seq_set_client_pool(m_SeqHandle, m_poolInfo.m_Info));
1403}
1404
1409void
1411{
1412 CHECK_WARNING(snd_seq_reset_pool_input(m_SeqHandle));
1413}
1414
1419void
1421{
1422 CHECK_WARNING(snd_seq_reset_pool_output(m_SeqHandle));
1423}
1424
1429void
1431{
1432 CHECK_WARNING(snd_seq_set_client_pool_input(m_SeqHandle, size));
1433}
1434
1439void
1441{
1442 CHECK_WARNING(snd_seq_set_client_pool_output(m_SeqHandle, size));
1443}
1444
1449void
1451{
1452 CHECK_WARNING(snd_seq_set_client_pool_output_room(m_SeqHandle, size));
1453}
1454
1459void
1461{
1462 CHECK_WARNING(snd_seq_drop_input(m_SeqHandle));
1463}
1464
1469void
1471{
1472 CHECK_WARNING(snd_seq_drop_input_buffer(m_SeqHandle));
1473}
1474
1482void
1484{
1485 CHECK_WARNING(snd_seq_drop_output(m_SeqHandle));
1486}
1487
1495void
1497{
1498 CHECK_WARNING(snd_seq_drop_output_buffer(m_SeqHandle));
1499}
1500
1507void
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
1532int
1534{
1535 return snd_seq_event_output_pending(m_SeqHandle);
1536}
1537
1551int
1553{
1554 return snd_seq_event_input_pending(m_SeqHandle, fetch ? 1 : 0);
1555}
1556
1563int
1564MidiClient::getQueueId(const QString& name)
1565{
1566 return snd_seq_query_named_queue(m_SeqHandle, name.toLocal8Bit().data());
1567}
1568
1574int
1576{
1577 return snd_seq_poll_descriptors_count(m_SeqHandle, events);
1578}
1579
1593int
1594MidiClient::pollDescriptors( struct pollfd *pfds, unsigned int space,
1595 short events )
1596{
1597 return snd_seq_poll_descriptors(m_SeqHandle, pfds, space, events);
1598}
1599
1606unsigned short
1607MidiClient::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
1620const char *
1622{
1623 return snd_seq_name(m_SeqHandle);
1624}
1625
1630void
1632{
1633 CHECK_WARNING(snd_seq_set_client_name(m_SeqHandle, name));
1634}
1635
1643int
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
1656void
1658{
1659 CHECK_WARNING( snd_seq_delete_simple_port( m_SeqHandle, port ));
1660}
1661
1668void
1669MidiClient::connectFrom(int myport, int client, int port)
1670{
1671 CHECK_WARNING( snd_seq_connect_from(m_SeqHandle, myport, client, port ));
1672}
1673
1680void
1681MidiClient::connectTo(int myport, int client, int port)
1682{
1683 CHECK_WARNING( snd_seq_connect_to(m_SeqHandle, myport, client, port ));
1684}
1685
1692void
1693MidiClient::disconnectFrom(int myport, int client, int port)
1694{
1695 CHECK_WARNING( snd_seq_disconnect_from(m_SeqHandle, myport, client, port ));
1696}
1697
1704void
1705MidiClient::disconnectTo(int myport, int client, int port)
1706{
1707 CHECK_WARNING( snd_seq_disconnect_to(m_SeqHandle, myport, client, port ));
1708}
1709
1721bool
1722MidiClient::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
1758bool
1760{
1761 QReadLocker locker(&m_mutex);
1762 return m_Stopped;
1763}
1764
1768void
1770{
1771 QWriteLocker locker(&m_mutex);
1772 m_Stopped = true;
1773}
1774
1775#if defined(RTKIT_SUPPORT)
1776static pid_t _gettid(void) {
1777 return (pid_t) ::syscall(SYS_gettid);
1778}
1779#endif
1780
1781void
1782MidiClient::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
1847void
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
1899ClientInfo::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
1910ClientInfo::ClientInfo(MidiClient* seq, int id)
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
1931{
1932 return new ClientInfo(m_Info);
1933}
1934
1942{
1943 snd_seq_client_info_copy(m_Info, other.m_Info);
1944 m_Ports = other.m_Ports;
1945 return *this;
1946}
1947
1952int
1954{
1955 return snd_seq_client_info_get_client(m_Info);
1956}
1957
1962snd_seq_client_type_t
1964{
1965 return snd_seq_client_info_get_type(m_Info);
1966}
1967
1972QString
1974{
1975 return QString(snd_seq_client_info_get_name(m_Info));
1976}
1977
1982bool
1984{
1985 return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0);
1986}
1987
1992bool
1994{
1995 return (snd_seq_client_info_get_error_bounce(m_Info) != 0);
1996}
1997
2003const unsigned char*
2005{
2006 return snd_seq_client_info_get_event_filter(m_Info);
2007}
2008
2013int
2015{
2016 return snd_seq_client_info_get_num_ports(m_Info);
2017}
2018
2023int
2025{
2026 return snd_seq_client_info_get_event_lost(m_Info);
2027}
2028
2033void
2035{
2036 snd_seq_client_info_set_client(m_Info, client);
2037}
2038
2043void
2045{
2046 snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data());
2047}
2048
2053void
2055{
2056 snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0);
2057}
2058
2063void
2065{
2066 snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0);
2067}
2068
2074void
2075ClientInfo::setEventFilter(unsigned char *filter)
2076{
2077 snd_seq_client_info_set_event_filter(m_Info, filter);
2078}
2079
2084void
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
2101void
2103{
2104 m_Ports.clear();
2105}
2106
2113{
2114 PortInfoList lst = m_Ports; // copy
2115 return lst;
2116}
2117
2122int
2124{
2125 return snd_seq_client_info_sizeof();
2126}
2127
2128#if SND_LIB_VERSION > 0x010010
2134void
2135ClientInfo::addFilter(int eventType)
2136{
2137 snd_seq_client_info_event_filter_add(m_Info, eventType);
2138}
2139
2145bool
2146ClientInfo::isFiltered(int eventType)
2147{
2148 return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0);
2149}
2150
2154void
2155ClientInfo::clearFilter()
2156{
2157 snd_seq_client_info_event_filter_clear(m_Info);
2158}
2159
2164void
2165ClientInfo::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
2193SystemInfo::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
2223{
2224 return new SystemInfo(m_Info);
2225}
2226
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
2324PoolInfo::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
2334PoolInfo::PoolInfo(MidiClient* seq)
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
2352PoolInfo*
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
2373int
2375{
2376 return snd_seq_client_pool_get_client(m_Info);
2377}
2378
2383int
2385{
2386 return snd_seq_client_pool_get_input_free(m_Info);
2387}
2388
2393int
2395{
2396 return snd_seq_client_pool_get_input_pool(m_Info);
2397}
2398
2403int
2405{
2406 return snd_seq_client_pool_get_output_free(m_Info);
2407}
2408
2413int
2415{
2416 return snd_seq_client_pool_get_output_pool(m_Info);
2417}
2418
2424int
2426{
2427 return snd_seq_client_pool_get_output_room(m_Info);
2428}
2429
2434void
2436{
2437 snd_seq_client_pool_set_input_pool(m_Info, size);
2438}
2439
2444void
2446{
2447 snd_seq_client_pool_set_output_pool(m_Info, size);
2448}
2449
2456void
2458{
2459 snd_seq_client_pool_set_output_room(m_Info, size);
2460}
2461
2466int
2468{
2469 return snd_seq_client_pool_sizeof();
2470}
2471
2472#if SND_LIB_VERSION > 0x010004
2478QString
2479getRuntimeALSALibraryVersion()
2480{
2481 return QString(snd_asoundlib_version());
2482}
2483
2489int
2490getRuntimeALSALibraryNumber()
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
2514QString
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
2533int
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 */
Classes managing ALSA Sequencer clients.
QList< ClientInfo > ClientInfoList
List of sequencer client information.
Definition alsaclient.h:99
DRUMSTICK_EXPORT QString getRuntimeALSADriverVersion()
Gets the runtime ALSA drivers version string.
DRUMSTICK_EXPORT int getRuntimeALSADriverNumber()
Gets the runtime ALSA drivers version number.
Classes managing ALSA Sequencer events.
QList< MidiPort * > MidiPortList
List of Ports instances.
Definition alsaport.h:215
QList< PortInfo > PortInfoList
List of port information objects.
Definition alsaport.h:112
Classes managing ALSA Sequencer queues.
The QObject class is the base class of all Qt objects.
The QThread class provides platform-independent threads.
Event representing a MIDI channel pressure or after-touch event.
Definition alsaevent.h:361
ALSA Event representing a change on some ALSA sequencer client on the system.
Definition alsaevent.h:555
Client information.
Definition alsaclient.h:51
void setBroadcastFilter(bool val)
Sets the broadcast filter.
int getSizeOfInfo() const
Gets the size of the internal object.
virtual ~ClientInfo()
Destructor.
bool getErrorBounce()
Gets the client's error bounce.
void readPorts(MidiClient *seq)
Read the client ports.
void setName(QString name)
Sets the client name.
const unsigned char * getEventFilter() __attribute__((deprecated))
Gets the client's event filter.
snd_seq_client_type_t getClientType()
Gets the client's type.
void setErrorBounce(bool val)
Sets the error bounce.
ClientInfo()
Default constructor.
bool getBroadcastFilter()
Gets the client's broadcast filter.
int getNumPorts()
Gets the client's port count.
void setClient(int client)
Sets the client identifier number.
ClientInfo & operator=(const ClientInfo &other)
Assignment operator.
QString getName()
Gets the client's name.
int getClientId()
Gets the client's numeric identifier.
void setEventFilter(unsigned char *filter) __attribute__((deprecated))
Sets the event filter.
int getEventLost()
Gets the number of lost events.
PortInfoList getPorts() const
Gets the ports list.
void freePorts()
Release the ports list.
ClientInfo * clone()
Clone the client info object.
Event representing a MIDI control change event.
Definition alsaevent.h:284
Event representing a MIDI key pressure, or polyphonic after-touch event.
Definition alsaevent.h:269
This class manages event input from the ALSA sequencer.
virtual void run()
Main input thread process loop.
bool stopped()
Returns true or false depending on the input thread state.
void outputBuffer(SequencerEvent *ev)
Output an event using the library output buffer, without draining the buffer.
MidiQueue * useQueue(int queue_id)
Create a new MidiQueue instance using a queue already existing in the system, associating it to the c...
void setOutputBufferSize(size_t newSize)
Sets the size of the library output buffer for the ALSA client.
void setPoolInfo(const PoolInfo &info)
Applies (updates) the client's PoolInfo data into the system.
int inputPending(bool fetch)
Gets the size of the events on the input buffer.
void removeEvents(const RemoveEvents *spec)
Removes events on input/output buffers and pools.
MidiQueue * createQueue()
Create and return a new MidiQueue associated to this client.
void setBroadcastFilter(bool newValue)
Sets the broadcast filter usage of the client.
size_t getOutputBufferSize()
Gets the size of the library output buffer for the ALSA client.
size_t getInputBufferSize()
Gets the size of the library input buffer for the ALSA client.
int createSimplePort(const char *name, unsigned int caps, unsigned int type)
Create an ALSA sequencer port, without using MidiPort.
PortInfoList getAvailableOutputs()
Gets the available user output ports in the system.
void startSequencerInput()
Starts reading events from the ALSA sequencer.
bool getErrorBounce()
Get the error-bounce usage of the client.
void readClients()
Reads the ALSA sequencer's clients list.
void removeListener(QObject *listener)
Removes a QObject listener from the listeners list.
int pollDescriptors(struct pollfd *pfds, unsigned int space, short events)
Get poll descriptors.
MidiPortList getMidiPorts() const
Gets the list of MidiPort instances belonging to this client.
int getQueueId(const QString &name)
Gets the queue's numeric identifier corresponding to the provided name.
void _setClientName(const char *name)
Sets the client name.
bool realTimeInputEnabled()
Return the real-time priority setting for the MIDI input thread.
void disconnectTo(int myport, int client, int port)
Unsubscribe one port to another arbitrary sequencer client:port.
snd_seq_type_t getSequencerType()
Returns the type snd_seq_type_t of the given sequencer handle.
PortInfoList filterPorts(unsigned int filter)
Gets a list of the available user ports in the system, filtered by the given bitmap of desired capabi...
void addListener(QObject *listener)
Adds a QObject to the listeners list.
PortInfoList getAvailableInputs()
Gets the available user input ports in the system.
void setBlockMode(bool newValue)
Change the blocking mode of the client.
void applyClientInfo()
This internal method applies the ClientInfo data to the ALSA sequencer client.
void close()
Close the sequencer device.
SystemInfo & getSystemInfo()
Gets a SystemInfo instance with the updated state of the system.
void resetPoolOutput()
Resets the client output pool.
MidiQueue * getQueue()
Get the MidiQueue instance associated to this client.
QList< int > getAvailableQueues()
Get a list of the existing queues.
int getPollDescriptorsCount(short events)
Returns the number of poll descriptors.
void setClientName(QString const &newName)
Changes the public name of the ALSA sequencer client.
SequencerEvent * extractOutput()
Extracts (and removes) the first event in the output buffer.
void detachAllPorts()
Detach all the ports belonging to this client.
void setRealTimeInput(bool enabled)
Enables real-time priority for the MIDI input thread.
void resetPoolInput()
Resets the client input pool.
void setPoolOutput(int size)
Sets the size of the client's output pool.
void stopSequencerInput()
Stops reading events from the ALSA sequencer.
bool getBroadcastFilter()
Gets the broadcast filter usage of the client.
void deleteSimplePort(int port)
Remove an ALSA sequencer port.
bool parseAddress(const QString &straddr, snd_seq_addr &result)
Parse a text address representation, returning an ALSA address record.
snd_seq_t * getHandle()
Returns the sequencer handler managed by ALSA.
Definition alsaclient.h:235
void output(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event using the library output buffer.
MidiPort * createPort()
Create and attach a new MidiPort instance to this client.
void portDetach(MidiPort *port)
Detach a MidiPort instance from this client.
const char * _getDeviceName()
Gets the internal sequencer device name.
void setThisClientInfo(const ClientInfo &val)
Sets the data supplied by the ClientInfo object into the ALSA sequencer client.
ClientInfoList getAvailableClients()
Gets the list of clients from the ALSA sequencer.
void dropOutput()
Clears the client's output buffer and and remove events in sequencer queue.
void dropInput()
Clears the client's input buffer and and remove events in sequencer queue.
void setPoolInput(int size)
Sets the size of the client's input pool.
MidiClient(QObject *parent=0)
Constructor.
int getClientId()
Gets the client ID.
void doEvents()
Dispatch the events received from the Sequencer.
void dropInputBuffer()
Remove all events on user-space input buffer.
QString getClientName()
Gets the client's public name.
void setPoolOutputRoom(int size)
Sets the room size of the client's output pool.
void open(const QString deviceName="default", const int openMode=SND_SEQ_OPEN_DUPLEX, const bool blockMode=false)
Open the sequencer device.
void dropOutputBuffer()
Removes all events on the library output buffer.
void setErrorBounce(bool newValue)
Sets the error-bounce usage of the client.
void disconnectFrom(int myport, int client, int port)
Unsubscribe one port from another arbitrary sequencer client:port.
void synchronizeOutput()
Wait until all sent events are processed.
void setInputBufferSize(size_t newSize)
Sets the size of the library input buffer for the ALSA client.
void updateAvailablePorts()
Update the internal lists of user ports.
void freeClients()
Releases the list of ALSA sequencer's clients.
unsigned short pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
Gets the number of returned events from poll descriptors.
void connectFrom(int myport, int client, int port)
Subscribe one port from another arbitrary sequencer client:port.
void eventReceived(SequencerEvent *ev)
Signal emitted when an event is received.
int outputPending()
Returns the size of pending events on the output buffer.
ClientInfo & getThisClientInfo()
Gets the ClientInfo object holding data about this client.
PoolInfo & getPoolInfo()
Gets a PoolInfo instance with an updated state of the client memory pool.
void portAttach(MidiPort *port)
Attach a MidiPort instance to this client.
void setEventsEnabled(const bool bEnabled)
Enables the notification of received SequencerEvent instances to the listeners registered with addLis...
void addEventFilter(int evtype)
Add an event filter to the client.
void outputDirect(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event directly to the sequencer.
void drainOutput(bool async=false, int timeout=-1)
Drain the library output buffer.
void connectTo(int myport, int client, int port)
Subscribe one port to another arbitrary sequencer client:port.
virtual ~MidiClient()
Destructor.
Port management.
Definition alsaport.h:120
void attach(MidiClient *seq)
Attach the port to a MidiClient instance.
void setMidiClient(MidiClient *seq)
Sets the MidiClient.
Definition alsaport.cpp:600
PortInfo * getPortInfo()
Gets the PortInfo object pointer.
Definition alsaport.cpp:571
Queue management.
Definition alsaqueue.h:189
Class representing a note event with duration.
Definition alsaevent.h:212
Event representing a note-off MIDI event.
Definition alsaevent.h:254
Event representing a note-on MIDI event.
Definition alsaevent.h:239
Event representing a MIDI bender, or pitch wheel event.
Definition alsaevent.h:342
Sequencer Pool information.
Definition alsaclient.h:139
int getInputFree()
Gets the available size on input pool.
void setOutputRoom(int size)
Sets the output room size.
PoolInfo & operator=(const PoolInfo &other)
Assignment operator.
int getSizeOfInfo() const
Gets the size of the client pool object.
int getOutputRoom()
Gets the output room size.
PoolInfo()
Default constructor.
virtual ~PoolInfo()
Destructor.
int getInputPool()
Gets the input pool size.
void setInputPool(int size)
Set the input pool size.
int getClientId()
Gets the client ID for this object.
int getOutputFree()
Gets the available size on output pool.
PoolInfo * clone()
Clone the pool info obeject.
void setOutputPool(int size)
Sets the output pool size.
int getOutputPool()
Gets the output pool size.
ALSA Event representing a change on some ALSA sequencer port on the system.
Definition alsaevent.h:570
Port information container.
Definition alsaport.h:41
void readSubscribers(MidiClient *seq)
Obtains the port subscribers lists.
Definition alsaport.cpp:431
int getClient()
Gets the client number.
Definition alsaport.cpp:145
int getPort()
Gets the port number.
Definition alsaport.cpp:156
void setClient(int client)
Sets the client number.
Definition alsaport.cpp:275
unsigned int getCapability()
Gets the capabilities bitmap.
Definition alsaport.cpp:189
void setClientName(QString name)
Sets the client name.
Definition alsaport.h:99
void setPort(int port)
Set the port number.
Definition alsaport.cpp:286
Event representing a MIDI program change event.
Definition alsaevent.h:323
ALSA Event representing a queue control command.
Definition alsaevent.h:456
Auxiliary class to remove events from an ALSA queue.
Definition alsaevent.h:587
Base class for the event's hierarchy.
Definition alsaevent.h:54
snd_seq_event_t * getHandle()
Gets the handle of the event.
Definition alsaevent.h:123
ALSA Event representing a subscription between two ALSA clients and ports.
Definition alsaevent.h:529
Event representing a MIDI system exclusive event.
Definition alsaevent.h:402
System information.
Definition alsaclient.h:108
int getSizeOfInfo() const
Get the system's info object size.
int getMaxQueues()
Get the system's maximum number of queues.
int getCurrentQueues()
Get the system's current number of queues.
int getMaxPorts()
Get the system's maximum number of ports.
int getMaxChannels()
Get the system's maximum number of channels.
SystemInfo * clone()
Clone the system info object.
virtual ~SystemInfo()
Destructor.
SystemInfo & operator=(const SystemInfo &other)
Assignment operator.
int getCurrentClients()
Get the system's current number of clients.
int getMaxClients()
Get the system's maximum number of clients.
SystemInfo()
Default constructor.
ALSA Event representing a tempo change for an ALSA queue.
Definition alsaevent.h:514
Generic event having a value property.
Definition alsaevent.h:495
#define CHECK_ERROR(x)
This macro calls the check error function.
#define CHECK_WARNING(x)
This macro calls the check warning function.