20#include <QCoreApplication>
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>
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;
209class 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;
260 d(new MidiClientPrivate)
262 qRegisterMetaType<drumstick::ALSA::SequencerEvent>();
263 qRegisterMetaType<drumstick::ALSA::SequencerEvent*>();
288 return d->m_SeqHandle;
297 return !d.isNull() && (d->m_SeqHandle !=
nullptr);
306 return d->m_DeviceName;
315 return d->m_OpenMode;
324 return d->m_BlockMode;
333 return d->m_eventsEnabled;
342 d->m_handler = handler;
356 if (d->m_Thread ==
nullptr) {
358 d->m_Thread->m_RealTime = enable;
369 if (d->m_Thread ==
nullptr)
371 return d->m_Thread->m_RealTime;
397 const bool blockMode)
400 openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) );
402 d->m_DeviceName = deviceName;
403 d->m_OpenMode = openMode;
404 d->m_BlockMode = blockMode;
429 const QString deviceName,
431 const bool blockMode )
434 deviceName.toLocal8Bit().data(),
436 blockMode ? 0 : SND_SEQ_NONBLOCK,
439 d->m_DeviceName = deviceName;
440 d->m_OpenMode = openMode;
441 d->m_BlockMode = blockMode;
454 if (d->m_SeqHandle !=
nullptr) {
457 d->m_SeqHandle =
nullptr;
472 return snd_seq_get_output_buffer_size(d->m_SeqHandle);
502 return snd_seq_get_input_buffer_size(d->m_SeqHandle);
533 if (d->m_BlockMode != newValue)
535 d->m_BlockMode = newValue;
536 if (d->m_SeqHandle !=
nullptr)
564 return snd_seq_type(d->m_SeqHandle);
592 snd_seq_event_t* evp =
nullptr;
594 err = snd_seq_event_input(d->m_SeqHandle, &evp);
595 if ((err >= 0) && (evp !=
nullptr)) {
598 case SND_SEQ_EVENT_NOTE:
602 case SND_SEQ_EVENT_NOTEON:
606 case SND_SEQ_EVENT_NOTEOFF:
610 case SND_SEQ_EVENT_KEYPRESS:
614 case SND_SEQ_EVENT_CONTROLLER:
615 case SND_SEQ_EVENT_CONTROL14:
616 case SND_SEQ_EVENT_REGPARAM:
617 case SND_SEQ_EVENT_NONREGPARAM:
621 case SND_SEQ_EVENT_PGMCHANGE:
625 case SND_SEQ_EVENT_CHANPRESS:
629 case SND_SEQ_EVENT_PITCHBEND:
633 case SND_SEQ_EVENT_SYSEX:
637 case SND_SEQ_EVENT_PORT_SUBSCRIBED:
638 case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
642 case SND_SEQ_EVENT_PORT_CHANGE:
643 case SND_SEQ_EVENT_PORT_EXIT:
644 case SND_SEQ_EVENT_PORT_START:
646 d->m_NeedRefreshClientList =
true;
649 case SND_SEQ_EVENT_CLIENT_CHANGE:
650 case SND_SEQ_EVENT_CLIENT_EXIT:
651 case SND_SEQ_EVENT_CLIENT_START:
653 d->m_NeedRefreshClientList =
true;
656 case SND_SEQ_EVENT_SONGPOS:
657 case SND_SEQ_EVENT_SONGSEL:
658 case SND_SEQ_EVENT_QFRAME:
659 case SND_SEQ_EVENT_TIMESIGN:
660 case SND_SEQ_EVENT_KEYSIGN:
664 case SND_SEQ_EVENT_SETPOS_TICK:
665 case SND_SEQ_EVENT_SETPOS_TIME:
666 case SND_SEQ_EVENT_QUEUE_SKEW:
670 case SND_SEQ_EVENT_TEMPO:
679 if (d->m_handler !=
nullptr) {
680 d->m_handler->handleSequencerEvent(event->clone());
683 if (d->m_eventsEnabled) {
684 QObjectList::Iterator it;
685 for(it=d->m_listeners.begin(); it!=d->m_listeners.end(); ++it) {
687 QCoreApplication::postEvent(sub, event->clone());
697 while (snd_seq_event_input_pending(d->m_SeqHandle, 0) > 0);
706 if (d->m_Thread ==
nullptr) {
709 d->m_Thread->start( d->m_Thread->m_RealTime ?
710 QThread::TimeCriticalPriority : QThread::InheritPriority );
720 if (d->m_Thread !=
nullptr) {
721 if (d->m_Thread->isRunning()) {
723 while (!d->m_Thread->wait(500) && (counter < 10)) {
726 if (!d->m_Thread->isFinished()) {
727 d->m_Thread->terminate();
743 while (snd_seq_query_next_client(d->m_SeqHandle, cInfo.m_Info) >= 0) {
745 d->m_ClientList.append(cInfo);
747 d->m_NeedRefreshClientList =
false;
756 d->m_ClientList.clear();
766 if (d->m_NeedRefreshClientList)
779 snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info);
794 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
803 if (d->m_SeqHandle !=
nullptr) {
804 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
815 return d->m_Info.getName();
826 ClientInfoList::Iterator it;
827 if (d->m_NeedRefreshClientList)
829 for (it = d->m_ClientList.begin(); it != d->m_ClientList.end(); ++it) {
830 if ((*it).getClientId() == clientId) {
831 return (*it).getName();
844 if (newName != d->m_Info.getName()) {
845 d->m_Info.setName(newName);
879 if (d->m_SeqHandle !=
nullptr) {
881 d->m_Ports.push_back(port);
892 if (d->m_SeqHandle !=
nullptr) {
900 MidiPortList::iterator it;
901 for(it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it)
905 d->m_Ports.erase(it);
917 if (d->m_SeqHandle !=
nullptr) {
918 QMutableListIterator<MidiPort*> it(d->m_Ports);
919 while (it.hasNext()) {
935 snd_seq_set_client_event_filter(d->m_SeqHandle, evtype);
946 return d->m_Info.getBroadcastFilter();
957 d->m_Info.setBroadcastFilter(newValue);
969 return d->m_Info.getErrorBounce();
980 d->m_Info.setErrorBounce(newValue);
998 pollfd* pfds =
nullptr;
1002 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1003 pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1004 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1005 while (snd_seq_event_output(d->m_SeqHandle, ev->
getHandle()) < 0)
1007 poll(pfds, npfds, timeout);
1029 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1030 pollfd* pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1031 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1032 while (snd_seq_event_output_direct(d->m_SeqHandle, ev->
getHandle()) < 0)
1034 poll(pfds, npfds, timeout);
1070 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1071 pollfd* pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1072 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1073 while (snd_seq_drain_output(d->m_SeqHandle) < 0)
1075 poll(pfds, npfds, timeout);
1089 snd_seq_sync_output_queue(d->m_SeqHandle);
1100 if (d->m_Queue ==
nullptr) {
1113 if (d->m_Queue !=
nullptr) {
1129 if (d->m_Queue !=
nullptr) {
1132 d->m_Queue =
new MidiQueue(
this, queueName,
this);
1146 if (d->m_Queue !=
nullptr) {
1149 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1163 if (d->m_Queue !=
nullptr) {
1167 if ( queue_id >= 0) {
1168 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1182 if (d->m_Queue !=
nullptr) {
1185 queue->setParent(
this);
1199 snd_seq_queue_info_t* qinfo;
1200 snd_seq_queue_info_alloca(&qinfo);
1202 for ( q = 0; q < max; ++q ) {
1203 err = snd_seq_get_queue_info(d->m_SeqHandle, q, qinfo);
1222 ClientInfoList::ConstIterator itc;
1223 PortInfoList::ConstIterator itp;
1225 if (d->m_NeedRefreshClientList)
1228 for (itc = d->m_ClientList.constBegin(); itc != d->m_ClientList.constEnd(); ++itc) {
1230 if ((ci.
getClientId() == SND_SEQ_CLIENT_SYSTEM) ||
1234 for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) {
1237 if ( ((filter & cap) != 0) &&
1238 ((SND_SEQ_PORT_CAP_NO_EXPORT & cap) == 0) ) {
1252 d->m_InputsAvail.clear();
1253 d->m_OutputsAvail.clear();
1254 d->m_InputsAvail =
filterPorts( SND_SEQ_PORT_CAP_READ |
1255 SND_SEQ_PORT_CAP_SUBS_READ );
1256 d->m_OutputsAvail =
filterPorts( SND_SEQ_PORT_CAP_WRITE |
1257 SND_SEQ_PORT_CAP_SUBS_WRITE );
1267 d->m_NeedRefreshClientList =
true;
1269 return d->m_InputsAvail;
1279 d->m_NeedRefreshClientList =
true;
1281 return d->m_OutputsAvail;
1293 d->m_listeners.append(listener);
1304 d->m_listeners.removeAll(listener);
1316 if (bEnabled != d->m_eventsEnabled) {
1317 d->m_eventsEnabled = bEnabled;
1328 snd_seq_system_info(d->m_SeqHandle, d->m_sysInfo.m_Info);
1329 return d->m_sysInfo;
1339 snd_seq_get_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info);
1340 return d->m_poolInfo;
1350 d->m_poolInfo = info;
1469 snd_seq_event_t* ev;
1484 return snd_seq_event_output_pending(d->m_SeqHandle);
1503 return snd_seq_event_input_pending(d->m_SeqHandle, fetch ? 1 : 0);
1515 return snd_seq_query_named_queue(d->m_SeqHandle, name.toLocal8Bit().data());
1526 return snd_seq_poll_descriptors_count(d->m_SeqHandle, events);
1546 return snd_seq_poll_descriptors(d->m_SeqHandle, pfds, space, events);
1558 unsigned short revents;
1572 return snd_seq_name(d->m_SeqHandle);
1598 name, caps, type ));
1674 QString testClient, testPort;
1675 ClientInfoList::ConstIterator cit;
1676 int pos = straddr.indexOf(
':');
1678 testClient = straddr.left(pos);
1679 testPort = straddr.mid(pos+1);
1681 testClient = straddr;
1684 addr.client = testClient.toInt(&ok);
1686 addr.port = testPort.toInt(&ok);
1688 if (d->m_NeedRefreshClientList)
1690 for ( cit = d->m_ClientList.constBegin();
1691 cit != d->m_ClientList.constEnd(); ++cit ) {
1693 if (testClient.compare(ci.
getName(), Qt::CaseInsensitive) == 0) {
1695 addr.port = testPort.toInt(&ok);
1710 QReadLocker locker(&m_mutex);
1720 QWriteLocker locker(&m_mutex);
1724#if defined(RTKIT_SUPPORT)
1725static pid_t _gettid() {
1726 return (pid_t) ::syscall(SYS_gettid);
1731MidiClient::SequencerInputThread::setRealtimePriority()
1733 struct sched_param p;
1734 int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK;
1735 quint32 priority = 6;
1736#if defined(RTKIT_SUPPORT)
1740 struct rlimit old_limit, new_limit;
1741 long long max_rttime;
1744 ::memset(&p, 0,
sizeof(p));
1745 p.sched_priority = priority;
1746 rt = ::pthread_setschedparam(::pthread_self(), policy, &p);
1748#if defined(RTKIT_SUPPORT)
1749 const QString rtkit_service =
1750 QStringLiteral(
"org.freedesktop.RealtimeKit1");
1751 const QString rtkit_path =
1752 QStringLiteral(
"/org/freedesktop/RealtimeKit1");
1753 const QString rtkit_iface = rtkit_service;
1755 QDBusConnection bus = QDBusConnection::systemBus();
1756 QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus);
1757 QVariant maxRTPrio = realtimeKit.property(
"MaxRealtimePriority");
1758 max_prio = maxRTPrio.toUInt(&ok);
1760 qWarning() <<
"invalid property RealtimeKit.MaxRealtimePriority";
1763 if (priority > max_prio)
1764 priority = max_prio;
1765 QVariant maxRTNSec = realtimeKit.property(
"RTTimeNSecMax");
1766 max_rttime = maxRTNSec.toLongLong(&ok);
1767 if (!ok || max_rttime < 0) {
1768 qWarning() <<
"invalid property RealtimeKit.RTTimeNSecMax";
1771 new_limit.rlim_cur = new_limit.rlim_max = max_rttime;
1772 rt = ::getrlimit(RLIMIT_RTTIME, &old_limit);
1774 qWarning() <<
"getrlimit() failed. err=" << rt << ::strerror(rt);
1777 rt = ::setrlimit(RLIMIT_RTTIME, &new_limit);
1779 qWarning() <<
"setrlimit() failed, err=" << rt << ::strerror(rt);
1782 QDBusMessage reply = realtimeKit.call(
"MakeThreadRealtime", thread, priority);
1783 if (reply.type() == QDBusMessage::ErrorMessage )
1784 qWarning() <<
"error returned by RealtimeKit.MakeThreadRealtime:"
1785 << reply.errorMessage();
1788 qWarning() <<
"pthread_setschedparam() failed, err="
1789 << rt << ::strerror(rt);
1799 if ( priority() == TimeCriticalPriority ) {
1800 setRealtimePriority();
1802 if (m_MidiClient !=
nullptr) {
1803 int npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN);
1804 pollfd* pfd = (pollfd *) calloc(npfd,
sizeof(pollfd));
1807 snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN);
1808 while (!stopped() && (m_MidiClient !=
nullptr))
1810 int rt = poll(pfd, npfd, m_Wait);
1812 m_MidiClient->doEvents();
1818 qWarning() <<
"exception in input thread";
1829 snd_seq_client_info_malloc(&m_Info);
1838 snd_seq_client_info_malloc(&m_Info);
1839 snd_seq_client_info_copy(m_Info, other.m_Info);
1840 m_Ports = other.m_Ports;
1849 snd_seq_client_info_malloc(&m_Info);
1850 snd_seq_client_info_copy(m_Info, other);
1860 snd_seq_client_info_malloc(&m_Info);
1861 snd_seq_get_any_client_info(seq->
getHandle(),
id, m_Info);
1870 snd_seq_client_info_free(m_Info);
1893 snd_seq_client_info_copy(m_Info, other.m_Info);
1894 m_Ports = other.m_Ports;
1905 return snd_seq_client_info_get_client(m_Info);
1912snd_seq_client_type_t
1915 return snd_seq_client_info_get_type(m_Info);
1925 return QString(snd_seq_client_info_get_name(m_Info));
1935 return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0);
1945 return (snd_seq_client_info_get_error_bounce(m_Info) != 0);
1956 return snd_seq_client_info_get_event_filter(m_Info);
1966 return snd_seq_client_info_get_num_ports(m_Info);
1976 return snd_seq_client_info_get_event_lost(m_Info);
1986 snd_seq_client_info_set_client(m_Info, client);
1996 snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data());
2006 snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0);
2016 snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0);
2027 snd_seq_client_info_set_event_filter(m_Info, filter);
2042 while (snd_seq_query_next_port(seq->
getHandle(), info.m_Info) >= 0) {
2044 m_Ports.append(info);
2075 return snd_seq_client_info_sizeof();
2078#if SND_LIB_VERSION > 0x010010
2085ClientInfo::addFilter(
int eventType)
2087 snd_seq_client_info_event_filter_add(m_Info, eventType);
2096ClientInfo::isFiltered(
int eventType)
2098 return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0);
2105ClientInfo::clearFilter()
2107 snd_seq_client_info_event_filter_clear(m_Info);
2115ClientInfo::removeFilter(
int eventType)
2117 snd_seq_client_info_event_filter_del(m_Info, eventType);
2126 snd_seq_system_info_malloc(&m_Info);
2135 snd_seq_system_info_malloc(&m_Info);
2136 snd_seq_system_info_copy(m_Info, other.m_Info);
2145 snd_seq_system_info_malloc(&m_Info);
2146 snd_seq_system_info_copy(m_Info, other);
2155 snd_seq_system_info_malloc(&m_Info);
2156 snd_seq_system_info(seq->
getHandle(), m_Info);
2164 snd_seq_system_info_free(m_Info);
2187 snd_seq_system_info_copy(m_Info, other.m_Info);
2197 return snd_seq_system_info_get_clients(m_Info);
2206 return snd_seq_system_info_get_ports(m_Info);
2215 return snd_seq_system_info_get_queues(m_Info);
2224 return snd_seq_system_info_get_channels(m_Info);
2233 return snd_seq_system_info_get_cur_queues(m_Info);
2242 return snd_seq_system_info_get_cur_clients(m_Info);
2251 return snd_seq_system_info_sizeof();
2259 snd_seq_client_pool_malloc(&m_Info);
2268 snd_seq_client_pool_malloc(&m_Info);
2269 snd_seq_client_pool_copy(m_Info, other.m_Info);
2278 snd_seq_client_pool_malloc(&m_Info);
2279 snd_seq_client_pool_copy(m_Info, other);
2288 snd_seq_client_pool_malloc(&m_Info);
2289 snd_seq_get_client_pool(seq->
getHandle(), m_Info);
2297 snd_seq_client_pool_free(m_Info);
2320 snd_seq_client_pool_copy(m_Info, other.m_Info);
2331 return snd_seq_client_pool_get_client(m_Info);
2341 return snd_seq_client_pool_get_input_free(m_Info);
2351 return snd_seq_client_pool_get_input_pool(m_Info);
2361 return snd_seq_client_pool_get_output_free(m_Info);
2371 return snd_seq_client_pool_get_output_pool(m_Info);
2382 return snd_seq_client_pool_get_output_room(m_Info);
2392 snd_seq_client_pool_set_input_pool(m_Info, size);
2402 snd_seq_client_pool_set_output_pool(m_Info, size);
2414 snd_seq_client_pool_set_output_room(m_Info, size);
2424 return snd_seq_client_pool_sizeof();
2427#if SND_LIB_VERSION > 0x010004
2434getRuntimeALSALibraryVersion()
2436 return QString(snd_asoundlib_version());
2445getRuntimeALSALibraryNumber()
2447 QRegularExpression rx(
"(\\d+)");
2448 QString str = getRuntimeALSALibraryVersion();
2450 int result = 0, j = 0;
2451 QRegularExpressionMatchIterator i = rx.globalMatch(str);
2452 while (i.hasNext() && (j < 3)) {
2453 QRegularExpressionMatch m = i.next();
2454 int v = m.captured(1).toInt(&ok);
2473 QRegularExpression rx(
"([\\d\\.]+)");
2475 QFile f(
"/proc/asound/version");
2476 if (f.open(QFile::ReadOnly)) {
2477 QTextStream str(&f);
2478 QString sub = str.readLine().trimmed();
2479 QRegularExpressionMatch m = rx.match(sub);
2495 QRegularExpression rx(
"(\\d+)");
2498 int result = 0, j = 0;
2499 QRegularExpressionMatchIterator i = rx.globalMatch(str);
2500 while (i.hasNext() && (j < 3)) {
2501 QRegularExpressionMatch m = i.next();
2502 int v = m.captured(1).toInt(&ok);
2522 return QStringLiteral(SND_LIB_VERSION_STR);
2531 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.
QString getDrumstickLibraryVersion()
getDrumstickLibraryVersion provides the Drumstick version as an edited QString
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.
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.
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.
int getRuntimeALSADriverNumber()
Gets the runtime ALSA drivers version number.
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.
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 getRuntimeALSADriverVersion()
Gets the runtime ALSA drivers version string.
QString getName()
Gets the client's name.
void setPoolInput(int size)
Sets the size of the client's input pool.
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 getCompiledALSALibraryVersion()
ALSA library version at build time.
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.