00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00202 private:
00206 class SequencerInputThread: public QThread
00207 {
00208 public:
00209 SequencerInputThread(MidiClient *seq, int timeout)
00210 : QThread(),
00211 m_MidiClient(seq),
00212 m_Wait(timeout),
00213 m_Stopped(false) {}
00214 virtual ~SequencerInputThread() {}
00215 virtual void run();
00216 bool stopped();
00217 void stop();
00218
00219 MidiClient *m_MidiClient;
00220 int m_Wait;
00221 bool m_Stopped;
00222 QReadWriteLock m_mutex;
00223 };
00224
00225 public:
00226 MidiClient( QObject* parent = 0 );
00227 virtual ~MidiClient();
00228
00229 void open( const QString deviceName = "default",
00230 const int openMode = SND_SEQ_OPEN_DUPLEX,
00231 const bool blockMode = false );
00232 void open( snd_config_t* conf,
00233 const QString deviceName = "default",
00234 const int openMode = SND_SEQ_OPEN_DUPLEX,
00235 const bool blockMode = false );
00236 void close();
00237 void startSequencerInput();
00238 void stopSequencerInput();
00239 MidiPort* createPort();
00240 MidiQueue* createQueue();
00241 MidiQueue* createQueue(QString const& name);
00242 MidiQueue* getQueue();
00243 MidiQueue* useQueue(int queue_id);
00244 MidiQueue* useQueue(const QString& name);
00245 MidiQueue* useQueue(MidiQueue* queue);
00246 void portAttach(MidiPort* port);
00247 void portDetach(MidiPort* port);
00248 void detachAllPorts();
00249 void addEventFilter(int evtype);
00250 void output(SequencerEvent* ev, bool async = false, int timeout = -1);
00251 void outputDirect(SequencerEvent* ev, bool async = false, int timeout = -1);
00252 void outputBuffer(SequencerEvent* ev);
00253 void drainOutput(bool async = false, int timeout = -1);
00254 void synchronizeOutput();
00255
00256 int getClientId();
00257 snd_seq_type_t getSequencerType();
00259 snd_seq_t* getHandle() { return m_SeqHandle; }
00261 bool isOpened() { return (m_SeqHandle != NULL); }
00262
00263 size_t getOutputBufferSize();
00264 void setOutputBufferSize(size_t newSize);
00265 size_t getInputBufferSize();
00266 void setInputBufferSize(size_t newSize);
00268 QString getDeviceName() { return m_DeviceName; }
00270 int getOpenMode() { return m_OpenMode; }
00272 bool getBlockMode() { return m_BlockMode; }
00273 void setBlockMode(bool newValue);
00274 QString getClientName();
00275 QString getClientName(const int clientId);
00276 void setClientName(QString const& newName);
00277 bool getBroadcastFilter();
00278 void setBroadcastFilter(bool newValue);
00279 bool getErrorBounce();
00280 void setErrorBounce(bool newValue);
00281
00282 ClientInfo& getThisClientInfo();
00283 void setThisClientInfo(const ClientInfo& val);
00284 MidiPortList getMidiPorts() const;
00285 ClientInfoList getAvailableClients();
00286 PortInfoList getAvailableInputs();
00287 PortInfoList getAvailableOutputs();
00288 SystemInfo& getSystemInfo();
00289 QList<int> getAvailableQueues();
00290
00291 PoolInfo& getPoolInfo();
00292 void setPoolInfo(const PoolInfo& info);
00293 void setPoolInput(int size);
00294 void setPoolOutput(int size);
00295 void setPoolOutputRoom(int size);
00296 void resetPoolInput();
00297 void resetPoolOutput();
00298 void dropInput();
00299 void dropInputBuffer();
00300 void dropOutput();
00301 void dropOutputBuffer();
00302 void removeEvents(const RemoveEvents* spec);
00303 SequencerEvent* extractOutput();
00304 int outputPending();
00305 int inputPending(bool fetch);
00306 int getQueueId(const QString& name);
00307
00308 void addListener(QObject* listener);
00309 void removeListener(QObject* listener);
00310 void setEventsEnabled(const bool bEnabled);
00312 bool getEventsEnabled() const { return m_eventsEnabled; }
00314 void setHandler(SequencerEventHandler* handler) { m_handler = handler; }
00315 bool parseAddress( const QString& straddr, snd_seq_addr& result );
00316
00317 signals:
00319 void eventReceived(SequencerEvent* ev);
00320
00321 protected:
00322 void doEvents();
00323 void applyClientInfo();
00324 void readClients();
00325 void freeClients();
00326 void updateAvailablePorts();
00327 PortInfoList filterPorts(unsigned int filter);
00328
00329
00330 const char * _getDeviceName();
00331 int getPollDescriptorsCount(short events);
00332 int pollDescriptors(struct pollfd *pfds, unsigned int space, short events);
00333 unsigned short pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds);
00334
00335
00336 void _setClientName( const char *name );
00337 int createSimplePort( const char *name,
00338 unsigned int caps,
00339 unsigned int type );
00340 void deleteSimplePort( int port );
00341 void connectFrom(int myport, int client, int port);
00342 void connectTo(int myport, int client, int port);
00343 void disconnectFrom(int myport, int client, int port);
00344 void disconnectTo(int myport, int client, int port);
00345
00346 private:
00347 bool m_eventsEnabled;
00348 bool m_BlockMode;
00349 bool m_NeedRefreshClientList;
00350 int m_OpenMode;
00351 QString m_DeviceName;
00352 snd_seq_t* m_SeqHandle;
00353 QPointer<SequencerInputThread> m_Thread;
00354 QPointer<MidiQueue> m_Queue;
00355 SequencerEventHandler* m_handler;
00356
00357 ClientInfo m_Info;
00358 ClientInfoList m_ClientList;
00359 MidiPortList m_Ports;
00360 PortInfoList m_OutputsAvail;
00361 PortInfoList m_InputsAvail;
00362 QObjectList m_listeners;
00363 SystemInfo m_sysInfo;
00364 PoolInfo m_poolInfo;
00365 };
00366
00367 #if SND_LIB_VERSION > 0x010004
00368 QString getRuntimeALSALibraryVersion();
00369 int getRuntimeALSALibraryNumber();
00370 #endif
00371 QString getRuntimeALSADriverVersion();
00372 int getRuntimeALSADriverNumber();
00373
00374 }
00375
00378 #endif // DRUMSTICK_ALSACLIENT_H