1 /* 2 MIDI Sequencer C++ library 3 Copyright (C) 2006-2021, Pedro Lopez-Cabanillas <plcl@users.sf.net> 4 5 This library is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef DRUMSTICK_PLAYTHREAD_H 20 #define DRUMSTICK_PLAYTHREAD_H 21 22 #include "alsaevent.h" 23 #include <QThread> 24 #include <QReadWriteLock> 25 26 namespace drumstick { namespace ALSA { 27 28 /** 29 * @file playthread.h 30 * Sequencer output thread 31 */ 32 33 class MidiClient; 34 class MidiQueue; 35 36 /** 37 * @addtogroup PlayThread ALSA Sequencer Output 38 * @{ 39 * 40 * @class SequencerOutputThread 41 * Sequence player auxiliary class 42 * 43 * This class is used to implement an asynchronous sequence player using 44 * ALSA sequencer scheduling 45 * 46 * Examples: guiplayer.cpp and playsmf.cpp 47 */ 48 class DRUMSTICK_EXPORT SequencerOutputThread : public QThread 49 { 50 Q_OBJECT 51 52 public: 53 SequencerOutputThread(MidiClient *seq, int portId); 54 virtual void run() override; 55 /** 56 * Gets the initial position in ticks of the sequence. The 57 * default value zero means starting from the beginning. 58 * @return Initial position (ticks) 59 */ getInitialPosition()60 virtual unsigned int getInitialPosition() { return 0; } 61 /** 62 * Gets the echo event resolution in ticks. This is the time 63 * between echo events interleaved with the MIDI sequence. The default 64 * value zero means that no echo events are sent at all. 65 * @return Echo resolution (ticks) 66 */ getEchoResolution()67 virtual unsigned int getEchoResolution() { return 0; } 68 /** 69 * Check if there is one more event in the sequence. 70 * This is a pure virtual method that must be overridden in the derived 71 * class. 72 * @return True if the sequence has another event. 73 */ 74 virtual bool hasNext() = 0; 75 /** 76 * Gets the next event in the sequence. 77 * This is a pure virtual function that must be overridden in the derived 78 * class. 79 * @return Pointer to the next SequencerEvent to be played. 80 */ 81 virtual SequencerEvent* nextEvent() = 0; 82 83 /** 84 * Stops playing the current sequence. 85 */ 86 virtual void stop(); 87 88 signals: 89 /** 90 * Signal emitted when the sequence play-back has finished. 91 */ 92 void playbackFinished(); 93 94 /** 95 * Signal emitted when the play-back has stopped. 96 */ 97 void playbackStopped(); 98 99 public slots: 100 void start( QThread::Priority priority = InheritPriority ); 101 102 protected: 103 virtual void sendEchoEvent(int tick); 104 virtual void sendSongEvent(SequencerEvent* ev); 105 virtual void drainOutput(); 106 virtual void syncOutput(); 107 virtual bool stopRequested(); 108 109 MidiClient *m_MidiClient; /**< MidiClient instance pointer */ 110 MidiQueue *m_Queue; /**< MidiQueue instance pointer */ 111 int m_PortId; /**< MidiPort numeric identifier */ 112 bool m_Stopped; /**< Stopped status */ 113 int m_QueueId; /**< MidiQueue numeric identifier */ 114 int m_npfds; /**< Number of pollfd pointers */ 115 pollfd* m_pfds; /**< Array of pollfd pointers */ 116 QReadWriteLock m_mutex; /**< Mutex object used for synchronization */ 117 }; 118 119 /** @} */ 120 121 }} /* namespace drumstick::ALSA */ 122 123 #endif /*DRUMSTICK_PLAYTHREAD_H*/ 124