20 #include <QCoreApplication>
22 #include <QReadLocker>
23 #include <QRegularExpression>
25 #include <QWriteLocker>
30 #if defined(RTKIT_SUPPORT)
31 #include <QDBusConnection>
32 #include <QDBusInterface>
33 #include <sys/resource.h>
34 #include <sys/syscall.h>
35 #include <sys/types.h>
40 #define RLIMIT_RTTIME 15
43 #ifndef SCHED_RESET_ON_FORK
44 #define SCHED_RESET_ON_FORK 0x40000000
47 #ifndef DEFAULT_INPUT_TIMEOUT
48 #define DEFAULT_INPUT_TIMEOUT 500
200 void setRealtimePriority();
206 QReadWriteLock m_mutex;
209 class MidiClient::MidiClientPrivate
212 MidiClientPrivate() :
213 m_eventsEnabled(false),
215 m_NeedRefreshClientList(true),
216 m_OpenMode(SND_SEQ_OPEN_DUPLEX),
217 m_DeviceName(
"default"),
218 m_SeqHandle(nullptr),
224 bool m_eventsEnabled;
226 bool m_NeedRefreshClientList;
228 QString m_DeviceName;
229 snd_seq_t* m_SeqHandle;
230 QPointer<SequencerInputThread> m_Thread;
231 QPointer<MidiQueue> m_Queue;
239 QObjectList m_listeners;
261 d(new MidiClientPrivate)
286 return d->m_SeqHandle;
295 return !d.isNull() && (d->m_SeqHandle !=
nullptr);
304 return d->m_DeviceName;
313 return d->m_OpenMode;
322 return d->m_BlockMode;
331 return d->m_eventsEnabled;
340 d->m_handler = handler;
354 if (d->m_Thread ==
nullptr) {
356 d->m_Thread->m_RealTime = enable;
367 if (d->m_Thread ==
nullptr)
369 return d->m_Thread->m_RealTime;
395 const bool blockMode)
398 openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) );
400 d->m_DeviceName = deviceName;
401 d->m_OpenMode = openMode;
402 d->m_BlockMode = blockMode;
427 const QString deviceName,
429 const bool blockMode )
432 deviceName.toLocal8Bit().data(),
434 blockMode ? 0 : SND_SEQ_NONBLOCK,
437 d->m_DeviceName = deviceName;
438 d->m_OpenMode = openMode;
439 d->m_BlockMode = blockMode;
452 if (d->m_SeqHandle !=
nullptr) {
455 d->m_SeqHandle =
nullptr;
470 return snd_seq_get_output_buffer_size(d->m_SeqHandle);
500 return snd_seq_get_input_buffer_size(d->m_SeqHandle);
531 if (d->m_BlockMode != newValue)
533 d->m_BlockMode = newValue;
534 if (d->m_SeqHandle !=
nullptr)
562 return snd_seq_type(d->m_SeqHandle);
590 snd_seq_event_t* evp =
nullptr;
592 err = snd_seq_event_input(d->m_SeqHandle, &evp);
593 if ((err >= 0) && (evp !=
nullptr)) {
596 case SND_SEQ_EVENT_NOTE:
600 case SND_SEQ_EVENT_NOTEON:
604 case SND_SEQ_EVENT_NOTEOFF:
608 case SND_SEQ_EVENT_KEYPRESS:
612 case SND_SEQ_EVENT_CONTROLLER:
613 case SND_SEQ_EVENT_CONTROL14:
614 case SND_SEQ_EVENT_REGPARAM:
615 case SND_SEQ_EVENT_NONREGPARAM:
619 case SND_SEQ_EVENT_PGMCHANGE:
623 case SND_SEQ_EVENT_CHANPRESS:
627 case SND_SEQ_EVENT_PITCHBEND:
631 case SND_SEQ_EVENT_SYSEX:
635 case SND_SEQ_EVENT_PORT_SUBSCRIBED:
636 case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
640 case SND_SEQ_EVENT_PORT_CHANGE:
641 case SND_SEQ_EVENT_PORT_EXIT:
642 case SND_SEQ_EVENT_PORT_START:
644 d->m_NeedRefreshClientList =
true;
647 case SND_SEQ_EVENT_CLIENT_CHANGE:
648 case SND_SEQ_EVENT_CLIENT_EXIT:
649 case SND_SEQ_EVENT_CLIENT_START:
651 d->m_NeedRefreshClientList =
true;
654 case SND_SEQ_EVENT_SONGPOS:
655 case SND_SEQ_EVENT_SONGSEL:
656 case SND_SEQ_EVENT_QFRAME:
657 case SND_SEQ_EVENT_TIMESIGN:
658 case SND_SEQ_EVENT_KEYSIGN:
662 case SND_SEQ_EVENT_SETPOS_TICK:
663 case SND_SEQ_EVENT_SETPOS_TIME:
664 case SND_SEQ_EVENT_QUEUE_SKEW:
668 case SND_SEQ_EVENT_TEMPO:
677 if (d->m_handler !=
nullptr) {
678 d->m_handler->handleSequencerEvent(event->clone());
681 if (d->m_eventsEnabled) {
682 QObjectList::Iterator it;
683 for(it=d->m_listeners.begin(); it!=d->m_listeners.end(); ++it) {
685 QCoreApplication::postEvent(sub, event->clone());
695 while (snd_seq_event_input_pending(d->m_SeqHandle, 0) > 0);
704 if (d->m_Thread ==
nullptr) {
707 d->m_Thread->start( d->m_Thread->m_RealTime ?
708 QThread::TimeCriticalPriority : QThread::InheritPriority );
718 if (d->m_Thread !=
nullptr) {
719 if (d->m_Thread->isRunning()) {
721 while (!d->m_Thread->wait(500) && (counter < 10)) {
724 if (!d->m_Thread->isFinished()) {
725 d->m_Thread->terminate();
741 while (snd_seq_query_next_client(d->m_SeqHandle, cInfo.m_Info) >= 0) {
743 d->m_ClientList.append(cInfo);
745 d->m_NeedRefreshClientList =
false;
754 d->m_ClientList.clear();
764 if (d->m_NeedRefreshClientList)
777 snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info);
792 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
801 if (d->m_SeqHandle !=
nullptr) {
802 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
813 return d->m_Info.getName();
824 ClientInfoList::Iterator it;
825 if (d->m_NeedRefreshClientList)
827 for (it = d->m_ClientList.begin(); it != d->m_ClientList.end(); ++it) {
828 if ((*it).getClientId() == clientId) {
829 return (*it).getName();
842 if (newName != d->m_Info.getName()) {
843 d->m_Info.setName(newName);
877 if (d->m_SeqHandle !=
nullptr) {
879 d->m_Ports.push_back(port);
890 if (d->m_SeqHandle !=
nullptr) {
898 MidiPortList::iterator it;
899 for(it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it)
903 d->m_Ports.erase(it);
915 if (d->m_SeqHandle !=
nullptr) {
916 QMutableListIterator<MidiPort*> it(d->m_Ports);
917 while (it.hasNext()) {
933 snd_seq_set_client_event_filter(d->m_SeqHandle, evtype);
944 return d->m_Info.getBroadcastFilter();
955 d->m_Info.setBroadcastFilter(newValue);
967 return d->m_Info.getErrorBounce();
978 d->m_Info.setErrorBounce(newValue);
996 pollfd* pfds =
nullptr;
1000 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1001 pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1002 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1003 while (snd_seq_event_output(d->m_SeqHandle, ev->
getHandle()) < 0)
1005 poll(pfds, npfds, timeout);
1027 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1028 pollfd* pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1029 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1030 while (snd_seq_event_output_direct(d->m_SeqHandle, ev->
getHandle()) < 0)
1032 poll(pfds, npfds, timeout);
1068 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1069 pollfd* pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1070 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1071 while (snd_seq_drain_output(d->m_SeqHandle) < 0)
1073 poll(pfds, npfds, timeout);
1087 snd_seq_sync_output_queue(d->m_SeqHandle);
1098 if (d->m_Queue ==
nullptr) {
1111 if (d->m_Queue !=
nullptr) {
1127 if (d->m_Queue !=
nullptr) {
1130 d->m_Queue =
new MidiQueue(
this, queueName,
this);
1144 if (d->m_Queue !=
nullptr) {
1147 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1161 if (d->m_Queue !=
nullptr) {
1165 if ( queue_id >= 0) {
1166 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1180 if (d->m_Queue !=
nullptr) {
1183 queue->setParent(
this);
1197 snd_seq_queue_info_t* qinfo;
1198 snd_seq_queue_info_alloca(&qinfo);
1200 for ( q = 0; q < max; ++q ) {
1201 err = snd_seq_get_queue_info(d->m_SeqHandle, q, qinfo);
1220 ClientInfoList::ConstIterator itc;
1221 PortInfoList::ConstIterator itp;
1223 if (d->m_NeedRefreshClientList)
1226 for (itc = d->m_ClientList.constBegin(); itc != d->m_ClientList.constEnd(); ++itc) {
1228 if ((ci.
getClientId() == SND_SEQ_CLIENT_SYSTEM) ||
1232 for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) {
1235 if ( ((filter & cap) != 0) &&
1236 ((SND_SEQ_PORT_CAP_NO_EXPORT & cap) == 0) ) {
1250 d->m_InputsAvail.clear();
1251 d->m_OutputsAvail.clear();
1252 d->m_InputsAvail =
filterPorts( SND_SEQ_PORT_CAP_READ |
1253 SND_SEQ_PORT_CAP_SUBS_READ );
1254 d->m_OutputsAvail =
filterPorts( SND_SEQ_PORT_CAP_WRITE |
1255 SND_SEQ_PORT_CAP_SUBS_WRITE );
1265 d->m_NeedRefreshClientList =
true;
1267 return d->m_InputsAvail;
1277 d->m_NeedRefreshClientList =
true;
1279 return d->m_OutputsAvail;
1291 d->m_listeners.append(listener);
1302 d->m_listeners.removeAll(listener);
1314 if (bEnabled != d->m_eventsEnabled) {
1315 d->m_eventsEnabled = bEnabled;
1326 snd_seq_system_info(d->m_SeqHandle, d->m_sysInfo.m_Info);
1327 return d->m_sysInfo;
1337 snd_seq_get_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info);
1338 return d->m_poolInfo;
1348 d->m_poolInfo = info;
1467 snd_seq_event_t* ev;
1482 return snd_seq_event_output_pending(d->m_SeqHandle);
1501 return snd_seq_event_input_pending(d->m_SeqHandle, fetch ? 1 : 0);
1513 return snd_seq_query_named_queue(d->m_SeqHandle, name.toLocal8Bit().data());
1524 return snd_seq_poll_descriptors_count(d->m_SeqHandle, events);
1544 return snd_seq_poll_descriptors(d->m_SeqHandle, pfds, space, events);
1556 unsigned short revents;
1570 return snd_seq_name(d->m_SeqHandle);
1596 name, caps, type ));
1672 QString testClient, testPort;
1673 ClientInfoList::ConstIterator cit;
1674 int pos = straddr.indexOf(
':');
1676 testClient = straddr.left(pos);
1677 testPort = straddr.mid(pos+1);
1679 testClient = straddr;
1682 addr.client = testClient.toInt(&ok);
1684 addr.port = testPort.toInt(&ok);
1686 if (d->m_NeedRefreshClientList)
1688 for ( cit = d->m_ClientList.constBegin();
1689 cit != d->m_ClientList.constEnd(); ++cit ) {
1691 if (testClient.compare(ci.
getName(), Qt::CaseInsensitive) == 0) {
1693 addr.port = testPort.toInt(&ok);
1708 QReadLocker locker(&m_mutex);
1718 QWriteLocker locker(&m_mutex);
1722 #if defined(RTKIT_SUPPORT)
1723 static pid_t _gettid() {
1724 return (pid_t) ::syscall(SYS_gettid);
1729 MidiClient::SequencerInputThread::setRealtimePriority()
1731 struct sched_param p;
1732 int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK;
1733 quint32 priority = 6;
1734 #if defined(RTKIT_SUPPORT)
1738 struct rlimit old_limit, new_limit;
1739 long long max_rttime;
1742 ::memset(&p, 0,
sizeof(p));
1743 p.sched_priority = priority;
1744 rt = ::pthread_setschedparam(::pthread_self(), policy, &p);
1746 #if defined(RTKIT_SUPPORT)
1747 const QString rtkit_service =
1748 QStringLiteral(
"org.freedesktop.RealtimeKit1");
1749 const QString rtkit_path =
1750 QStringLiteral(
"/org/freedesktop/RealtimeKit1");
1751 const QString rtkit_iface = rtkit_service;
1753 QDBusConnection bus = QDBusConnection::systemBus();
1754 QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus);
1755 QVariant maxRTPrio = realtimeKit.property(
"MaxRealtimePriority");
1756 max_prio = maxRTPrio.toUInt(&ok);
1758 qWarning() <<
"invalid property RealtimeKit.MaxRealtimePriority";
1761 if (priority > max_prio)
1762 priority = max_prio;
1763 QVariant maxRTNSec = realtimeKit.property(
"RTTimeNSecMax");
1764 max_rttime = maxRTNSec.toLongLong(&ok);
1765 if (!ok || max_rttime < 0) {
1766 qWarning() <<
"invalid property RealtimeKit.RTTimeNSecMax";
1769 new_limit.rlim_cur = new_limit.rlim_max = max_rttime;
1770 rt = ::getrlimit(RLIMIT_RTTIME, &old_limit);
1772 qWarning() <<
"getrlimit() failed. err=" << rt << ::strerror(rt);
1775 rt = ::setrlimit(RLIMIT_RTTIME, &new_limit);
1777 qWarning() <<
"setrlimit() failed, err=" << rt << ::strerror(rt);
1780 QDBusMessage reply = realtimeKit.call(
"MakeThreadRealtime", thread, priority);
1781 if (reply.type() == QDBusMessage::ErrorMessage )
1782 qWarning() <<
"error returned by RealtimeKit.MakeThreadRealtime:"
1783 << reply.errorMessage();
1786 qWarning() <<
"pthread_setschedparam() failed, err="
1787 << rt << ::strerror(rt);
1797 if ( priority() == TimeCriticalPriority ) {
1798 setRealtimePriority();
1800 if (m_MidiClient !=
nullptr) {
1801 int npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN);
1802 pollfd* pfd = (pollfd *) calloc(npfd,
sizeof(pollfd));
1805 snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN);
1806 while (!stopped() && (m_MidiClient !=
nullptr))
1808 int rt = poll(pfd, npfd, m_Wait);
1810 m_MidiClient->doEvents();
1816 qWarning() <<
"exception in input thread";
1827 snd_seq_client_info_malloc(&m_Info);
1836 snd_seq_client_info_malloc(&m_Info);
1837 snd_seq_client_info_copy(m_Info, other.m_Info);
1838 m_Ports = other.m_Ports;
1847 snd_seq_client_info_malloc(&m_Info);
1848 snd_seq_client_info_copy(m_Info, other);
1858 snd_seq_client_info_malloc(&m_Info);
1859 snd_seq_get_any_client_info(seq->
getHandle(),
id, m_Info);
1868 snd_seq_client_info_free(m_Info);
1891 snd_seq_client_info_copy(m_Info, other.m_Info);
1892 m_Ports = other.m_Ports;
1903 return snd_seq_client_info_get_client(m_Info);
1910 snd_seq_client_type_t
1913 return snd_seq_client_info_get_type(m_Info);
1923 return QString(snd_seq_client_info_get_name(m_Info));
1933 return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0);
1943 return (snd_seq_client_info_get_error_bounce(m_Info) != 0);
1951 const unsigned char*
1954 return snd_seq_client_info_get_event_filter(m_Info);
1964 return snd_seq_client_info_get_num_ports(m_Info);
1974 return snd_seq_client_info_get_event_lost(m_Info);
1984 snd_seq_client_info_set_client(m_Info, client);
1994 snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data());
2004 snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0);
2014 snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0);
2025 snd_seq_client_info_set_event_filter(m_Info, filter);
2040 while (snd_seq_query_next_port(seq->
getHandle(), info.m_Info) >= 0) {
2042 m_Ports.append(info);
2073 return snd_seq_client_info_sizeof();
2076 #if SND_LIB_VERSION > 0x010010
2083 ClientInfo::addFilter(
int eventType)
2085 snd_seq_client_info_event_filter_add(m_Info, eventType);
2094 ClientInfo::isFiltered(
int eventType)
2096 return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0);
2103 ClientInfo::clearFilter()
2105 snd_seq_client_info_event_filter_clear(m_Info);
2113 ClientInfo::removeFilter(
int eventType)
2115 snd_seq_client_info_event_filter_del(m_Info, eventType);
2124 snd_seq_system_info_malloc(&m_Info);
2133 snd_seq_system_info_malloc(&m_Info);
2134 snd_seq_system_info_copy(m_Info, other.m_Info);
2143 snd_seq_system_info_malloc(&m_Info);
2144 snd_seq_system_info_copy(m_Info, other);
2153 snd_seq_system_info_malloc(&m_Info);
2154 snd_seq_system_info(seq->
getHandle(), m_Info);
2162 snd_seq_system_info_free(m_Info);
2185 snd_seq_system_info_copy(m_Info, other.m_Info);
2195 return snd_seq_system_info_get_clients(m_Info);
2204 return snd_seq_system_info_get_ports(m_Info);
2213 return snd_seq_system_info_get_queues(m_Info);
2222 return snd_seq_system_info_get_channels(m_Info);
2231 return snd_seq_system_info_get_cur_queues(m_Info);
2240 return snd_seq_system_info_get_cur_clients(m_Info);
2249 return snd_seq_system_info_sizeof();
2257 snd_seq_client_pool_malloc(&m_Info);
2266 snd_seq_client_pool_malloc(&m_Info);
2267 snd_seq_client_pool_copy(m_Info, other.m_Info);
2276 snd_seq_client_pool_malloc(&m_Info);
2277 snd_seq_client_pool_copy(m_Info, other);
2286 snd_seq_client_pool_malloc(&m_Info);
2287 snd_seq_get_client_pool(seq->
getHandle(), m_Info);
2295 snd_seq_client_pool_free(m_Info);
2318 snd_seq_client_pool_copy(m_Info, other.m_Info);
2329 return snd_seq_client_pool_get_client(m_Info);
2339 return snd_seq_client_pool_get_input_free(m_Info);
2349 return snd_seq_client_pool_get_input_pool(m_Info);
2359 return snd_seq_client_pool_get_output_free(m_Info);
2369 return snd_seq_client_pool_get_output_pool(m_Info);
2380 return snd_seq_client_pool_get_output_room(m_Info);
2390 snd_seq_client_pool_set_input_pool(m_Info, size);
2400 snd_seq_client_pool_set_output_pool(m_Info, size);
2412 snd_seq_client_pool_set_output_room(m_Info, size);
2422 return snd_seq_client_pool_sizeof();
2425 #if SND_LIB_VERSION > 0x010004
2432 getRuntimeALSALibraryVersion()
2434 return QString(snd_asoundlib_version());
2443 getRuntimeALSALibraryNumber()
2445 QRegularExpression rx(
"(\\d+)");
2446 QString str = getRuntimeALSALibraryVersion();
2448 int result = 0, j = 0;
2449 QRegularExpressionMatchIterator i = rx.globalMatch(str);
2450 while (i.hasNext() && (j < 3)) {
2451 QRegularExpressionMatch m = i.next();
2452 int v = m.captured(1).toInt(&ok);
2471 QRegularExpression rx(
"([\\d\\.]+)");
2473 QFile f(
"/proc/asound/version");
2474 if (f.open(QFile::ReadOnly)) {
2475 QTextStream str(&f);
2476 QString sub = str.readLine().trimmed();
2477 QRegularExpressionMatch m = rx.match(sub);
2493 QRegularExpression rx(
"(\\d+)");
2496 int result = 0, j = 0;
2497 QRegularExpressionMatchIterator i = rx.globalMatch(str);
2498 while (i.hasNext() && (j < 3)) {
2499 QRegularExpressionMatch m = i.next();
2500 int v = m.captured(1).toInt(&ok);
2520 return QStringLiteral(SND_LIB_VERSION_STR);
2529 return QStringLiteral(QT_STRINGIFY(VERSION));
Classes managing ALSA Sequencer clients.
Classes managing ALSA Sequencer events.
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.
ALSA Event representing a change on some ALSA sequencer client on the system.
Event representing a MIDI control change event.
Event representing a MIDI key pressure, or polyphonic after-touch event.
void eventReceived(drumstick::ALSA::SequencerEvent *ev)
Signal emitted when an event is received.
void attach(MidiClient *seq)
Attach the port to a MidiClient instance.
void setMidiClient(MidiClient *seq)
Sets the MidiClient.
PortInfo * getPortInfo()
Gets the PortInfo object pointer.
Class representing a note event with duration.
Event representing a note-off MIDI event.
Event representing a note-on MIDI event.
Event representing a MIDI bender, or pitch wheel event.
Sequencer Pool information.
ALSA Event representing a change on some ALSA sequencer port on the system.
Port information container.
void readSubscribers(MidiClient *seq)
Obtains the port subscribers lists.
int getClient()
Gets the client number.
int getPort()
Gets the port number.
void setClient(int client)
Sets the client number.
unsigned int getCapability()
Gets the capabilities bitmap.
void setClientName(QString name)
Sets the client name.
void setPort(int port)
Set the port number.
Event representing a MIDI program change event.
ALSA Event representing a queue control command.
Auxiliary class to remove events from an ALSA queue.
Sequencer events handler.
Base class for the event's hierarchy.
snd_seq_event_t * getHandle()
Gets the handle of the event.
ALSA Event representing a subscription between two ALSA clients and ports.
Event representing a MIDI system exclusive event.
ALSA Event representing a tempo change for an ALSA queue.
Generic event having a value property.
Error checking functions and macros.
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 getInputFree()
Gets the available size on input pool.
void setOutputRoom(int size)
Sets the output room size.
int inputPending(bool fetch)
Gets the size of the events on the input buffer.
void setBroadcastFilter(bool val)
Sets the broadcast filter.
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.
QString getDeviceName()
Returns the name of the sequencer device.
bool getEventsEnabled() const
Returns true if the events mode of delivery has been enabled.
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.
PoolInfo & operator=(const PoolInfo &other)
Assignment operator.
int getSizeOfInfo() const
Gets the size of the internal object.
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.
int getMaxQueues()
Get the system's maximum number of queues.
virtual ~ClientInfo()
Destructor.
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.
int getOutputRoom()
Gets the output room size.
void removeListener(QObject *listener)
Removes a QObject listener from the listeners list.
PoolInfo()
Default constructor.
int getCurrentQueues()
Get the system's current number of queues.
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.
int getRuntimeALSADriverNumber()
Gets the runtime ALSA drivers version number.
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.
int getMaxPorts()
Get the system's maximum number of ports.
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.
int getMaxChannels()
Get the system's maximum number of channels.
void readPorts(MidiClient *seq)
Read the client ports.
void setName(QString name)
Sets the client name.
SystemInfo & getSystemInfo()
Gets a SystemInfo instance with the updated state of the system.
QString getRuntimeALSADriverVersion()
Gets the runtime ALSA drivers version string.
Q_DECL_DEPRECATED void setEventFilter(unsigned char *filter)
Sets the event filter.
snd_seq_client_type_t getClientType()
Gets the client's type.
void resetPoolOutput()
Resets the client output pool.
SystemInfo * clone()
Clone the system info object.
virtual ~SystemInfo()
Destructor.
void setErrorBounce(bool val)
Sets the error bounce.
MidiClient(QObject *parent=nullptr)
Constructor.
MidiQueue * getQueue()
Get the MidiQueue instance associated to this client.
virtual ~PoolInfo()
Destructor.
SystemInfo & operator=(const SystemInfo &other)
Assignment operator.
int getInputPool()
Gets the input pool size.
void stop()
Stops the input thread.
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.
QList< ClientInfo > ClientInfoList
List of sequencer client information.
void setPoolOutput(int size)
Sets the size of the client's output pool.
void stopSequencerInput()
Stops reading events from the ALSA sequencer.
ClientInfo()
Default constructor.
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.
void setInputPool(int size)
Set the input pool size.
int getCurrentClients()
Get the system's current number of clients.
snd_seq_t * getHandle()
Returns the sequencer handler managed by ALSA.
void output(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event using the library output buffer.
int getOpenMode()
Returns the last open mode used in open()
MidiPort * createPort()
Create and attach a new MidiPort instance to this client.
void portDetach(MidiPort *port)
Detach a MidiPort instance from this client.
int getNumPorts()
Gets the client's port count.
void setClient(int client)
Sets the client identifier number.
ClientInfo & operator=(const ClientInfo &other)
Assignment operator.
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 setHandler(SequencerEventHandler *handler)
Sets a sequencer event handler enabling the callback delivery mode.
QString getDrumstickLibraryVersion()
getDrumstickLibraryVersion provides the Drumstick version as an edited QString
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.
QString getName()
Gets the client's name.
void setPoolInput(int size)
Sets the size of the client's input pool.
QString getCompiledALSALibraryVersion()
ALSA library version at build time.
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.
int getMaxClients()
Get the system's maximum number of clients.
void setErrorBounce(bool newValue)
Sets the error-bounce usage of the client.
void run() override
Main input thread process loop.
void disconnectFrom(int myport, int client, int port)
Unsubscribe one port from another arbitrary sequencer client:port.
Q_DECL_DEPRECATED const unsigned char * getEventFilter()
Gets the client's event filter.
void synchronizeOutput()
Wait until all sent events are processed.
int getEventLost()
Gets the number of lost events.
void setInputBufferSize(size_t newSize)
Sets the size of the library input buffer for the ALSA client.
SystemInfo()
Default constructor.
PortInfoList getPorts() const
Gets the ports list.
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.
int getOutputFree()
Gets the available size on output pool.
int outputPending()
Returns the size of pending events on the output buffer.
PoolInfo * clone()
Clone the pool info obeject.
bool stopped()
Returns true or false depending on the input thread state.
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 freePorts()
Release the ports list.
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...
bool getBlockMode()
Returns the last block mode used in open()
void addEventFilter(int evtype)
Add an event filter to the client.
void setOutputPool(int size)
Sets the output pool size.
void outputDirect(SequencerEvent *ev, bool async=false, int timeout=-1)
Output an event directly to the sequencer.
int getOutputPool()
Gets the output pool size.
void drainOutput(bool async=false, int timeout=-1)
Drain the library output buffer.
bool isOpened()
Returns true if the sequencer is opened.
void connectTo(int myport, int client, int port)
Subscribe one port to another arbitrary sequencer client:port.
ClientInfo * clone()
Clone the client info object.
virtual ~MidiClient()
Destructor.
#define DRUMSTICK_ALSA_CHECK_WARNING(x)
This macro calls the check warning function.
#define DRUMSTICK_ALSA_CHECK_ERROR(x)
This macro calls the check error function.
QList< MidiPort * > MidiPortList
List of Ports instances.
QList< PortInfo > PortInfoList
List of port information objects.