MuseScore  3.4
Music composition and notation
seq.h
Go to the documentation of this file.
1 //=============================================================================
2 // MusE Score
3 // Linux Music Score Editor
4 //
5 // Copyright (C) 2002-2009 Werner Schweer and others
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2.
9 //
10 // This program 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, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //=============================================================================
19 
20 #ifndef __SEQ_H__
21 #define __SEQ_H__
22 
23 #include "libmscore/rendermidi.h"
24 #include "libmscore/sequencer.h"
25 #include "libmscore/fraction.h"
26 #include "synthesizer/event.h"
27 #include "driver.h"
28 #include "libmscore/fifo.h"
29 #include "libmscore/tempo.h"
30 
31 class QTimer;
32 
33 namespace Ms {
34 
35 class Note;
36 class MasterScore;
37 class Score;
38 class Painter;
39 class Measure;
40 class Fraction;
41 class Driver;
42 class Part;
43 class Channel;
44 class ScoreView;
45 class MasterSynthesizer;
46 class Segment;
47 enum class POS : char;
48 
49 //---------------------------------------------------------
50 // SeqMsg
51 // message format for gui -> sequencer messages
52 //---------------------------------------------------------
53 
54 enum class SeqMsgId : char {
55  NO_MESSAGE,
57  PLAY, SEEK,
59  };
60 
61 struct SeqMsg {
63  union {
64  int intVal;
65  qreal realVal;
66  };
68 
69  SeqMsg() {}
70  SeqMsg(SeqMsgId _id, int val) : id(_id), intVal(val) {}
71  SeqMsg(SeqMsgId _id, qreal val) : id(_id), realVal(val) {}
72  SeqMsg(SeqMsgId _id, const NPlayEvent& e) : id(_id), event(e) {}
73  };
74 
75 //---------------------------------------------------------
76 // SeqMsgFifo
77 //---------------------------------------------------------
78 
79 static const int SEQ_MSG_FIFO_SIZE = 1024*8;
80 
81 class SeqMsgFifo : public FifoBase {
82  SeqMsg messages[SEQ_MSG_FIFO_SIZE];
83 
84  public:
85  SeqMsgFifo();
86  virtual ~SeqMsgFifo() {}
87  void enqueue(const SeqMsg&); // put object on fifo
88  SeqMsg dequeue(); // remove object from fifo
89  };
90 
91 // this are also the jack audio transport states:
92 enum class Transport : char {
93  STOP=0,
94  PLAY=1,
95  STARTING=3,
96  NET_STARTING=4
97  };
98 
99 //---------------------------------------------------------
100 // Seq
101 // sequencer
102 //---------------------------------------------------------
103 
104 class Seq : public QObject, public Sequencer {
105  Q_OBJECT
106 
107  mutable QMutex mutex;
108 
111  bool running; // true if sequencer is available
112  Transport state; // STOP, PLAY, STARTING=3
113  bool inCountIn;
114  // When we begin playing count in, JACK should play the ticks, but shouldn't run
115  // JACK Transport to prevent playing in other applications. Before playing
116  // count in we have to disconnect from JACK Transport by switching to the fake transport.
117  // Also we save current preferences.useJackTransport value to useJackTransportSavedFlag
118  // to restore it when count in ends. After this all applications start playing in sync.
120  int maxMidiOutPort; // Maximum count of midi out ports in all opened scores
122  double prevTempo;
123 
124  bool oggInit;
126 
131 
132  double meterValue[2];
133  double meterPeakValue[2];
134  int peakTimer[2];
135 
136  EventMap events; // playlist for playback mode
137  EventMap::const_iterator eventsEnd;
138  EventMap renderEvents; // event list that is rendered in background
141  QFuture<void> midiRenderFuture;
142  bool allowBackgroundRendering = false; // should be set to true only when playing, so no
143  // score changes are possible.
144  EventMap countInEvents; // playlist of any metronome countin clicks
145  QQueue<NPlayEvent> _liveEventQueue; // playlist for score editing and note entry (rendered live)
146 
147  int playFrame; // current play position in samples, relative to the first frame of playback
148  int countInPlayFrame; // current play position in samples, relative to the first frame of countin
149  int endUTick; // the final tick of midi events collected by collectEvents()
150 
151  EventMap::const_iterator playPos; // moved in real time thread
152  EventMap::const_iterator countInPlayPos;
153  EventMap::const_iterator guiPos; // moved in gui thread
154 
155  QList<const Note*> markedNotes; // notes marked as sounding
156 
157  uint tackRemain; // metronome state (remaining audio samples)
159  qreal tackVolume; // relative volumes
160  qreal tickVolume;
161  qreal metronomeVolume; // overall volume
162 
163  unsigned initialMillisecondTimestampWithLatency; // millisecond timestamp (relative to PortAudio's initialization) of start of playback
164 
165  QTimer* heartBeatTimer;
166  QTimer* noteTimer;
167 
168  void renderChunk(const MidiRenderer::Chunk&, EventMap*);
169  void updateEventsEnd();
170 
171  void setPos(int);
172  void playEvent(const NPlayEvent&, unsigned framePos);
173  void guiToSeq(const SeqMsg& msg);
174  void metronome(unsigned n, float* l, bool force);
175  void seekCommon(int utick);
176  void unmarkNotes();
177  void updateSynthesizerState(int tick1, int tick2);
178  void addCountInClicks();
179 
180  int getPlayStartUtick();
181 
182  inline QQueue<NPlayEvent>* liveEventQueue() { return &_liveEventQueue; }
183 
184  private slots:
185  void seqMessage(int msg, int arg = 0);
186  void heartBeatTimeout();
187  void midiInputReady();
188  void setPlaylistChanged() { playlistChanged = true; }
189  void handleTimeSigTempoChanged();
190 
191  public slots:
192  void setRelTempo(double);
193  void seek(int utick);
194  void seekRT(int utick);
195  void stopNotes(int channel = -1, bool realTime = false);
196  void start();
197  void stop();
198  void setPos(POS, unsigned);
199  void setMetronomeGain(float val) { metronomeVolume = val; }
200 
201  signals:
202  void started();
203  void stopped();
204  int toGui(int, int arg = 0);
205  void heartBeat(int, int, int);
206  void tempoChanged();
207  void timeSigChanged();
208 
209  public:
210  Seq();
211  ~Seq();
212  bool canStart();
213  void rewindStart();
214  void loopStart();
215  void seekEnd();
216  void nextMeasure();
217  void nextChord();
218  void prevMeasure();
219  void prevChord();
220 
221  void collectEvents(int utick);
222  void ensureBufferAsync(int utick);
223  void guiStop();
224  void stopWait();
225  void setLoopIn();
226  void setLoopOut();
227  void setLoopSelection();
228 
229  bool init(bool hotPlug = false);
230  void exit();
231  bool isRunning() const { return running; }
232  bool isPlaying() const { return state == Transport::PLAY; }
233  bool isStopped() const { return state == Transport::STOP; }
234 
235  void processMessages();
236  void process(unsigned framesPerPeriod, float* buffer);
237  int getEndUTick() const { return endUTick; }
238  bool isRealtime() const { return true; }
239  void sendMessage(SeqMsg&) const;
240 
241  void setController(int, int, int);
242  virtual void sendEvent(const NPlayEvent&);
243  void setScoreView(ScoreView*);
244  MasterScore* score() const { return cs; }
245  ScoreView* viewer() const { return cv; }
246  void initInstruments(bool realTime = false);
247 
248  Driver* driver() { return _driver; }
249  void setDriver(Driver* d) { _driver = d; }
250  MasterSynthesizer* synti() const { return _synti; }
251  void setMasterSynthesizer(MasterSynthesizer* ms) { _synti = ms; }
252 
253  int getCurTick();
254  double curTempo() const;
255 
256  void putEvent(const NPlayEvent&, unsigned framePos = 0);
257  void startNoteTimer(int duration);
258  virtual void startNote(int channel, int, int, double nt) override;
259  virtual void startNote(int channel, int, int, int, double nt) override;
260  virtual void playMetronomeBeat(BeatType type) override;
261 
262  void eventToGui(NPlayEvent);
263  void stopNoteTimer();
264  void recomputeMaxMidiOutPort();
265  float metronomeGain() const { return metronomeVolume; }
266 
267  void setInitialMillisecondTimestampWithLatency();
268  unsigned getCurrentMillisecondTimestampWithLatency(unsigned framePos) const;
269  };
270 
271 extern Seq* seq;
272 extern void initSequencer();
273 extern bool initMidi();
274 
275 } // namespace Ms
276 #endif
277 
RangeMap renderEventsStatus
Definition: seq.h:139
ScoreView * viewer() const
Definition: seq.h:245
int getEndUTick() const
Definition: seq.h:237
unsigned initialMillisecondTimestampWithLatency
Definition: seq.h:163
bool oggInit
Definition: seq.h:124
Seq * seq
Definition: seq.cpp:62
QTimer * heartBeatTimer
Definition: seq.h:165
int endUTick
Definition: seq.h:149
QQueue< NPlayEvent > * liveEventQueue()
Definition: seq.h:182
MasterScore * cs
Definition: seq.h:109
bool isPlaying() const
Definition: seq.h:232
SeqMsg(SeqMsgId _id, const NPlayEvent &e)
Definition: seq.h:72
QTimer * noteTimer
Definition: seq.h:166
Definition: fifo.h:30
uint tickRemain
Definition: seq.h:158
MasterScore * score() const
Definition: seq.h:244
Definition: score.h:1227
Definition: scoreview.h:90
QFuture< void > midiRenderFuture
Definition: seq.h:141
bool inCountIn
Definition: seq.h:113
Definition: sequencer.h:26
qreal tickVolume
Definition: seq.h:160
void setMasterSynthesizer(MasterSynthesizer *ms)
Definition: seq.h:251
uint tackRemain
Definition: seq.h:157
bool isStopped() const
Definition: seq.h:233
Definition: driver.h:33
Transport state
Definition: seq.h:112
Helper class to keep track of status of status of certain parts of score or MIDI representation.
Definition: rendermidi.h:45
EventMap::const_iterator playPos
Definition: seq.h:151
Transport
Definition: seq.h:92
EventMap renderEvents
Definition: seq.h:138
Definition: seq.h:104
bool initMidi()
EventMap::const_iterator countInPlayPos
Definition: seq.h:152
qreal tackVolume
Definition: seq.h:159
ScoreView * cv
Definition: seq.h:110
int playFrame
Definition: seq.h:147
virtual ~SeqMsgFifo()
Definition: seq.h:86
bool useJackTransportSavedFlag
Definition: seq.h:119
Driver * driver()
Definition: seq.h:248
SeqMsg()
Definition: seq.h:69
void setMetronomeGain(float val)
Definition: seq.h:199
EventMap events
Definition: seq.h:136
qreal metronomeVolume
Definition: seq.h:161
Definition: aeolus.cpp:26
MIDI renderer for a score.
Definition: rendermidi.h:63
int countInPlayFrame
Definition: seq.h:148
bool isRunning() const
Definition: seq.h:231
double prevTempo
Definition: seq.h:122
void initSequencer()
Definition: event.h:238
SeqMsg(SeqMsgId _id, qreal val)
Definition: seq.h:71
BeatType
Definition: sig.h:29
MidiRenderer midi
Definition: seq.h:140
bool playlistChanged
Definition: seq.h:125
MasterSynthesizer * synti() const
Definition: seq.h:250
Fraction prevTimeSig
Definition: seq.h:121
Definition: rendermidi.h:69
QMutex mutex
Definition: seq.h:107
QList< const Note * > markedNotes
Definition: seq.h:155
SeqMsgFifo fromSeq
Definition: seq.h:128
NPlayEvent event
Definition: seq.h:67
int maxMidiOutPort
Definition: seq.h:120
SeqMsgFifo toSeq
Definition: seq.h:127
EventMap::const_iterator eventsEnd
Definition: seq.h:137
Definition: seq.h:61
Definition: fraction.h:46
Definition: msynthesizer.h:33
Definition: event.h:325
bool isRealtime() const
Definition: seq.h:238
POS
Definition: score.h:100
EventMap::const_iterator guiPos
Definition: seq.h:153
SeqMsgId id
Definition: seq.h:62
QQueue< NPlayEvent > _liveEventQueue
Definition: seq.h:145
MasterSynthesizer * _synti
Definition: seq.h:130
qreal realVal
Definition: seq.h:65
SeqMsg(SeqMsgId _id, int val)
Definition: seq.h:70
Driver * _driver
Definition: seq.h:129
EventMap countInEvents
Definition: seq.h:144
SeqMsgId
Definition: seq.h:54
int intVal
Definition: seq.h:64
void setDriver(Driver *d)
Definition: seq.h:249
bool running
Definition: seq.h:111
Definition: seq.h:81
float metronomeGain() const
Definition: seq.h:265
Definition: channel.h:23
void setPlaylistChanged()
Definition: seq.h:188