drumstick 0.5.0
sysinfo.cpp

Prints information about the ALSA sequencer subsystem.

Prints information about the ALSA sequencer subsystem

/*
MIDI Sequencer C++ library
Copyright (C) 2006-2010, 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;
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 ) {
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: "
cout << "Numeric ALSA compiled library: "
<< hex << SND_LIB_VERSION << endl;
cout << "Numeric ALSA runtime library: "
<< getRuntimeALSALibraryNumber() << endl;
cout << "Numeric ALSA runtime driver: "
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;
}
Classes managing ALSA Sequencer clients.
QList< ClientInfo > ClientInfoList
List of sequencer client information.
Definition alsaclient.h:99
DRUMSTICK_EXPORT QString getRuntimeALSADriverVersion()
Gets the runtime ALSA drivers version string.
DRUMSTICK_EXPORT int getRuntimeALSADriverNumber()
Gets the runtime ALSA drivers version number.
QList< PortInfo > PortInfoList
List of port information objects.
Definition alsaport.h:112
Classes managing ALSA Sequencer queues.
Classes managing ALSA Timers.
QList< TimerId > TimerIdList
List of timer identifiers.
Definition alsatimer.h:113
Client information.
Definition alsaclient.h:51
snd_seq_client_type_t getClientType()
Gets the client's type.
QString getName()
Gets the client's name.
int getClientId()
Gets the client's numeric identifier.
PortInfoList getPorts() const
Gets the ports list.
Client management.
Definition alsaclient.h:199
SystemInfo & getSystemInfo()
Gets a SystemInfo instance with the updated state of the system.
QList< int > getAvailableQueues()
Get a list of the existing queues.
void setClientName(QString const &newName)
Changes the public name of the ALSA sequencer client.
ClientInfoList getAvailableClients()
Gets the list of clients from the ALSA sequencer.
void open(const QString deviceName="default", const int openMode=SND_SEQ_OPEN_DUPLEX, const bool blockMode=false)
Open the sequencer device.
Queue management.
Definition alsaqueue.h:189
QueueTimer & getTimer()
Gets a QueueTimer object reference.
QueueStatus & getStatus()
Gets a QueueStatus object reference.
QueueInfo & getInfo()
Gets a QueueInfo object reference.
QueueTempo & getTempo()
Gets a QueueTempo object reference.
Port information container.
Definition alsaport.h:41
unsigned int getType()
Gets the port type.
Definition alsaport.cpp:200
SubscribersList getReadSubscribers() const
Gets the list of read subscribers.
Definition alsaport.cpp:411
int getPort()
Gets the port number.
Definition alsaport.cpp:156
QString getName()
Gets the port name.
Definition alsaport.cpp:178
SubscribersList getWriteSubscribers() const
Gets the list of write subscribers.
Definition alsaport.cpp:421
Queue information container.
Definition alsaqueue.h:48
bool isLocked()
Returns the locking status of the queue.
int getOwner()
Gets the owner's client id of the queue.
int getId()
Gets the queue's numeric identifier.
QString getName()
Gets the queue name.
Queue status container.
Definition alsaqueue.h:81
bool isRunning()
Gets the queue's running state.
snd_seq_tick_time_t getTickTime()
Gets the musical time (ticks) of the queue.
double getClockTime()
Gets the clock time in seconds of the queue.
Queue tempo container.
Definition alsaqueue.h:118
float getRealBPM()
Gets the queue's real BPM tempo in beats per minute.
float getNominalBPM()
Gets the queue's nominal BPM tempo (in beats per minute)
int getPPQ()
Gets the PPQ (parts per quarter note) resolution of the queue.
Queue timer container.
Definition alsaqueue.h:158
const snd_timer_id_t * getId()
Gets the timer identifier record.
Class used to report errors from the ALSA sequencer.
const QString qstrError() const
Gets the human readable error message from the error code.
Subscriber container class.
const snd_seq_addr_t * getAddr()
Gets the subscriber's address.
System information.
Definition alsaclient.h:108
int getMaxQueues()
Get the system's maximum number of queues.
int getCurrentQueues()
Get the system's current number of queues.
int getMaxPorts()
Get the system's maximum number of ports.
int getMaxChannels()
Get the system's maximum number of channels.
int getCurrentClients()
Get the system's current number of clients.
int getMaxClients()
Get the system's maximum number of clients.
ALSA Timer identifier container.
Definition alsatimer.h:80
ALSA Timer information container.
Definition alsatimer.h:48
bool isSlave()
Check if the timer is slave (depends on another device)
QString getId()
Gets the string identifier.
QString getName()
Gets the timer name.
long getFrequency()
Gets the timer frequency in Hz.
ALSA Timer inquiry helper.
Definition alsatimer.h:155
TimerIdList getTimers() const
Gets the list of available timers.
Definition alsatimer.h:164
ALSA Timer management.
Definition alsatimer.h:268
TimerInfo & getTimerInfo()
Gets the timer info object.
const QString LIBRARY_VERSION(SND_LIB_VERSION_STR)
ALSA library version as a constant string.
Classes managing ALSA sequencer subscriptions.
QList< Subscriber > SubscribersList
List of subscribers.