19#include <QCoreApplication>
23#include <QRegularExpression>
25#include <QWriteLocker>
33#if defined(RTKIT_SUPPORT)
34#include <QDBusConnection>
35#include <QDBusInterface>
36#include <sys/resource.h>
37#include <sys/syscall.h>
43#define RLIMIT_RTTIME 15
46#ifndef SCHED_RESET_ON_FORK
47#define SCHED_RESET_ON_FORK 0x40000000
50#ifndef DEFAULT_INPUT_TIMEOUT
51#define DEFAULT_INPUT_TIMEOUT 500
203 void setRealtimePriority();
209 QReadWriteLock m_mutex;
212class MidiClient::MidiClientPrivate
215 MidiClientPrivate() :
216 m_eventsEnabled(false),
218 m_NeedRefreshClientList(true),
219 m_OpenMode(SND_SEQ_OPEN_DUPLEX),
220 m_DeviceName(
"default"),
221 m_SeqHandle(nullptr),
227 bool m_eventsEnabled;
229 bool m_NeedRefreshClientList;
231 QString m_DeviceName;
232 snd_seq_t* m_SeqHandle;
233 QPointer<SequencerInputThread> m_Thread;
234 QPointer<MidiQueue> m_Queue;
242 QObjectList m_listeners;
263 d(new MidiClientPrivate)
265 qRegisterMetaType<drumstick::ALSA::SequencerEvent>();
266 qRegisterMetaType<drumstick::ALSA::SequencerEvent*>();
291 return d->m_SeqHandle;
300 return !d.isNull() && (d->m_SeqHandle !=
nullptr);
309 return d->m_DeviceName;
318 return d->m_OpenMode;
327 return d->m_BlockMode;
336 return d->m_eventsEnabled;
345 d->m_handler = handler;
359 if (d->m_Thread ==
nullptr) {
361 d->m_Thread->m_RealTime = enable;
372 if (d->m_Thread ==
nullptr)
374 return d->m_Thread->m_RealTime;
400 const bool blockMode)
403 openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) );
405 d->m_DeviceName = deviceName;
406 d->m_OpenMode = openMode;
407 d->m_BlockMode = blockMode;
432 const QString deviceName,
434 const bool blockMode )
437 deviceName.toLocal8Bit().data(),
439 blockMode ? 0 : SND_SEQ_NONBLOCK,
442 d->m_DeviceName = deviceName;
443 d->m_OpenMode = openMode;
444 d->m_BlockMode = blockMode;
457 if (d->m_SeqHandle !=
nullptr) {
460 d->m_SeqHandle =
nullptr;
475 return snd_seq_get_output_buffer_size(d->m_SeqHandle);
505 return snd_seq_get_input_buffer_size(d->m_SeqHandle);
536 if (d->m_BlockMode != newValue)
538 d->m_BlockMode = newValue;
539 if (d->m_SeqHandle !=
nullptr)
567 return snd_seq_type(d->m_SeqHandle);
596 snd_seq_event_t* evp =
nullptr;
598 err = snd_seq_event_input(d->m_SeqHandle, &evp);
599 if ((err >= 0) && (evp !=
nullptr)) {
602 case SND_SEQ_EVENT_NOTE:
606 case SND_SEQ_EVENT_NOTEON:
610 case SND_SEQ_EVENT_NOTEOFF:
614 case SND_SEQ_EVENT_KEYPRESS:
618 case SND_SEQ_EVENT_CONTROLLER:
619 case SND_SEQ_EVENT_CONTROL14:
620 case SND_SEQ_EVENT_REGPARAM:
621 case SND_SEQ_EVENT_NONREGPARAM:
625 case SND_SEQ_EVENT_PGMCHANGE:
629 case SND_SEQ_EVENT_CHANPRESS:
633 case SND_SEQ_EVENT_PITCHBEND:
637 case SND_SEQ_EVENT_SYSEX:
641 case SND_SEQ_EVENT_PORT_SUBSCRIBED:
642 case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
646 case SND_SEQ_EVENT_PORT_CHANGE:
647 case SND_SEQ_EVENT_PORT_EXIT:
648 case SND_SEQ_EVENT_PORT_START:
650 d->m_NeedRefreshClientList =
true;
653 case SND_SEQ_EVENT_CLIENT_CHANGE:
654 case SND_SEQ_EVENT_CLIENT_EXIT:
655 case SND_SEQ_EVENT_CLIENT_START:
657 d->m_NeedRefreshClientList =
true;
660 case SND_SEQ_EVENT_SONGPOS:
661 case SND_SEQ_EVENT_SONGSEL:
662 case SND_SEQ_EVENT_QFRAME:
663 case SND_SEQ_EVENT_TIMESIGN:
664 case SND_SEQ_EVENT_KEYSIGN:
668 case SND_SEQ_EVENT_SETPOS_TICK:
669 case SND_SEQ_EVENT_SETPOS_TIME:
670 case SND_SEQ_EVENT_QUEUE_SKEW:
674 case SND_SEQ_EVENT_TEMPO:
683 if (d->m_handler !=
nullptr) {
684 d->m_handler->handleSequencerEvent(event->clone());
687 if (d->m_eventsEnabled) {
688 QObjectList::Iterator it;
689 for(it=d->m_listeners.begin(); it!=d->m_listeners.end(); ++it) {
691 QCoreApplication::postEvent(sub, event->clone());
695 if (isSignalConnected(receivedSignal)) {
703 while (snd_seq_event_input_pending(d->m_SeqHandle, 0) > 0);
712 if (d->m_Thread ==
nullptr) {
715 d->m_Thread->start( d->m_Thread->m_RealTime ?
716 QThread::TimeCriticalPriority : QThread::InheritPriority );
726 if (d->m_Thread !=
nullptr) {
727 if (d->m_Thread->isRunning()) {
729 while (!d->m_Thread->wait(500) && (counter < 10)) {
732 if (!d->m_Thread->isFinished()) {
733 d->m_Thread->terminate();
749 while (snd_seq_query_next_client(d->m_SeqHandle, cInfo.m_Info) >= 0) {
751 d->m_ClientList.append(cInfo);
753 d->m_NeedRefreshClientList =
false;
762 d->m_ClientList.clear();
772 if (d->m_NeedRefreshClientList)
785 snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info);
800 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
809 if (d->m_SeqHandle !=
nullptr) {
810 snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
821 return d->m_Info.getName();
832 ClientInfoList::Iterator it;
833 if (d->m_NeedRefreshClientList)
835 for (it = d->m_ClientList.begin(); it != d->m_ClientList.end(); ++it) {
836 if ((*it).getClientId() == clientId) {
837 return (*it).getName();
850 if (newName != d->m_Info.getName()) {
851 d->m_Info.setName(newName);
885 if (d->m_SeqHandle !=
nullptr) {
887 d->m_Ports.push_back(port);
898 if (d->m_SeqHandle !=
nullptr) {
906 MidiPortList::iterator it;
907 for(it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it)
911 d->m_Ports.erase(it);
923 if (d->m_SeqHandle !=
nullptr) {
924 QMutableListIterator<MidiPort*> it(d->m_Ports);
925 while (it.hasNext()) {
941 snd_seq_set_client_event_filter(d->m_SeqHandle, evtype);
952 return d->m_Info.getBroadcastFilter();
963 d->m_Info.setBroadcastFilter(newValue);
975 return d->m_Info.getErrorBounce();
986 d->m_Info.setErrorBounce(newValue);
1004 pollfd* pfds =
nullptr;
1008 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1009 pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1010 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1011 while (snd_seq_event_output(d->m_SeqHandle, ev->
getHandle()) < 0)
1013 poll(pfds, npfds, timeout);
1035 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1036 pollfd* pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1037 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1038 while (snd_seq_event_output_direct(d->m_SeqHandle, ev->
getHandle()) < 0)
1040 poll(pfds, npfds, timeout);
1076 int npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
1077 pollfd* pfds = (pollfd*) calloc(npfds,
sizeof(pollfd));
1078 snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
1079 while (snd_seq_drain_output(d->m_SeqHandle) < 0)
1081 poll(pfds, npfds, timeout);
1095 snd_seq_sync_output_queue(d->m_SeqHandle);
1106 if (d->m_Queue ==
nullptr) {
1119 if (d->m_Queue !=
nullptr) {
1135 if (d->m_Queue !=
nullptr) {
1138 d->m_Queue =
new MidiQueue(
this, queueName,
this);
1152 if (d->m_Queue !=
nullptr) {
1155 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1169 if (d->m_Queue !=
nullptr) {
1173 if ( queue_id >= 0) {
1174 d->m_Queue =
new MidiQueue(
this, queue_id,
this);
1188 if (d->m_Queue !=
nullptr) {
1191 queue->setParent(
this);
1205 snd_seq_queue_info_t* qinfo;
1206 snd_seq_queue_info_alloca(&qinfo);
1208 for ( q = 0; q < max; ++q ) {
1209 err = snd_seq_get_queue_info(d->m_SeqHandle, q, qinfo);
1228 ClientInfoList::ConstIterator itc;
1229 PortInfoList::ConstIterator itp;
1231 if (d->m_NeedRefreshClientList)
1234 for (itc = d->m_ClientList.constBegin(); itc != d->m_ClientList.constEnd(); ++itc) {
1236 if ((ci.
getClientId() == SND_SEQ_CLIENT_SYSTEM) ||
1240 for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) {
1243 if ( ((filter & cap) != 0) &&
1244 ((SND_SEQ_PORT_CAP_NO_EXPORT & cap) == 0) ) {
1258 d->m_InputsAvail.clear();
1259 d->m_OutputsAvail.clear();
1260 d->m_InputsAvail =
filterPorts( SND_SEQ_PORT_CAP_READ |
1261 SND_SEQ_PORT_CAP_SUBS_READ );
1262 d->m_OutputsAvail =
filterPorts( SND_SEQ_PORT_CAP_WRITE |
1263 SND_SEQ_PORT_CAP_SUBS_WRITE );
1273 d->m_NeedRefreshClientList =
true;
1275 return d->m_InputsAvail;
1285 d->m_NeedRefreshClientList =
true;
1287 return d->m_OutputsAvail;
1299 d->m_listeners.append(listener);
1310 d->m_listeners.removeAll(listener);
1322 if (bEnabled != d->m_eventsEnabled) {
1323 d->m_eventsEnabled = bEnabled;
1334 snd_seq_system_info(d->m_SeqHandle, d->m_sysInfo.m_Info);
1335 return d->m_sysInfo;
1345 snd_seq_get_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info);
1346 return d->m_poolInfo;
1356 d->m_poolInfo = info;
1475 snd_seq_event_t* ev;
1490 return snd_seq_event_output_pending(d->m_SeqHandle);
1509 return snd_seq_event_input_pending(d->m_SeqHandle, fetch ? 1 : 0);
1521 return snd_seq_query_named_queue(d->m_SeqHandle, name.toLocal8Bit().data());
1532 return snd_seq_poll_descriptors_count(d->m_SeqHandle, events);
1552 return snd_seq_poll_descriptors(d->m_SeqHandle, pfds, space, events);
1564 unsigned short revents;
1578 return snd_seq_name(d->m_SeqHandle);
1604 name, caps, type ));
1680 QString testClient, testPort;
1681 ClientInfoList::ConstIterator cit;
1682 int pos = straddr.indexOf(
':');
1684 testClient = straddr.left(pos);
1685 testPort = straddr.mid(pos+1);
1687 testClient = straddr;
1690 addr.client = testClient.toInt(&ok);
1692 addr.port = testPort.toInt(&ok);
1694 if (d->m_NeedRefreshClientList)
1696 for ( cit = d->m_ClientList.constBegin();
1697 cit != d->m_ClientList.constEnd(); ++cit ) {
1699 if (testClient.compare(ci.
getName(), Qt::CaseInsensitive) == 0) {
1701 addr.port = testPort.toInt(&ok);
1716 QReadLocker locker(&m_mutex);
1726 QWriteLocker locker(&m_mutex);
1730#if defined(RTKIT_SUPPORT)
1731static pid_t _gettid() {
1732 return (pid_t) ::syscall(SYS_gettid);
1737MidiClient::SequencerInputThread::setRealtimePriority()
1739 struct sched_param p;
1740 int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK;
1741 quint32 priority = 6;
1742#if defined(RTKIT_SUPPORT)
1746 struct rlimit old_limit, new_limit;
1747 long long max_rttime;
1750 ::memset(&p, 0,
sizeof(p));
1751 p.sched_priority = priority;
1752 rt = ::pthread_setschedparam(::pthread_self(), policy, &p);
1754#if defined(RTKIT_SUPPORT)
1755 const QString rtkit_service =
1756 QStringLiteral(
"org.freedesktop.RealtimeKit1");
1757 const QString rtkit_path =
1758 QStringLiteral(
"/org/freedesktop/RealtimeKit1");
1759 const QString rtkit_iface = rtkit_service;
1761 QDBusConnection bus = QDBusConnection::systemBus();
1762 QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus);
1763 QVariant maxRTPrio = realtimeKit.property(
"MaxRealtimePriority");
1764 max_prio = maxRTPrio.toUInt(&ok);
1766 qWarning() <<
"invalid property RealtimeKit.MaxRealtimePriority";
1769 if (priority > max_prio)
1770 priority = max_prio;
1771 QVariant maxRTNSec = realtimeKit.property(
"RTTimeNSecMax");
1772 max_rttime = maxRTNSec.toLongLong(&ok);
1773 if (!ok || max_rttime < 0) {
1774 qWarning() <<
"invalid property RealtimeKit.RTTimeNSecMax";
1777 new_limit.rlim_cur = new_limit.rlim_max = max_rttime;
1778 rt = ::getrlimit(RLIMIT_RTTIME, &old_limit);
1780 qWarning() <<
"getrlimit() failed. err=" << rt << ::strerror(rt);
1783 rt = ::setrlimit(RLIMIT_RTTIME, &new_limit);
1785 qWarning() <<
"setrlimit() failed, err=" << rt << ::strerror(rt);
1788 QDBusMessage reply = realtimeKit.call(
"MakeThreadRealtime", thread, priority);
1789 if (reply.type() == QDBusMessage::ErrorMessage )
1790 qWarning() <<
"error returned by RealtimeKit.MakeThreadRealtime:"
1791 << reply.errorMessage();
1794 qWarning() <<
"pthread_setschedparam() failed, err="
1795 << rt << ::strerror(rt);
1805 if ( priority() == TimeCriticalPriority ) {
1806 setRealtimePriority();
1808 if (m_MidiClient !=
nullptr) {
1809 int npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN);
1810 pollfd* pfd = (pollfd *) calloc(npfd,
sizeof(pollfd));
1813 snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN);
1814 while (!stopped() && (m_MidiClient !=
nullptr))
1816 int rt = poll(pfd, npfd, m_Wait);
1818 m_MidiClient->doEvents();
1824 qWarning() <<
"exception in input thread";
1835 snd_seq_client_info_malloc(&m_Info);
1844 snd_seq_client_info_malloc(&m_Info);
1845 snd_seq_client_info_copy(m_Info, other.m_Info);
1846 m_Ports = other.m_Ports;
1855 snd_seq_client_info_malloc(&m_Info);
1856 snd_seq_client_info_copy(m_Info, other);
1866 snd_seq_client_info_malloc(&m_Info);
1867 snd_seq_get_any_client_info(seq->
getHandle(),
id, m_Info);
1876 snd_seq_client_info_free(m_Info);
1899 snd_seq_client_info_copy(m_Info, other.m_Info);
1900 m_Ports = other.m_Ports;
1911 return snd_seq_client_info_get_client(m_Info);
1918snd_seq_client_type_t
1921 return snd_seq_client_info_get_type(m_Info);
1931 return QString(snd_seq_client_info_get_name(m_Info));
1941 return (snd_seq_client_info_get_broadcast_filter(m_Info) != 0);
1951 return (snd_seq_client_info_get_error_bounce(m_Info) != 0);
1962 return snd_seq_client_info_get_event_filter(m_Info);
1972 return snd_seq_client_info_get_num_ports(m_Info);
1982 return snd_seq_client_info_get_event_lost(m_Info);
1992 snd_seq_client_info_set_client(m_Info, client);
2002 snd_seq_client_info_set_name(m_Info, name.toLocal8Bit().data());
2012 snd_seq_client_info_set_broadcast_filter(m_Info, val ? 1 : 0);
2022 snd_seq_client_info_set_error_bounce(m_Info, val ? 1 : 0);
2033 snd_seq_client_info_set_event_filter(m_Info, filter);
2048 while (snd_seq_query_next_port(seq->
getHandle(), info.m_Info) >= 0) {
2050 m_Ports.append(info);
2081 return snd_seq_client_info_sizeof();
2084#if SND_LIB_VERSION > 0x010010
2091ClientInfo::addFilter(
int eventType)
2093 snd_seq_client_info_event_filter_add(m_Info, eventType);
2102ClientInfo::isFiltered(
int eventType)
2104 return (snd_seq_client_info_event_filter_check(m_Info, eventType) != 0);
2111ClientInfo::clearFilter()
2113 snd_seq_client_info_event_filter_clear(m_Info);
2121ClientInfo::removeFilter(
int eventType)
2123 snd_seq_client_info_event_filter_del(m_Info, eventType);
2132 snd_seq_system_info_malloc(&m_Info);
2141 snd_seq_system_info_malloc(&m_Info);
2142 snd_seq_system_info_copy(m_Info, other.m_Info);
2151 snd_seq_system_info_malloc(&m_Info);
2152 snd_seq_system_info_copy(m_Info, other);
2161 snd_seq_system_info_malloc(&m_Info);
2162 snd_seq_system_info(seq->
getHandle(), m_Info);
2170 snd_seq_system_info_free(m_Info);
2193 snd_seq_system_info_copy(m_Info, other.m_Info);
2203 return snd_seq_system_info_get_clients(m_Info);
2212 return snd_seq_system_info_get_ports(m_Info);
2221 return snd_seq_system_info_get_queues(m_Info);
2230 return snd_seq_system_info_get_channels(m_Info);
2239 return snd_seq_system_info_get_cur_queues(m_Info);
2248 return snd_seq_system_info_get_cur_clients(m_Info);
2257 return snd_seq_system_info_sizeof();
2265 snd_seq_client_pool_malloc(&m_Info);
2274 snd_seq_client_pool_malloc(&m_Info);
2275 snd_seq_client_pool_copy(m_Info, other.m_Info);
2284 snd_seq_client_pool_malloc(&m_Info);
2285 snd_seq_client_pool_copy(m_Info, other);
2294 snd_seq_client_pool_malloc(&m_Info);
2295 snd_seq_get_client_pool(seq->
getHandle(), m_Info);
2303 snd_seq_client_pool_free(m_Info);
2326 snd_seq_client_pool_copy(m_Info, other.m_Info);
2337 return snd_seq_client_pool_get_client(m_Info);
2347 return snd_seq_client_pool_get_input_free(m_Info);
2357 return snd_seq_client_pool_get_input_pool(m_Info);
2367 return snd_seq_client_pool_get_output_free(m_Info);
2377 return snd_seq_client_pool_get_output_pool(m_Info);
2388 return snd_seq_client_pool_get_output_room(m_Info);
2398 snd_seq_client_pool_set_input_pool(m_Info, size);
2408 snd_seq_client_pool_set_output_pool(m_Info, size);
2420 snd_seq_client_pool_set_output_room(m_Info, size);
2430 return snd_seq_client_pool_sizeof();
2433#if SND_LIB_VERSION > 0x010004
2440getRuntimeALSALibraryVersion()
2442 return QString(snd_asoundlib_version());
2451getRuntimeALSALibraryNumber()
2453 QRegularExpression rx(
"(\\d+)");
2454 QString str = getRuntimeALSALibraryVersion();
2456 int result = 0, j = 0;
2457 QRegularExpressionMatchIterator i = rx.globalMatch(str);
2458 while (i.hasNext() && (j < 3)) {
2459 QRegularExpressionMatch m = i.next();
2460 int v = m.captured(1).toInt(&ok);
2479 QRegularExpression rx(
"([\\d\\.]+)");
2481 QFile f(
"/proc/asound/version");
2482 if (f.open(QFile::ReadOnly)) {
2483 QTextStream str(&f);
2484 QString sub = str.readLine().trimmed();
2485 QRegularExpressionMatch m = rx.match(sub);
2501 QRegularExpression rx(
"(\\d+)");
2504 int result = 0, j = 0;
2505 QRegularExpressionMatchIterator i = rx.globalMatch(str);
2506 while (i.hasNext() && (j < 3)) {
2507 QRegularExpressionMatch m = i.next();
2508 int v = m.captured(1).toInt(&ok);
2528 return QStringLiteral(SND_LIB_VERSION_STR);
2537 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.