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> 38 #define RLIMIT_RTTIME 15 41 #ifndef SCHED_RESET_ON_FORK 42 #define SCHED_RESET_ON_FORK 0x40000000 45 #ifndef DEFAULT_INPUT_TIMEOUT 46 #define DEFAULT_INPUT_TIMEOUT 500 199 void setRealtimePriority();
205 QReadWriteLock m_mutex;
208 class MidiClient::MidiClientPrivate
211 MidiClientPrivate() :
212 m_eventsEnabled(
false),
214 m_NeedRefreshClientList(
true),
215 m_OpenMode(SND_SEQ_OPEN_DUPLEX),
216 m_DeviceName(
"default"),
223 bool m_eventsEnabled;
225 bool m_NeedRefreshClientList;
227 QString m_DeviceName;
228 snd_seq_t* m_SeqHandle;
229 QPointer<SequencerInputThread> m_Thread;
230 QPointer<MidiQueue> m_Queue;
238 QObjectList m_listeners;
260 d(new MidiClientPrivate)
276 if (d->m_Thread != 0)
288 return d->m_SeqHandle;
296 return (d->m_SeqHandle != NULL);
304 return d->m_DeviceName;
312 return d->m_OpenMode;
320 return d->m_BlockMode;
328 return d->m_eventsEnabled;
336 d->m_handler = handler;
350 if (d->m_Thread == 0) {
352 d->m_Thread->m_RealTime = enable;
363 if (d->m_Thread == 0)
365 return d->m_Thread->m_RealTime;
391 const bool blockMode)
393 CHECK_ERROR( snd_seq_open( &d->m_SeqHandle, deviceName.toLocal8Bit().data(),
394 openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) );
395 CHECK_WARNING( snd_seq_get_client_info( d->m_SeqHandle, d->m_Info.m_Info ) );
396 d->m_DeviceName = deviceName;
397 d->m_OpenMode = openMode;
398 d->m_BlockMode = blockMode;
423 const QString deviceName,
425 const bool blockMode )
428 deviceName.toLocal8Bit().data(),
430 blockMode ? 0 : SND_SEQ_NONBLOCK,
432 CHECK_WARNING( snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info));
433 d->m_DeviceName = deviceName;
434 d->m_OpenMode = openMode;
435 d->m_BlockMode = blockMode;
448 if (d->m_SeqHandle != NULL) {
451 d->m_SeqHandle = NULL;
466 return snd_seq_get_output_buffer_size(d->m_SeqHandle);
481 CHECK_WARNING(snd_seq_set_output_buffer_size(d->m_SeqHandle, newSize));
496 return snd_seq_get_input_buffer_size(d->m_SeqHandle);
511 CHECK_WARNING(snd_seq_set_input_buffer_size(d->m_SeqHandle, newSize));
527 if (d->m_BlockMode != newValue)
529 d->m_BlockMode = newValue;
530 if (d->m_SeqHandle != NULL)
532 CHECK_WARNING(snd_seq_nonblock(d->m_SeqHandle, d->m_BlockMode ? 0 : 1));
558 return snd_seq_type(d->m_SeqHandle);
586 snd_seq_event_t* evp = NULL;
588 err = snd_seq_event_input(d->m_SeqHandle, &evp);
589 if ((err >= 0) && (evp != NULL)) {
592 case SND_SEQ_EVENT_NOTE:
596 case SND_SEQ_EVENT_NOTEON:
600 case SND_SEQ_EVENT_NOTEOFF:
604 case SND_SEQ_EVENT_KEYPRESS:
608 case SND_SEQ_EVENT_CONTROLLER:
609 case SND_SEQ_EVENT_CONTROL14:
610 case SND_SEQ_EVENT_REGPARAM:
611 case SND_SEQ_EVENT_NONREGPARAM:
615 case SND_SEQ_EVENT_PGMCHANGE:
619 case SND_SEQ_EVENT_CHANPRESS:
623 case SND_SEQ_EVENT_PITCHBEND:
627 case SND_SEQ_EVENT_SYSEX:
631 case SND_SEQ_EVENT_PORT_SUBSCRIBED:
632 case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
636 case SND_SEQ_EVENT_PORT_CHANGE:
637 case SND_SEQ_EVENT_PORT_EXIT:
638 case SND_SEQ_EVENT_PORT_START:
640 d->m_NeedRefreshClientList =
true;
643 case SND_SEQ_EVENT_CLIENT_CHANGE:
644 case SND_SEQ_EVENT_CLIENT_EXIT:
645 case SND_SEQ_EVENT_CLIENT_START:
647 d->m_NeedRefreshClientList =
true;
650 case SND_SEQ_EVENT_SONGPOS:
651 case SND_SEQ_EVENT_SONGSEL:
652 case SND_SEQ_EVENT_QFRAME:
653 case SND_SEQ_EVENT_TIMESIGN:
654 case SND_SEQ_EVENT_KEYSIGN:
658 case SND_SEQ_EVENT_SETPOS_TICK:
659 case SND_SEQ_EVENT_SETPOS_TIME:
660 case SND_SEQ_EVENT_QUEUE_SKEW:
664 case SND_SEQ_EVENT_TEMPO:
673 if (d->m_handler != NULL) {
674 d->m_handler->handleSequencerEvent(event->clone());
677 if (d->m_eventsEnabled) {
678 QObjectList::Iterator it;
679 for(it=d->m_listeners.begin(); it!=d->m_listeners.end(); ++it) {
681 QCoreApplication::postEvent(sub, event->clone());
691 while (snd_seq_event_input_pending(d->m_SeqHandle, 0) > 0);
700 if (d->m_Thread == 0) {
703 d->m_Thread->start( d->m_Thread->m_RealTime ?
704 QThread::TimeCriticalPriority : QThread::InheritPriority );
714 if (d->m_Thread != 0) {
715 if (d->m_Thread->isRunning()) {
717 while (!d->m_Thread->wait(500) && (counter < 10)) {
720 if (!d->m_Thread->isFinished()) {
721 d->m_Thread->terminate();
737 while (snd_seq_query_next_client(d->m_SeqHandle, cInfo.m_Info) >= 0) {
739 d->m_ClientList.append(cInfo);
741 d->m_NeedRefreshClientList =
false;
750 d->m_ClientList.clear();
760 if (d->m_NeedRefreshClientList)
773 snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info);
788 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
797 if (d->m_SeqHandle != NULL) {
798 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
809 return d->m_Info.getName();
820 ClientInfoList::Iterator it;
821 if (d->m_NeedRefreshClientList)
823 for (it = d->m_ClientList.begin(); it != d->m_ClientList.end(); ++it) {
824 if ((*it).getClientId() == clientId) {
825 return (*it).getName();
838 if (newName != d->m_Info.getName()) {
839 d->m_Info.setName(newName);
873 if (d->m_SeqHandle != NULL) {
874 CHECK_ERROR(snd_seq_create_port(d->m_SeqHandle, port->m_Info.m_Info));
875 d->m_Ports.push_back(port);
886 if (d->m_SeqHandle != NULL) {
894 MidiPortList::iterator it;
895 for(it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it)
899 d->m_Ports.erase(it);
911 if (d->m_SeqHandle != NULL) {
912 MidiPortList::iterator it;
913 for (it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it) {
914 CHECK_ERROR(snd_seq_delete_port(d->m_SeqHandle, (*it)->getPortInfo()->getPort()));
915 (*it)->setMidiClient(NULL);
916 d->m_Ports.erase(it);
928 snd_seq_set_client_event_filter(d->m_SeqHandle, evtype);
939 return d->m_Info.getBroadcastFilter();
950 d->m_Info.setBroadcastFilter(newValue);
962 return d->m_Info.getErrorBounce();
973 d->m_Info.setErrorBounce(newValue);
996 npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
997 pfds = (pollfd*) alloca(npfds *
sizeof(pollfd));
998 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
999 while (snd_seq_event_output(d->m_SeqHandle, ev->
getHandle()) < 0)
1001 poll(pfds, npfds, timeout);
1024 npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1025 pfds = (pollfd*) alloca(npfds *
sizeof(pollfd));
1026 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1027 while (snd_seq_event_output_direct(d->m_SeqHandle, ev->
getHandle()) < 0)
1029 poll(pfds, npfds, timeout);
1066 npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1067 pfds = (pollfd*) alloca(npfds *
sizeof(pollfd));
1068 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1069 while (snd_seq_drain_output(d->m_SeqHandle) < 0)
1071 poll(pfds, npfds, timeout);
1084 snd_seq_sync_output_queue(d->m_SeqHandle);
1095 if (d->m_Queue == NULL) {
1108 if (d->m_Queue != NULL) {
1124 if (d->m_Queue != NULL) {
1127 d->m_Queue =
new MidiQueue(
this, queueName,
this);
1141 if (d->m_Queue != NULL) {
1144 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1158 if (d->m_Queue != NULL) {
1162 if ( queue_id >= 0) {
1163 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1177 if (d->m_Queue != NULL) {
1180 queue->setParent(
this);
1194 snd_seq_queue_info_t* qinfo;
1195 snd_seq_queue_info_alloca(&qinfo);
1197 for ( q = 0; q < max; ++q ) {
1198 err = snd_seq_get_queue_info(d->m_SeqHandle, q, qinfo);
1217 ClientInfoList::ConstIterator itc;
1218 PortInfoList::ConstIterator itp;
1220 if (d->m_NeedRefreshClientList)
1223 for (itc = d->m_ClientList.constBegin(); itc != d->m_ClientList.constEnd(); ++itc) {
1225 if ((ci.
getClientId() == SND_SEQ_CLIENT_SYSTEM) ||
1229 for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) {
1232 if ( ((filter & cap) != 0) &&
1233 ((SND_SEQ_PORT_CAP_NO_EXPORT & cap) == 0) ) {
1247 d->m_InputsAvail.clear();
1248 d->m_OutputsAvail.clear();
1249 d->m_InputsAvail =
filterPorts( SND_SEQ_PORT_CAP_READ |
1250 SND_SEQ_PORT_CAP_SUBS_READ );
1251 d->m_OutputsAvail =
filterPorts( SND_SEQ_PORT_CAP_WRITE |
1252 SND_SEQ_PORT_CAP_SUBS_WRITE );
1262 d->m_NeedRefreshClientList =
true;
1264 return d->m_InputsAvail;
1274 d->m_NeedRefreshClientList =
true;
1276 return d->m_OutputsAvail;
1288 d->m_listeners.append(listener);
1299 d->m_listeners.removeAll(listener);
1311 if (bEnabled != d->m_eventsEnabled) {
1312 d->m_eventsEnabled = bEnabled;
1323 snd_seq_system_info(d->m_SeqHandle, d->m_sysInfo.m_Info);
1324 return d->m_sysInfo;
1334 snd_seq_get_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info);
1335 return d->m_poolInfo;
1345 d->m_poolInfo = info;
1346 CHECK_WARNING(snd_seq_set_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info));
1376 CHECK_WARNING(snd_seq_set_client_pool_input(d->m_SeqHandle, size));
1386 CHECK_WARNING(snd_seq_set_client_pool_output(d->m_SeqHandle, size));
1396 CHECK_WARNING(snd_seq_set_client_pool_output_room(d->m_SeqHandle, size));
1454 CHECK_WARNING(snd_seq_remove_events(d->m_SeqHandle, spec->m_Info));
1464 snd_seq_event_t* ev;
1465 if (
CHECK_WARNING(snd_seq_extract_output(d->m_SeqHandle, &ev) == 0)) {
1479 return snd_seq_event_output_pending(d->m_SeqHandle);
1498 return snd_seq_event_input_pending(d->m_SeqHandle, fetch ? 1 : 0);
1510 return snd_seq_query_named_queue(d->m_SeqHandle, name.toLocal8Bit().data());
1521 return snd_seq_poll_descriptors_count(d->m_SeqHandle, events);
1541 return snd_seq_poll_descriptors(d->m_SeqHandle, pfds, space, events);
1553 unsigned short revents;
1554 CHECK_WARNING( snd_seq_poll_descriptors_revents( d->m_SeqHandle,
1567 return snd_seq_name(d->m_SeqHandle);
1577 CHECK_WARNING(snd_seq_set_client_name(d->m_SeqHandle, name));
1592 return CHECK_WARNING( snd_seq_create_simple_port( d->m_SeqHandle,
1593 name, caps, type ));
1603 CHECK_WARNING( snd_seq_delete_simple_port( d->m_SeqHandle, port ));
1615 CHECK_WARNING( snd_seq_connect_from(d->m_SeqHandle, myport, client, port ));
1627 CHECK_WARNING( snd_seq_connect_to(d->m_SeqHandle, myport, client, port ));
1639 CHECK_WARNING( snd_seq_disconnect_from(d->m_SeqHandle, myport, client, port ));
1651 CHECK_WARNING( snd_seq_disconnect_to(d->m_SeqHandle, myport, client, port ));
1669 QString testClient, testPort;
1670 ClientInfoList::ConstIterator cit;
1671 int pos = straddr.indexOf(
':');
1673 testClient = straddr.left(pos);
1674 testPort = straddr.mid(pos+1);
1676 testClient = straddr;
1679 addr.client = testClient.toInt(&ok);
1681 addr.port = testPort.toInt(&ok);
1683 if (d->m_NeedRefreshClientList)
1685 for ( cit = d->m_ClientList.constBegin();
1686 cit != d->m_ClientList.constEnd(); ++cit ) {
1688 if (testClient.compare(ci.
getName(), Qt::CaseInsensitive) == 0) {
1690 addr.port = testPort.toInt(&ok);
1705 QReadLocker locker(&m_mutex);
1715 QWriteLocker locker(&m_mutex);
1719 #if defined(RTKIT_SUPPORT) 1720 static pid_t _gettid(
void) {
1721 return (pid_t) ::syscall(SYS_gettid);
1726 MidiClient::SequencerInputThread::setRealtimePriority()
1728 struct sched_param p;
1729 int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK;
1730 quint32 priority = 6;
1731 #if defined(RTKIT_SUPPORT) 1735 struct rlimit old_limit, new_limit;
1736 long long max_rttime;
1739 ::memset(&p, 0,
sizeof(p));
1740 p.sched_priority = priority;
1741 rt = ::pthread_setschedparam(::pthread_self(), policy, &p);
1743 #if defined(RTKIT_SUPPORT) 1744 const QString rtkit_service =
1745 QLatin1String(
"org.freedesktop.RealtimeKit1");
1746 const QString rtkit_path =
1747 QLatin1String(
"/org/freedesktop/RealtimeKit1");
1748 const QString rtkit_iface = rtkit_service;
1750 QDBusConnection bus = QDBusConnection::systemBus();
1751 QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus);
1752 QVariant maxRTPrio = realtimeKit.property(
"MaxRealtimePriority");
1753 max_prio = maxRTPrio.toUInt(&ok);
1755 qWarning() <<
"invalid property RealtimeKit.MaxRealtimePriority";
1758 if (priority > max_prio)
1759 priority = max_prio;
1760 QVariant maxRTNSec = realtimeKit.property(
"RTTimeNSecMax");
1761 max_rttime = maxRTNSec.toLongLong(&ok);
1762 if (!ok || max_rttime < 0) {
1763 qWarning() <<
"invalid property RealtimeKit.RTTimeNSecMax";
1766 new_limit.rlim_cur = new_limit.rlim_max = max_rttime;
1767 rt = ::getrlimit(RLIMIT_RTTIME, &old_limit);
1769 qWarning() <<
"getrlimit() failed. err=" << rt << ::strerror(rt);
1772 rt = ::setrlimit(RLIMIT_RTTIME, &new_limit);
1774 qWarning() <<
"setrlimit() failed, err=" << rt << ::strerror(rt);
1777 QDBusMessage reply = realtimeKit.call(
"MakeThreadRealtime", thread, priority);
1778 if (reply.type() == QDBusMessage::ErrorMessage )
1779 qWarning() <<
"error returned by RealtimeKit.MakeThreadRealtime:" 1780 << reply.errorMessage();
1782 qWarning() <<
"pthread_setschedparam() failed, err=" 1783 << rt << ::strerror(rt);
1796 if ( priority() == TimeCriticalPriority )
1797 setRealtimePriority();
1799 if (m_MidiClient != NULL) {
1800 npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN);
1801 pfd = (pollfd *) alloca(npfd *
sizeof(pollfd));
1804 snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN);
1805 while (!stopped() && (m_MidiClient != NULL))
1807 int rt = poll(pfd, npfd, m_Wait);
1809 m_MidiClient->doEvents();
1815 qWarning() <<
"exception in input thread";
1825 snd_seq_client_info_malloc(&m_Info);
1834 snd_seq_client_info_malloc(&m_Info);
1835 snd_seq_client_info_copy(m_Info, other.m_Info);
1836 m_Ports = other.m_Ports;
1845 snd_seq_client_info_malloc(&m_Info);
1846 snd_seq_client_info_copy(m_Info, other);
1856 snd_seq_client_info_malloc(&m_Info);
1857 snd_seq_get_any_client_info(seq->
getHandle(), id, m_Info);
1866 snd_seq_client_info_free(m_Info);
1887 snd_seq_client_info_copy(m_Info, other.m_Info);
1888 m_Ports = other.m_Ports;
1899 return snd_seq_client_info_get_client(m_Info);
1906 snd_seq_client_type_t
1909 return snd_seq_client_info_get_type(m_Info);
1919 return QString(snd_seq_client_info_get_name(m_Info));
1929 return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0);
1939 return (snd_seq_client_info_get_error_bounce(m_Info) != 0);
1947 const unsigned char*
1950 return snd_seq_client_info_get_event_filter(m_Info);
1960 return snd_seq_client_info_get_num_ports(m_Info);
1970 return snd_seq_client_info_get_event_lost(m_Info);
1980 snd_seq_client_info_set_client(m_Info, client);
1990 snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data());
2000 snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0);
2010 snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0);
2021 snd_seq_client_info_set_event_filter(m_Info, filter);
2036 while (snd_seq_query_next_port(seq->
getHandle(), info.m_Info) >= 0) {
2038 m_Ports.append(info);
2069 return snd_seq_client_info_sizeof();
2072 #if SND_LIB_VERSION > 0x010010 2079 ClientInfo::addFilter(
int eventType)
2081 snd_seq_client_info_event_filter_add(m_Info, eventType);
2090 ClientInfo::isFiltered(
int eventType)
2092 return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0);
2099 ClientInfo::clearFilter()
2101 snd_seq_client_info_event_filter_clear(m_Info);
2109 ClientInfo::removeFilter(
int eventType)
2111 snd_seq_client_info_event_filter_del(m_Info, eventType);
2120 snd_seq_system_info_malloc(&m_Info);
2129 snd_seq_system_info_malloc(&m_Info);
2130 snd_seq_system_info_copy(m_Info, other.m_Info);
2139 snd_seq_system_info_malloc(&m_Info);
2140 snd_seq_system_info_copy(m_Info, other);
2149 snd_seq_system_info_malloc(&m_Info);
2150 snd_seq_system_info(seq->
getHandle(), m_Info);
2158 snd_seq_system_info_free(m_Info);
2179 snd_seq_system_info_copy(m_Info, other.m_Info);
2189 return snd_seq_system_info_get_clients(m_Info);
2198 return snd_seq_system_info_get_ports(m_Info);
2207 return snd_seq_system_info_get_queues(m_Info);
2216 return snd_seq_system_info_get_channels(m_Info);
2225 return snd_seq_system_info_get_cur_queues(m_Info);
2234 return snd_seq_system_info_get_cur_clients(m_Info);
2243 return snd_seq_system_info_sizeof();
2251 snd_seq_client_pool_malloc(&m_Info);
2260 snd_seq_client_pool_malloc(&m_Info);
2261 snd_seq_client_pool_copy(m_Info, other.m_Info);
2270 snd_seq_client_pool_malloc(&m_Info);
2271 snd_seq_client_pool_copy(m_Info, other);
2280 snd_seq_client_pool_malloc(&m_Info);
2281 snd_seq_get_client_pool(seq->
getHandle(), m_Info);
2289 snd_seq_client_pool_free(m_Info);
2309 snd_seq_client_pool_copy(m_Info, other.m_Info);
2320 return snd_seq_client_pool_get_client(m_Info);
2330 return snd_seq_client_pool_get_input_free(m_Info);
2340 return snd_seq_client_pool_get_input_pool(m_Info);
2350 return snd_seq_client_pool_get_output_free(m_Info);
2360 return snd_seq_client_pool_get_output_pool(m_Info);
2371 return snd_seq_client_pool_get_output_room(m_Info);
2381 snd_seq_client_pool_set_input_pool(m_Info, size);
2391 snd_seq_client_pool_set_output_pool(m_Info, size);
2403 snd_seq_client_pool_set_output_room(m_Info, size);
2413 return snd_seq_client_pool_sizeof();
2416 #if SND_LIB_VERSION > 0x010004 2423 getRuntimeALSALibraryVersion()
2425 return QString(snd_asoundlib_version());
2434 getRuntimeALSALibraryNumber()
2436 QRegExp rx(
"(\\d+)");
2437 QString str = getRuntimeALSALibraryVersion();
2439 int pos = 0, result = 0, j = 0;
2440 while ((pos = rx.indexIn(str, pos)) != -1 && j < 3) {
2441 int v = rx.cap(1).toInt(&ok);
2446 pos += rx.matchedLength();
2451 #endif // SND_LIB_VERSION > 0x010004 2461 QRegExp rx(
".*Driver Version.*([\\d\\.]+).*");
2463 QFile f(
"/proc/asound/version");
2464 if (f.open(QFile::ReadOnly)) {
2465 QTextStream str(&f);
2466 if (rx.exactMatch(str.readLine().trimmed()))
2480 QRegExp rx(
"(\\d+)");
2483 int pos = 0, result = 0, j = 0;
2484 while ((pos = rx.indexIn(str, pos)) != -1 && j < 3) {
2485 int v = rx.cap(1).toInt(&ok);
2490 pos += rx.matchedLength();
void setClient(int client)
Sets the client number.
snd_seq_event_t * getHandle()
Gets the handle of the event.
MidiPort * createPort()
Create and attach a new MidiPort instance to this client.
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 setInputPool(int size)
Set the input pool size.
ALSA Event representing a queue control command.
int outputPending()
Returns the size of pending events on the output buffer.
void eventReceived(SequencerEvent *ev)
Signal emitted when an event is received.
QList< ClientInfo > ClientInfoList
List of sequencer client information.
void setBlockMode(bool newValue)
Change the blocking mode of the client.
void close()
Close the sequencer device.
void updateAvailablePorts()
Update the internal lists of user ports.
void portDetach(MidiPort *port)
Detach a MidiPort instance from this client.
void dropInputBuffer()
Remove all events on user-space input buffer.
Classes managing ALSA Sequencer clients.
void disconnectFrom(int myport, int client, int port)
Unsubscribe one port from another arbitrary sequencer client:port.
void setName(QString name)
Sets the client name.
bool parseAddress(const QString &straddr, snd_seq_addr &result)
Parse a text address representation, returning an ALSA address record.
void addListener(QObject *listener)
Adds a QObject to the listeners list.
int getMaxQueues()
Get the system's maximum number of queues.
void setErrorBounce(bool newValue)
Sets the error-bounce usage of the client.
virtual ~ClientInfo()
Destructor.
void setBroadcastFilter(bool val)
Sets the broadcast filter.
Generic event having a value property.
PoolInfo & getPoolInfo()
Gets a PoolInfo instance with an updated state of the client memory pool.
PoolInfo & operator=(const PoolInfo &other)
Assignment operator.
size_t getInputBufferSize()
Gets the size of the library input buffer for the ALSA client.
int getPollDescriptorsCount(short events)
Returns the number of poll descriptors.
bool isOpened()
Returns true if the sequencer is opened.
snd_seq_t * getHandle()
Returns the sequencer handler managed by ALSA.
int getSizeOfInfo() const
Gets the size of the internal object.
virtual ~MidiClient()
Destructor.
void setClientName(QString const &newName)
Changes the public name of the ALSA sequencer client.
virtual ~SystemInfo()
Destructor.
PortInfoList getAvailableOutputs()
Gets the available user output ports in the system.
void freeClients()
Releases the list of ALSA sequencer's clients.
void setClient(int client)
Sets the client identifier number.
void disconnectTo(int myport, int client, int port)
Unsubscribe one port to another arbitrary sequencer client:port.
void setOutputBufferSize(size_t newSize)
Sets the size of the library output buffer for the ALSA client.
const unsigned char * getEventFilter() __attribute__((deprecated))
Gets the client's event filter.
int createSimplePort(const char *name, unsigned int caps, unsigned int type)
Create an ALSA sequencer port, without using MidiPort.
void _setClientName(const char *name)
Sets the client name.
Event representing a MIDI control change event.
MidiQueue * createQueue()
Create and return a new MidiQueue associated to this client.
bool getBlockMode()
Returns the last block mode used in open()
void connectTo(int myport, int client, int port)
Subscribe one port to another arbitrary sequencer client:port.
MidiPortList getMidiPorts() const
Gets the list of MidiPort instances belonging to this client.
MidiQueue * useQueue(int queue_id)
Create a new MidiQueue instance using a queue already existing in the system, associating it to the c...
SystemInfo()
Default constructor.
ALSA Event representing a change on some ALSA sequencer client on the system.
void setEventFilter(unsigned char *filter) __attribute__((deprecated))
Sets the event filter.
int getMaxPorts()
Get the system's maximum number of ports.
The QObject class is the base class of all Qt objects.
Base class for the event's hierarchy.
Event representing a MIDI system exclusive event.
int getInputFree()
Gets the available size on input pool.
int getSizeOfInfo() const
Get the system's info object size.
void freePorts()
Release the ports list.
snd_seq_client_type_t getClientType()
Gets the client's type.
bool getBroadcastFilter()
Gets the broadcast filter usage of the client.
void setPoolOutputRoom(int size)
Sets the room size of the client's output pool.
void doEvents()
Dispatch the events received from the Sequencer.
void drainOutput(bool async=false, int timeout=-1)
Drain the library output buffer.
void stopSequencerInput()
Stops reading events from the ALSA sequencer.
void setRealTimeInput(bool enabled)
Enables real-time priority for the MIDI input thread.
void attach(MidiClient *seq)
Attach the port to a MidiClient instance.
virtual ~PoolInfo()
Destructor.
int getClient()
Gets the client number.
QList< PortInfo > PortInfoList
List of port information objects.
void readPorts(MidiClient *seq)
Read the client ports.
int getEventLost()
Gets the number of lost events.
int getOutputRoom()
Gets the output room size.
int getMaxClients()
Get the system's maximum number of clients.
int getSizeOfInfo() const
Gets the size of the client pool object.
bool realTimeInputEnabled()
Return the real-time priority setting for the MIDI input thread.
void setHandler(SequencerEventHandler *handler)
Sets a sequencer event handler enabling the callback delivery mode.
void setClientName(QString name)
Sets the client name.
Sequencer Pool information.
void setMidiClient(MidiClient *seq)
Sets the MidiClient.
void setPoolOutput(int size)
Sets the size of the client's output pool.
void deleteSimplePort(int port)
Remove an ALSA sequencer port.
void setBroadcastFilter(bool newValue)
Sets the broadcast filter usage of the client.
void resetPoolInput()
Resets the client input pool.
void setPoolInfo(const PoolInfo &info)
Applies (updates) the client's PoolInfo data into the system.
bool getBroadcastFilter()
Gets the client's broadcast filter.
Sequencer events handler.
bool getErrorBounce()
Gets the client's error bounce.
void setThisClientInfo(const ClientInfo &val)
Sets the data supplied by the ClientInfo object into the ALSA sequencer client.
int getClientId()
Gets the client's numeric identifier.
int inputPending(bool fetch)
Gets the size of the events on the input buffer.
void connectFrom(int myport, int client, int port)
Subscribe one port from another arbitrary sequencer client:port.
ALSA Event representing a change on some ALSA sequencer port on the system.
Event representing a MIDI key pressure, or polyphonic after-touch event.
ALSA Event representing a tempo change for an ALSA queue.
Event representing a MIDI program change event.
int getCurrentClients()
Get the system's current number of clients.
ClientInfoList getAvailableClients()
Gets the list of clients from the ALSA sequencer.
QList< int > getAvailableQueues()
Get a list of the existing queues.
unsigned int getCapability()
Gets the capabilities bitmap.
void detachAllPorts()
Detach all the ports belonging to this client.
QString getClientName()
Gets the client's public name.
int getRuntimeALSADriverNumber()
Gets the runtime ALSA drivers version number.
int getCurrentQueues()
Get the system's current number of queues.
void setErrorBounce(bool val)
Sets the error bounce.
void resetPoolOutput()
Resets the client output pool.
MidiClient(QObject *parent=0)
Constructor.
void dropOutputBuffer()
Removes all events on the library output buffer.
void readSubscribers(MidiClient *seq)
Obtains the port subscribers lists.
void removeEvents(const RemoveEvents *spec)
Removes events on input/output buffers and pools.
PortInfoList getPorts() const
Gets the ports list.
int getClientId()
Gets the client ID for this object.
int pollDescriptors(struct pollfd *pfds, unsigned int space, short events)
Get poll descriptors.
Auxiliary class to remove events from an ALSA queue.
int getOpenMode()
Returns the last open mode used in open()
void readClients()
Reads the ALSA sequencer's clients list.
Class representing a note event with duration.
PortInfo * getPortInfo()
Gets the PortInfo object pointer.
SystemInfo & operator=(const SystemInfo &other)
Assignment operator.
snd_seq_type_t getSequencerType()
Returns the type snd_seq_type_t of the given sequencer handle.
ClientInfo()
Default constructor.
unsigned short pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
Gets the number of returned events from poll descriptors.
SystemInfo & getSystemInfo()
Gets a SystemInfo instance with the updated state of the system.
PoolInfo()
Default constructor.
ALSA Event representing a subscription between two ALSA clients and ports.
void dropOutput()
Clears the client's output buffer and and remove events in sequencer queue.
void startSequencerInput()
Starts reading events from the ALSA sequencer.
MidiQueue * getQueue()
Get the MidiQueue instance associated to this client.
bool getEventsEnabled() const
Returns true if the events mode of delivery has been enabled.
Event representing a MIDI bender, or pitch wheel event.
bool getErrorBounce()
Get the error-bounce usage of the client.
size_t getOutputBufferSize()
Gets the size of the library output buffer for the ALSA client.
void setOutputPool(int size)
Sets the output pool size.
Port information container.
void outputDirect(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event directly to the sequencer.
void applyClientInfo()
This internal method applies the ClientInfo data to the ALSA sequencer client.
Event representing a note-off MIDI event.
void dropInput()
Clears the client's input buffer and and remove events in sequencer queue.
QString getDeviceName()
Returns the name of the sequencer device.
const char * _getDeviceName()
Gets the internal sequencer device name.
Event representing a MIDI channel pressure or after-touch event.
void setPoolInput(int size)
Sets the size of the client's input pool.
Event representing a note-on MIDI event.
int getOutputPool()
Gets the output pool size.
void setOutputRoom(int size)
Sets the output room size.
void setInputBufferSize(size_t newSize)
Sets the size of the library input buffer for the ALSA client.
void output(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event using the library output buffer.
ClientInfo & operator=(const ClientInfo &other)
Assignment operator.
#define CHECK_ERROR(x)
This macro calls the check error function.
PoolInfo * clone()
Clone the pool info obeject.
int getPort()
Gets the port number.
#define CHECK_WARNING(x)
This macro calls the check warning function.
int getInputPool()
Gets the input pool size.
Classes managing ALSA Sequencer queues.
QString getName()
Gets the client's name.
int getClientId()
Gets the client ID.
QString getRuntimeALSADriverVersion()
Gets the runtime ALSA drivers version string.
int getNumPorts()
Gets the client's port count.
QList< MidiPort * > MidiPortList
List of Ports instances.
void outputBuffer(SequencerEvent *ev)
Output an event using the library output buffer, without draining the buffer.
int getMaxChannels()
Get the system's maximum number of channels.
void synchronizeOutput()
Wait until all sent events are processed.
The QThread class provides platform-independent threads.
int getOutputFree()
Gets the available size on output pool.
Classes managing ALSA Sequencer events.
int getQueueId(const QString &name)
Gets the queue's numeric identifier corresponding to the provided name.
void addEventFilter(int evtype)
Add an event filter to the client.
void removeListener(QObject *listener)
Removes a QObject listener from the listeners list.
SystemInfo * clone()
Clone the system info object.
ClientInfo * clone()
Clone the client info object.
void open(const QString deviceName="default", const int openMode=SND_SEQ_OPEN_DUPLEX, const bool blockMode=false)
Open the sequencer device.
PortInfoList filterPorts(unsigned int filter)
Gets a list of the available user ports in the system, filtered by the given bitmap of desired capabi...
PortInfoList getAvailableInputs()
Gets the available user input ports in the system.
SequencerEvent * extractOutput()
Extracts (and removes) the first event in the output buffer.
void setPort(int port)
Set the port number.
ClientInfo & getThisClientInfo()
Gets the ClientInfo object holding data about this client.