drumstick  0.5.0
alsaclient.h
Go to the documentation of this file.
00001 /*
00002     MIDI Sequencer C++ library
00003     Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl@users.sf.net>
00004 
00005     This library is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License along
00016     with this program; if not, write to the Free Software Foundation, Inc.,
00017     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 */
00019 
00020 #ifndef DRUMSTICK_ALSACLIENT_H
00021 #define DRUMSTICK_ALSACLIENT_H
00022 
00023 #include "alsaport.h"
00024 #include <QPointer>
00025 #include <QThread>
00026 #include <QReadWriteLock>
00027 
00036 namespace drumstick {
00037 
00038 class MidiQueue;
00039 class MidiClient;
00040 class SequencerEvent;
00041 class SequencerInputThread;
00042 class RemoveEvents;
00043 
00050 class DRUMSTICK_EXPORT ClientInfo
00051 {
00052     friend class MidiClient;
00053 
00054 public:
00055     ClientInfo();
00056     ClientInfo(const ClientInfo& other);
00057     ClientInfo(snd_seq_client_info_t* other);
00058     ClientInfo(MidiClient* seq, int id);
00059     virtual ~ClientInfo();
00060     ClientInfo* clone();
00061     ClientInfo& operator=(const ClientInfo& other);
00062     int getSizeOfInfo() const;
00063 
00064     int getClientId();
00065     snd_seq_client_type_t getClientType();
00066     QString getName();
00067     bool getBroadcastFilter();
00068     bool getErrorBounce();
00069     int getNumPorts();
00070     int getEventLost();
00071     void setClient(int client);
00072     void setName(QString name);
00073     void setBroadcastFilter(bool val);
00074     void setErrorBounce(bool val);
00075     PortInfoList getPorts() const;
00076 
00077 #if SND_LIB_VERSION > 0x010010
00078     void addFilter(int eventType);
00079     bool isFiltered(int eventType);
00080     void clearFilter();
00081     void removeFilter(int eventType);
00082 #endif
00083 
00084 protected:
00085     void readPorts(MidiClient* seq);
00086     void freePorts();
00087 
00088     const unsigned char* getEventFilter() __attribute__((deprecated));
00089     void setEventFilter(unsigned char* filter) __attribute__((deprecated));
00090 
00091 private:
00092     snd_seq_client_info_t* m_Info;
00093     PortInfoList m_Ports;
00094 };
00095 
00099 typedef QList<ClientInfo> ClientInfoList;
00100 
00107 class DRUMSTICK_EXPORT SystemInfo
00108 {
00109     friend class MidiClient;
00110 
00111 public:
00112     SystemInfo();
00113     SystemInfo(const SystemInfo& other);
00114     SystemInfo(snd_seq_system_info_t* other);
00115     SystemInfo(MidiClient* seq);
00116     virtual ~SystemInfo();
00117     SystemInfo* clone();
00118     SystemInfo& operator=(const SystemInfo& other);
00119     int getSizeOfInfo() const;
00120 
00121     int getMaxClients();
00122     int getMaxPorts();
00123     int getMaxQueues();
00124     int getMaxChannels();
00125     int getCurrentQueues();
00126     int getCurrentClients();
00127 
00128 private:
00129     snd_seq_system_info_t* m_Info;
00130 };
00131 
00138 class DRUMSTICK_EXPORT PoolInfo
00139 {
00140     friend class MidiClient;
00141 
00142 public:
00143     PoolInfo();
00144     PoolInfo(const PoolInfo& other);
00145     PoolInfo(snd_seq_client_pool_t* other);
00146     PoolInfo(MidiClient* seq);
00147     virtual ~PoolInfo();
00148     PoolInfo* clone();
00149     PoolInfo& operator=(const PoolInfo& other);
00150     int getSizeOfInfo() const;
00151 
00152     int getClientId();
00153     int getInputFree();
00154     int getInputPool();
00155     int getOutputFree();
00156     int getOutputPool();
00157     int getOutputRoom();
00158     void setInputPool(int size);
00159     void setOutputPool(int size);
00160     void setOutputRoom(int size);
00161 
00162 private:
00163     snd_seq_client_pool_t* m_Info;
00164 };
00165 
00175 class DRUMSTICK_EXPORT SequencerEventHandler
00176 {
00177 public:
00179     virtual ~SequencerEventHandler() {}
00180 
00190     virtual void handleSequencerEvent(SequencerEvent* ev) = 0;
00191 };
00192 
00198 class DRUMSTICK_EXPORT MidiClient : public QObject
00199 {
00200     Q_OBJECT
00201 public:
00202     MidiClient( QObject* parent = 0 );
00203     virtual ~MidiClient();
00204 
00205     void open( const QString deviceName = "default",
00206                const int openMode = SND_SEQ_OPEN_DUPLEX,
00207                const bool blockMode = false );
00208     void open( snd_config_t* conf,
00209                const QString deviceName = "default",
00210                const int openMode = SND_SEQ_OPEN_DUPLEX,
00211                const bool blockMode = false );
00212     void close();
00213     void startSequencerInput();
00214     void stopSequencerInput();
00215     MidiPort* createPort();
00216     MidiQueue* createQueue();
00217     MidiQueue* createQueue(QString const& name);
00218     MidiQueue* getQueue();
00219     MidiQueue* useQueue(int queue_id);
00220     MidiQueue* useQueue(const QString& name);
00221     MidiQueue* useQueue(MidiQueue* queue);
00222     void portAttach(MidiPort* port);
00223     void portDetach(MidiPort* port);
00224     void detachAllPorts();
00225     void addEventFilter(int evtype);
00226     void output(SequencerEvent* ev, bool async = false, int timeout = -1);
00227     void outputDirect(SequencerEvent* ev, bool async = false, int timeout = -1);
00228     void outputBuffer(SequencerEvent* ev);
00229     void drainOutput(bool async = false, int timeout = -1);
00230     void synchronizeOutput();
00231 
00232     int getClientId();
00233     snd_seq_type_t getSequencerType();
00235     snd_seq_t* getHandle() { return m_SeqHandle; }
00237     bool isOpened() { return (m_SeqHandle != NULL); }
00238 
00239     size_t getOutputBufferSize();
00240     void setOutputBufferSize(size_t newSize);
00241     size_t getInputBufferSize();
00242     void setInputBufferSize(size_t newSize);
00244     QString getDeviceName() { return m_DeviceName; }
00246     int getOpenMode() { return m_OpenMode; }
00248     bool getBlockMode() { return m_BlockMode; }
00249     void setBlockMode(bool newValue);
00250     QString getClientName();
00251     QString getClientName(const int clientId);
00252     void setClientName(QString const& newName);
00253     bool getBroadcastFilter();
00254     void setBroadcastFilter(bool newValue);
00255     bool getErrorBounce();
00256     void setErrorBounce(bool newValue);
00257 
00258     ClientInfo& getThisClientInfo();
00259     void setThisClientInfo(const ClientInfo& val);
00260     MidiPortList getMidiPorts() const;
00261     ClientInfoList getAvailableClients();
00262     PortInfoList getAvailableInputs();
00263     PortInfoList getAvailableOutputs();
00264     SystemInfo& getSystemInfo();
00265     QList<int> getAvailableQueues();
00266 
00267     PoolInfo& getPoolInfo();
00268     void setPoolInfo(const PoolInfo& info);
00269     void setPoolInput(int size);
00270     void setPoolOutput(int size);
00271     void setPoolOutputRoom(int size);
00272     void resetPoolInput();
00273     void resetPoolOutput();
00274     void dropInput();
00275     void dropInputBuffer();
00276     void dropOutput();
00277     void dropOutputBuffer();
00278     void removeEvents(const RemoveEvents* spec);
00279     SequencerEvent* extractOutput();
00280     int outputPending();
00281     int inputPending(bool fetch);
00282     int getQueueId(const QString& name);
00283 
00284     void addListener(QObject* listener);
00285     void removeListener(QObject* listener);
00286     void setEventsEnabled(const bool bEnabled);
00288     bool getEventsEnabled() const { return m_eventsEnabled; }
00290     void setHandler(SequencerEventHandler* handler)  { m_handler = handler; }
00291     bool parseAddress( const QString& straddr, snd_seq_addr& result );
00292     void setRealTimeInput(bool enabled);
00293     bool realTimeInputEnabled();
00294 
00295 signals:
00297     void eventReceived(SequencerEvent* ev);
00298 
00299 protected:
00300     void doEvents();
00301     void applyClientInfo();
00302     void readClients();
00303     void freeClients();
00304     void updateAvailablePorts();
00305     PortInfoList filterPorts(unsigned int filter);
00306 
00307     /* low level public functions */
00308     const char * _getDeviceName();
00309     int getPollDescriptorsCount(short events);
00310     int pollDescriptors(struct pollfd *pfds, unsigned int space, short events);
00311     unsigned short pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds);
00312 
00313     /* mid level functions */
00314     void _setClientName( const char *name );
00315     int createSimplePort( const char *name,
00316                           unsigned int caps,
00317                           unsigned int type );
00318     void deleteSimplePort( int port );
00319     void connectFrom(int myport, int client, int port);
00320     void connectTo(int myport, int client, int port);
00321     void disconnectFrom(int myport, int client, int port);
00322     void disconnectTo(int myport, int client, int port);
00323 
00324 private:
00325     class SequencerInputThread;
00326     bool m_eventsEnabled;
00327     bool m_BlockMode;
00328     bool m_NeedRefreshClientList;
00329     int  m_OpenMode;
00330     QString m_DeviceName;
00331     snd_seq_t* m_SeqHandle;
00332     QPointer<SequencerInputThread> m_Thread;
00333     QPointer<MidiQueue> m_Queue;
00334     SequencerEventHandler* m_handler;
00335 
00336     ClientInfo m_Info;
00337     ClientInfoList m_ClientList;
00338     MidiPortList m_Ports;
00339     PortInfoList m_OutputsAvail;
00340     PortInfoList m_InputsAvail;
00341     QObjectList m_listeners;
00342     SystemInfo m_sysInfo;
00343     PoolInfo m_poolInfo;
00344 };
00345 
00346 #if SND_LIB_VERSION > 0x010004
00347 DRUMSTICK_EXPORT QString getRuntimeALSALibraryVersion();
00348 DRUMSTICK_EXPORT int getRuntimeALSALibraryNumber();
00349 #endif
00350 DRUMSTICK_EXPORT QString getRuntimeALSADriverVersion();
00351 DRUMSTICK_EXPORT int getRuntimeALSADriverNumber();
00352 
00353 } /* namespace drumstick */
00354 
00357 #endif // DRUMSTICK_ALSACLIENT_H