drumstick
1.0.2
|
Prints information about the ALSA sequencer subsystem
/* MIDI Sequencer C++ library Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl@users.sf.net> This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "alsatimer.h" #include "alsaqueue.h" #include "alsaclient.h" #include "subscription.h" #include "cmdlineargs.h" #include <QTextStream> #include <QStringList> static QTextStream cout(stdout, QIODevice::WriteOnly); static QTextStream cerr(stderr, QIODevice::WriteOnly); using namespace drumstick; void queryTimers() { cout << endl << "ALSA Timers" << endl; TimerQuery* query = new TimerQuery("hw", 0); cout << "type___ Name________________ c/s/C/D/S Freq." << endl; TimerIdList lst = query->getTimers(); TimerIdList::ConstIterator it; for( it = lst.constBegin(); it != lst.constEnd(); ++it ) { TimerId id = *it; try { Timer* timer = new Timer(id, SND_TIMER_OPEN_NONBLOCK); TimerInfo info = timer->getTimerInfo(); cout << qSetFieldWidth(8) << left << info.getId() << qSetFieldWidth(20) << left << info.getName().left(20) << qSetFieldWidth(0) << " " << id.getClass() << "/" << id.getSlaveClass() << "/" << id.getCard() << "/" << id.getDevice() << "/" << id.getSubdevice() << " "; if( info.isSlave() ) { cout << "SLAVE"; } else { long freq = info.getFrequency(); cout << freq << " Hz"; } cout << endl; delete timer; } catch (const SequencerError& err) { cerr << "Error opening timer:" << err.qstrError(); } } delete query; } void queryQueues(MidiClient* c) { cout << endl << "ALSA Queues" << endl; cout << "id Queue_Name__________ Timer_Name__________ owner status " << " state PPQ Tempo BPM Ticks Time" << endl; QList<int> queues = c->getAvailableQueues(); foreach( int q, queues ) { MidiQueue* queue = new MidiQueue(c, q); if (queue != NULL) { QueueInfo qinfo = queue->getInfo(); QueueStatus qsts = queue->getStatus(); QueueTempo qtmp = queue->getTempo(); QueueTimer qtmr = queue->getTimer(); TimerId tid(qtmr.getId()); QString tname; try { Timer* timer = new Timer(tid, SND_TIMER_OPEN_NONBLOCK); TimerInfo tinfo = timer->getTimerInfo(); tname = tinfo.getName(); delete timer; } catch (...) { tname = "inaccessible"; } cout << qSetFieldWidth(3) << left << qinfo.getId() << qSetFieldWidth(20) << qinfo.getName().left(20) << qSetFieldWidth(0) << " " << qSetFieldWidth(20) << tname.left(20) << qSetFieldWidth(6) << right << qinfo.getOwner() << qSetFieldWidth(7) << (qinfo.isLocked() ? "locked" : "free") << qSetFieldWidth(8) << (qsts.isRunning() ? "running" : "stopped") << qSetFieldWidth(4) << qtmp.getPPQ() << qSetFieldWidth(7) << qtmp.getRealBPM() << qSetFieldWidth(4) << qtmp.getNominalBPM() << qSetFieldWidth(8) << qsts.getTickTime() << qSetFieldWidth(0) << " " << qsts.getClockTime() << endl; delete queue; } } } QString clientTypeName(snd_seq_client_type_t ctype) { if (ctype == SND_SEQ_USER_CLIENT) return "User"; if (ctype == SND_SEQ_KERNEL_CLIENT) return "Kernel"; return "Unknown"; } QString portTypeNames(int ptype) { QStringList lst; if ((ptype & SND_SEQ_PORT_TYPE_HARDWARE) != 0) lst << "Hardware"; if ((ptype & SND_SEQ_PORT_TYPE_SOFTWARE) != 0) lst << "Software"; if ((ptype & SND_SEQ_PORT_TYPE_PORT) != 0) lst << "Port"; if ((ptype & SND_SEQ_PORT_TYPE_DIRECT_SAMPLE) != 0) lst << "Direct Sample"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GENERIC) != 0) lst << "MIDI Generic"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GM) != 0) lst << "GM"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GM2) != 0) lst << "GM2"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_GS) != 0) lst << "GS"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_MT32) != 0) lst << "MT32"; if ((ptype & SND_SEQ_PORT_TYPE_MIDI_XG) != 0) lst << "XG"; if ((ptype & SND_SEQ_PORT_TYPE_SAMPLE) != 0) lst << "Sample"; if ((ptype & SND_SEQ_PORT_TYPE_SPECIFIC) != 0) lst << "Specific"; if ((ptype & SND_SEQ_PORT_TYPE_SYNTH) != 0) lst << "Synth"; if ((ptype & SND_SEQ_PORT_TYPE_APPLICATION) != 0) lst << "Application"; if ((ptype & SND_SEQ_PORT_TYPE_SYNTHESIZER) != 0) lst << "Synthesizer"; return " (" + lst.join(", ") + ")"; } QString subsNames(SubscribersList& subs) { QStringList lst; foreach( Subscriber s, subs ) { QString sname = QString("%1:%2").arg((int)s.getAddr()->client) .arg((int)s.getAddr()->port); lst << sname; } return lst.join(", "); } void queryClients(MidiClient* c) { cout << endl << "ALSA Sequencer clients" << endl; ClientInfoList clients = c->getAvailableClients(); foreach( ClientInfo cinfo, clients ) { PortInfoList plist = cinfo.getPorts(); cout << "Client " << qSetFieldWidth(4) << left << cinfo.getClientId() << qSetFieldWidth(0) << " : \"" << cinfo.getName() << "\" [" << clientTypeName(cinfo.getClientType()) << "]" << endl; foreach( PortInfo pinfo, plist ) { SubscribersList to = pinfo.getReadSubscribers(); SubscribersList from = pinfo.getWriteSubscribers(); cout << " Port " << qSetFieldWidth(4) << right << pinfo.getPort() << qSetFieldWidth(0) << " : \"" << pinfo.getName() << "\"" << (pinfo.getType() != 0 ? portTypeNames(pinfo.getType()) : "") << endl; if ( from.count() > 0 ) cout << " Connected From: " << subsNames(from) << endl; if ( to.count() > 0 ) cout << " Connecting To: " << subsNames(to) << endl; } } } void systemInfo(CmdLineArgs* args) { MidiClient* client = new MidiClient(); client->open(); client->setClientName(args->programName()); SystemInfo info = client->getSystemInfo(); cout << "ALSA Sequencer System Info, version: " << args->programVersion() << endl; cout << "Compiled ALSA library: " << LIBRARY_VERSION << endl; cout << "Runtime ALSA library: " << getRuntimeALSALibraryVersion() << endl; cout << "Runtime ALSA drivers: " << getRuntimeALSADriverVersion() << endl; cout << "Numeric ALSA compiled library: " << hex << SND_LIB_VERSION << endl; cout << "Numeric ALSA runtime library: " << getRuntimeALSALibraryNumber() << endl; cout << "Numeric ALSA runtime driver: " << getRuntimeALSADriverNumber() << endl; cout << "Max Clients: " << dec << info.getMaxClients() << endl; cout << "Max Ports: " << info.getMaxPorts() << endl; cout << "Max Queues: " << info.getMaxQueues() << endl; cout << "Max Channels: " << info.getMaxChannels() << endl; cout << "Current Queues: " << info.getCurrentQueues() << endl; cout << "Current Clients: " << info.getCurrentClients() << endl; queryTimers(); if (info.getCurrentQueues() > 0) queryQueues(client); if (info.getCurrentClients() > 0) queryClients(client); delete client; } int main(int argc, char **argv) { const QString errorstr = "Fatal error from the ALSA sequencer. " "This usually happens when the kernel doesn't have ALSA support, " "or the device node (/dev/snd/seq) doesn't exists, " "or the kernel module (snd_seq) is not loaded. " "Please check your ALSA/MIDI configuration."; CmdLineArgs args; args.parse(argc, argv); try { systemInfo(&args); } catch (const SequencerError& ex) { cerr << errorstr + " Returned error was: " + ex.qstrError() << endl; } catch (...) { cerr << errorstr << endl; } return 0; }