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