1 //=============================================================================
2 //  MuseScore
3 //  Linux Music Score Editor
4 //
5 //  Copyright (C) 2002-2011 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 #include "config.h"
21 #include "seq.h"
22 #include "musescore.h"
23 
24 #include "audio/midi/msynthesizer.h"
25 #include "libmscore/rendermidi.h"
26 #include "libmscore/slur.h"
27 #include "libmscore/tie.h"
28 #include "libmscore/score.h"
29 #include "libmscore/segment.h"
30 #include "libmscore/note.h"
31 #include "libmscore/chord.h"
32 #include "libmscore/tempo.h"
33 #include "scoreview.h"
34 #include "playpanel.h"
35 #include "libmscore/staff.h"
36 #include "libmscore/measure.h"
37 #include "preferences.h"
38 #include "libmscore/part.h"
39 #include "libmscore/ottava.h"
40 #include "libmscore/utils.h"
41 #include "libmscore/repeatlist.h"
42 #include "libmscore/audio.h"
43 #include "synthcontrol.h"
44 #include "pianoroll/pianoroll.h"
45 #include "pianotools.h"
46 
47 #include "click.h"
48 
49 #define OV_EXCLUDE_STATIC_CALLBACKS
50 #include <vorbis/vorbisfile.h>
51 
52 #ifdef USE_PORTMIDI
53 #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
54   #include "portmidi/porttime/porttime.h"
55 #else
56   #include <porttime.h>
57 #endif
58 #endif
59 
60 namespace Ms {
61 
62 Seq* seq;
63 
64 static const int guiRefresh   = 10;       // Hz
65 static const int peakHoldTime = 1400;     // msec
66 static const int peakHold     = (peakHoldTime * guiRefresh) / 1000;
67 static OggVorbis_File vf;
68 
69 static constexpr int minUtickBufferSize = 480 * 4 * 10; // about 10 measures of 4/4 time signature
70 
71 #if 0 // yet(?) unused
72 static const int AUDIO_BUFFER_SIZE = 1024 * 512;  // 2 MB
73 #endif
74 
75 //---------------------------------------------------------
76 //   VorbisData
77 //---------------------------------------------------------
78 
79 struct VorbisData {
80       int pos;          // current position in audio->data()
81       QByteArray data;
82       };
83 
84 static VorbisData vorbisData;
85 
86 static size_t ovRead(void* ptr, size_t size, size_t nmemb, void* datasource);
87 static int ovSeek(void* datasource, ogg_int64_t offset, int whence);
88 static long ovTell(void* datasource);
89 
90 static ov_callbacks ovCallbacks = {
91       ovRead, ovSeek, 0, ovTell
92       };
93 
94 //---------------------------------------------------------
95 //   ovRead
96 //---------------------------------------------------------
97 
ovRead(void * ptr,size_t size,size_t nmemb,void * datasource)98 static size_t ovRead(void* ptr, size_t size, size_t nmemb, void* datasource)
99       {
100       VorbisData* vd = (VorbisData*)datasource;
101       size_t n = size * nmemb;
102       if (vd->data.size() < int(vd->pos + n))
103             n = vd->data.size() - vd->pos;
104       if (n) {
105             const char* src = vd->data.data() + vd->pos;
106             memcpy(ptr, src, n);
107             vd->pos += int(n);
108             }
109       return n;
110       }
111 
112 //---------------------------------------------------------
113 //   ovSeek
114 //---------------------------------------------------------
115 
ovSeek(void * datasource,ogg_int64_t offset,int whence)116 static int ovSeek(void* datasource, ogg_int64_t offset, int whence)
117       {
118       VorbisData* vd = (VorbisData*)datasource;
119       switch(whence) {
120             case SEEK_SET:
121                   vd->pos = offset;
122                   break;
123             case SEEK_CUR:
124                   vd->pos += offset;
125                   break;
126             case SEEK_END:
127                   vd->pos = vd->data.size() - offset;
128                   break;
129             }
130       return 0;
131       }
132 
133 //---------------------------------------------------------
134 //   ovTell
135 //---------------------------------------------------------
136 
ovTell(void * datasource)137 static long ovTell(void* datasource)
138       {
139       VorbisData* vd = (VorbisData*)datasource;
140       return vd->pos;
141       }
142 
143 //---------------------------------------------------------
144 //   Seq
145 //---------------------------------------------------------
146 
Seq()147 Seq::Seq()
148    : midi(nullptr)
149       {
150       running         = false;
151       playlistChanged = false;
152       cs              = 0;
153       cv              = 0;
154       tackRemain        = 0;
155       tickRemain        = 0;
156       maxMidiOutPort  = 0;
157 
158       endUTick  = 0;
159       state    = Transport::STOP;
160       oggInit  = false;
161       _driver  = 0;
162       playPos  = events.cbegin();
163       playFrame  = 0;
164       metronomeVolume = 0.3;
165       useJackTransportSavedFlag = false;
166 
167       inCountIn         = false;
168       countInPlayPos    = countInEvents.cbegin();
169       countInPlayFrame  = 0;
170 
171       meterValue[0]     = 0.0;
172       meterValue[1]     = 0.0;
173       meterPeakValue[0] = 0.0;
174       meterPeakValue[1] = 0.0;
175       peakTimer[0]       = 0;
176       peakTimer[1]       = 0;
177 
178       heartBeatTimer = new QTimer(this);
179       connect(heartBeatTimer, SIGNAL(timeout()), this, SLOT(heartBeatTimeout()));
180 
181       noteTimer = new QTimer(this);
182       noteTimer->setSingleShot(true);
183       connect(noteTimer, SIGNAL(timeout()), this, SLOT(stopNotes()));
184       noteTimer->stop();
185 
186       connect(this, SIGNAL(toGui(int, int)), this, SLOT(seqMessage(int, int)), Qt::QueuedConnection);
187 
188       prevTimeSig.setNumerator(0);
189       prevTempo = 0;
190       connect(this, SIGNAL(timeSigChanged()),this,SLOT(handleTimeSigTempoChanged()));
191       connect(this, SIGNAL(tempoChanged()),this,SLOT(handleTimeSigTempoChanged()));
192 
193       initialMillisecondTimestampWithLatency = 0;
194       }
195 
196 //---------------------------------------------------------
197 //   Seq
198 //---------------------------------------------------------
199 
~Seq()200 Seq::~Seq()
201       {
202       delete _driver;
203       }
204 
205 //---------------------------------------------------------
206 //   setScoreView
207 //---------------------------------------------------------
208 
setScoreView(ScoreView * v)209 void Seq::setScoreView(ScoreView* v)
210       {
211       if (oggInit) {
212             ov_clear(&vf);
213             oggInit = false;
214             }
215       if (cv !=v && cs) {
216             unmarkNotes();
217             stopWait();
218             }
219       cv = v;
220       if (cs)
221             disconnect(cs, SIGNAL(playlistChanged()), this, SLOT(setPlaylistChanged()));
222       cs = cv ? cv->score()->masterScore() : 0;
223       midi = MidiRenderer(cs);
224       midi.setMinChunkSize(10);
225 
226       if (!heartBeatTimer->isActive())
227             heartBeatTimer->start(20);    // msec
228 
229       playlistChanged = true;
230       _synti->reset();
231       if (cs) {
232             initInstruments();
233             connect(cs, SIGNAL(playlistChanged()), this, SLOT(setPlaylistChanged()));
234             }
235       }
236 
237 //---------------------------------------------------------
238 //   Seq::CachedPreferences::update
239 //---------------------------------------------------------
240 
update()241 void Seq::CachedPreferences::update()
242       {
243       portMidiOutputLatencyMilliseconds = preferences.getInt(PREF_IO_PORTMIDI_OUTPUTLATENCYMILLISECONDS);
244       jackTimeBaseMaster = preferences.getBool(PREF_IO_JACK_TIMEBASEMASTER);
245       useJackTransport = preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT);
246       useJackMidi = preferences.getBool(PREF_IO_JACK_USEJACKMIDI);
247       useJackAudio = preferences.getBool(PREF_IO_JACK_USEJACKAUDIO);
248       useAlsaAudio = preferences.getBool(PREF_IO_ALSA_USEALSAAUDIO);
249       usePortAudio = preferences.getBool(PREF_IO_PORTAUDIO_USEPORTAUDIO);
250       usePulseAudio = preferences.getBool(PREF_IO_PULSEAUDIO_USEPULSEAUDIO);
251       }
252 
253 //---------------------------------------------------------
254 //   startTransport
255 //---------------------------------------------------------
256 
startTransport()257 void Seq::startTransport()
258       {
259       cachedPrefs.update();
260       _driver->startTransport();
261       }
262 
263 //---------------------------------------------------------
264 //   stopTransport
265 //---------------------------------------------------------
266 
stopTransport()267 void Seq::stopTransport()
268       {
269       _driver->stopTransport();
270       }
271 
272 //---------------------------------------------------------
273 //   init
274 //    return false on error
275 //---------------------------------------------------------
276 
init(bool hotPlug)277 bool Seq::init(bool hotPlug)
278       {
279       if (!_driver || !_driver->start(hotPlug)) {
280             qDebug("Cannot start I/O");
281             running = false;
282             return false;
283             }
284       cachedPrefs.update();
285       running = true;
286       return true;
287       }
288 
289 //---------------------------------------------------------
290 //   exit
291 //---------------------------------------------------------
292 
exit()293 void Seq::exit()
294       {
295       if (_driver) {
296             if (MScore::debugMode)
297                   qDebug("Stop I/O");
298             stopWait();
299             delete _driver;
300             _driver = 0;
301             }
302       }
303 
304 //---------------------------------------------------------
305 //   rewindStart
306 //---------------------------------------------------------
307 
rewindStart()308 void Seq::rewindStart()
309       {
310       seek(0);
311       }
312 
313 //---------------------------------------------------------
314 //   loopStart
315 //---------------------------------------------------------
316 
loopStart()317 void Seq::loopStart()
318       {
319       start();
320 //      qDebug("LoopStart. playPos = %d", playPos);
321       }
322 
323 //---------------------------------------------------------
324 //   canStart
325 //    return true if sequencer can be started
326 //---------------------------------------------------------
327 
canStart()328 bool Seq::canStart()
329       {
330       if (!_driver)
331             return false;
332       collectEvents(getPlayStartUtick());
333       return (!events.empty() && endUTick != 0);
334       }
335 
336 //---------------------------------------------------------
337 //   start
338 //    called from gui thread
339 //---------------------------------------------------------
340 
start()341 void Seq::start()
342       {
343       if (!_driver) {
344             qDebug("No driver!");
345             return;
346             }
347 
348       mscore->moveControlCursor();
349 
350       allowBackgroundRendering = true;
351       collectEvents(getPlayStartUtick());
352       if (cs->playMode() == PlayMode::AUDIO) {
353             if (!oggInit) {
354                   vorbisData.pos  = 0;
355                   vorbisData.data = cs->audio()->data();
356                   int n = ov_open_callbacks(&vorbisData, &vf, 0, 0, ovCallbacks);
357                   if (n < 0) {
358                         qDebug("ogg open failed: %d", n);
359                         }
360                   oggInit = true;
361                   }
362             }
363 
364       if (!preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT) || (preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT) && state == Transport::STOP))
365             seek(getPlayStartUtick());
366 
367       if (preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT) && mscore->countIn() && state == Transport::STOP) {
368             // Ready to start playing count in, switching to fake transport
369             // to prevent playing in other applications with our ticks simultaneously
370             useJackTransportSavedFlag    = true;
371             preferences.setPreference(PREF_IO_JACK_USEJACKTRANSPORT, false);
372             }
373       startTransport();
374       }
375 
376 //---------------------------------------------------------
377 //   stop
378 //    called from gui thread
379 //---------------------------------------------------------
380 
stop()381 void Seq::stop()
382       {
383       const bool seqStopped = (state == Transport::STOP);
384       const bool driverStopped = !_driver || _driver->getState() == Transport::STOP;
385       if (seqStopped && driverStopped)
386             return;
387 
388       allowBackgroundRendering = false;
389       if (oggInit) {
390             ov_clear(&vf);
391             oggInit = false;
392             }
393       if (!_driver)
394             return;
395       if (!preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT) || (preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT) && _driver->getState() == Transport::PLAY))
396             stopTransport();
397       if (cv)
398             cv->setCursorOn(false);
399       if (midiRenderFuture.isRunning())
400             midiRenderFuture.waitForFinished();
401       if (cs) {
402             cs->setUpdateAll();
403             cs->update();
404             }
405       }
406 
407 //---------------------------------------------------------
408 //   stopWait
409 //---------------------------------------------------------
410 
stopWait()411 void Seq::stopWait()
412       {
413       stop();
414       QWaitCondition sleep;
415       int idx = 0;
416       while (state != Transport::STOP) {
417             qDebug("State %d", (int)state);
418             mutex.lock();
419             sleep.wait(&mutex, 100);
420             mutex.unlock();
421             ++idx;
422             Q_ASSERT(idx <= 10);
423             }
424       }
425 
426 //---------------------------------------------------------
427 //   seqStarted
428 //---------------------------------------------------------
429 
seqStarted()430 void MuseScore::seqStarted()
431       {
432       if (cv)
433             cv->setCursorOn(true);
434       if (cs)
435             cs->update();
436       }
437 
438 //---------------------------------------------------------
439 //   seqStopped
440 //    JACK has stopped
441 //    executed in gui environment
442 //---------------------------------------------------------
443 
seqStopped()444 void MuseScore::seqStopped()
445       {
446       cv->setCursorOn(false);
447       }
448 
449 //---------------------------------------------------------
450 //   unmarkNotes
451 //---------------------------------------------------------
452 
unmarkNotes()453 void Seq::unmarkNotes()
454       {
455       foreach(const Note* n, markedNotes) {
456             n->setMark(false);
457             cs->addRefresh(n->canvasBoundingRect());
458             }
459       markedNotes.clear();
460       PianoTools* piano = mscore->pianoTools();
461       if (piano && piano->isVisible())
462             piano->setPlaybackNotes(markedNotes);
463       }
464 
465 //---------------------------------------------------------
466 //   guiStop
467 //---------------------------------------------------------
468 
guiStop()469 void Seq::guiStop()
470       {
471       QAction* a = getAction("play");
472       a->setChecked(false);
473 
474       unmarkNotes();
475       if (!cs)
476             return;
477 
478       int tck = cs->repeatList().utick2tick(cs->utime2utick(qreal(playFrame) / qreal(MScore::sampleRate)));
479       cs->setPlayPos(Fraction::fromTicks(tck));
480       cs->update();
481       emit stopped();
482       }
483 
484 //---------------------------------------------------------
485 //   seqSignal
486 //    sequencer message to GUI
487 //    execution environment: gui thread
488 //---------------------------------------------------------
489 
seqMessage(int msg,int arg)490 void Seq::seqMessage(int msg, int arg)
491       {
492       switch(msg) {
493             case '5': {
494                   // Update the screen after seeking from the realtime thread
495                   Segment* seg = cs->tick2segment(Fraction::fromTicks(arg));
496                   if (seg)
497                         mscore->currentScoreView()->moveCursor(seg->tick());
498                   cs->setPlayPos(Fraction::fromTicks(arg));
499                   cs->update();
500                   break;
501                   }
502             case '4':   // Restart the playback at the end of the score
503                   loopStart();
504                   break;
505             case '3':   // Loop restart while playing
506                   seek(cs->repeatList().tick2utick(cs->loopInTick().ticks()));
507                   break;
508             case '2':
509                   guiStop();
510 //                  heartBeatTimer->stop();
511                   if (_driver && mscore->getSynthControl()) {
512                         meterValue[0]     = .0f;
513                         meterValue[1]     = .0f;
514                         meterPeakValue[0] = .0f;
515                         meterPeakValue[1] = .0f;
516                         peakTimer[0]       = 0;
517                         peakTimer[1]       = 0;
518                         mscore->getSynthControl()->setMeter(0.0, 0.0, 0.0, 0.0);
519                         }
520                   seek(0);
521                   break;
522             case '0':         // STOP
523                   guiStop();
524 //                  heartBeatTimer->stop();
525                   if (_driver && mscore->getSynthControl()) {
526                         meterValue[0]     = .0f;
527                         meterValue[1]     = .0f;
528                         meterPeakValue[0] = .0f;
529                         meterPeakValue[1] = .0f;
530                         peakTimer[0]       = 0;
531                         peakTimer[1]       = 0;
532                         mscore->getSynthControl()->setMeter(0.0, 0.0, 0.0, 0.0);
533                         }
534                   break;
535 
536             case '1':         // PLAY
537                   emit started();
538 //                  heartBeatTimer->start(1000/guiRefresh);
539                   break;
540 
541             default:
542                   qDebug("MScore::Seq:: unknown seq msg %d", msg);
543                   break;
544             }
545       }
546 
547 //---------------------------------------------------------
548 //   playEvent
549 //    send one event to the synthesizer
550 //---------------------------------------------------------
551 
playEvent(const NPlayEvent & event,unsigned framePos)552 void Seq::playEvent(const NPlayEvent& event, unsigned framePos)
553       {
554       int type = event.type();
555       if (type == ME_NOTEON) {
556             if (!event.isMuted()) {
557                   if (event.discard()) { // ignore noteoff but restrike noteon
558                         if (event.velo() > 0)
559                               putEvent(NPlayEvent(ME_NOTEON, event.channel(), event.pitch(), 0) ,framePos);
560                         else
561                               return;
562                         }
563                   putEvent(event, framePos);
564                   }
565             }
566       else if (type == ME_CONTROLLER || type == ME_PITCHBEND || type == ME_AFTERTOUCH || type == ME_POLYAFTER)
567             putEvent(event, framePos);
568       }
569 
570 //---------------------------------------------------------
571 //   recomputeMaxMidiOutPort
572 //   Computes the maximum number of midi out ports
573 //   in all opened scores
574 //---------------------------------------------------------
575 
recomputeMaxMidiOutPort()576 void Seq::recomputeMaxMidiOutPort()
577       {
578       if (!(preferences.getBool(PREF_IO_JACK_USEJACKMIDI) || preferences.getBool(PREF_IO_ALSA_USEALSAAUDIO)))
579             return;
580       int max = 0;
581       for (Score * s : MuseScoreCore::mscoreCore->scores()) {
582             if (s->masterScore()->midiPortCount() > max)
583                   max = s->masterScore()->midiPortCount();
584             }
585       maxMidiOutPort = max;
586       }
587 
588 //---------------------------------------------------------
589 //   processMessages
590 //   from gui to process thread
591 //---------------------------------------------------------
592 
processMessages()593 void Seq::processMessages()
594       {
595       for (;;) {
596             if (toSeq.empty())
597                   break;
598             SeqMsg msg = toSeq.dequeue();
599             switch(msg.id) {
600                   case SeqMsgId::TEMPO_CHANGE:
601                         {
602                         if (!cs)
603                               continue;
604                         if (playFrame != 0) {
605                               int utick = cs->utime2utick(qreal(playFrame) / qreal(MScore::sampleRate));
606                               cs->tempomap()->setRelTempo(msg.realVal);
607                               playFrame = cs->utick2utime(utick) * MScore::sampleRate;
608                               if (cachedPrefs.jackTimeBaseMaster && cachedPrefs.useJackTransport)
609                                     _driver->seekTransport(utick + 2 * cs->utime2utick(qreal((_driver->bufferSize()) + 1) / qreal(MScore::sampleRate)));
610                               }
611                         else
612                               cs->tempomap()->setRelTempo(msg.realVal);
613                         cs->masterScore()->updateRepeatListTempo();
614                         prevTempo = curTempo();
615                         emit tempoChanged();
616                         }
617                         break;
618                   case SeqMsgId::PLAY:
619                         putEvent(msg.event);
620                         break;
621                   case SeqMsgId::SEEK:
622                         setPos(msg.intVal);
623                         break;
624                   case SeqMsgId::ALL_NOTE_OFF:
625                         _synti->allNotesOff(msg.intVal);
626                         break;
627                   default:
628                         break;
629                   }
630             }
631       }
632 
633 //---------------------------------------------------------
634 //   metronome
635 //---------------------------------------------------------
636 
metronome(unsigned n,float * p,bool force)637 void Seq::metronome(unsigned n, float* p, bool force)
638       {
639       if (!mscore->metronome() && !force) {
640             tickRemain = 0;
641             tackRemain = 0;
642             return;
643             }
644       if (tickRemain) {
645             tackRemain = 0;
646             int idx = tickLength - tickRemain;
647             int nn = n < tickRemain ? n : tickRemain;
648             for (int i = 0; i < nn; ++i) {
649                   qreal v = tick[idx] * tickVolume * metronomeVolume;
650                   *p++ += v;
651                   *p++ += v;
652                   ++idx;
653                   }
654             tickRemain -= nn;
655             }
656       if (tackRemain) {
657             int idx = tackLength - tackRemain;
658             int nn = n < tackRemain ? n : tackRemain;
659             for (int i = 0; i < nn; ++i) {
660                   qreal v = tack[idx] * tackVolume * metronomeVolume;
661                   *p++ += v;
662                   *p++ += v;
663                   ++idx;
664                   }
665             tackRemain -= nn;
666             }
667       }
668 
669 //---------------------------------------------------------
670 //   addCountInClicks
671 //---------------------------------------------------------
672 
addCountInClicks()673 void Seq::addCountInClicks()
674       {
675       const Fraction plPos = cs->playPos();
676       Measure*    m        = cs->tick2measure(plPos);
677       Fraction   msrTick   = m->tick();
678       qreal tempo          = cs->tempomap()->tempo(msrTick.ticks());
679       TimeSigFrac timeSig  = cs->sigmap()->timesig(m->tick()).nominal();
680 
681       const int clickTicks = timeSig.isBeatedCompound(tempo) ? timeSig.beatTicks() : timeSig.dUnitTicks();
682 
683       // add at least one full measure of just clicks.
684       Fraction endTick = Fraction::fromTicks(timeSig.ticksPerMeasure());
685 
686       // add extra clicks if...
687       endTick += plPos - msrTick;   // ...not starting playback at beginning of measure
688 
689       if (m->isAnacrusis())         // ...measure is incomplete (anacrusis)
690             endTick += Fraction::fromTicks(timeSig.ticksPerMeasure()) - m->ticks();
691 
692       for (int t = 0; t < endTick.ticks(); t += clickTicks) {
693             const int rtick = t % timeSig.ticksPerMeasure();
694             countInEvents.insert(std::pair<int,NPlayEvent>(t, NPlayEvent(timeSig.rtick2beatType(rtick))));
695             }
696 
697       NPlayEvent event;
698       event.setType(ME_INVALID);
699       event.setPitch(0);
700       countInEvents.insert( std::pair<int,NPlayEvent>(endTick.ticks(), event));
701       // initialize play parameters to count-in events
702       countInPlayPos  = countInEvents.cbegin();
703       countInPlayFrame = 0;
704       }
705 
706 //-------------------------------------------------------------------
707 //   process
708 //    This function is called in a realtime context. This
709 //    means that no blocking operations are allowed which
710 //    includes memory allocation. The usual thread synchronisation
711 //    methods like semaphores can also not be used.
712 //-------------------------------------------------------------------
713 
process(unsigned framesPerPeriod,float * buffer)714 void Seq::process(unsigned framesPerPeriod, float* buffer)
715       {
716       unsigned framesRemain = framesPerPeriod; // the number of frames remaining to be processed by this call to Seq::process
717       Transport driverState = _driver->getState();
718       // Checking for the reposition from JACK Transport
719       _driver->checkTransportSeek(playFrame, framesRemain, inCountIn);
720 
721       if (driverState != state) {
722             // Got a message from JACK Transport panel: Play
723             if (state == Transport::STOP && driverState == Transport::PLAY) {
724                   if ((cachedPrefs.useJackMidi || cachedPrefs.useJackAudio) && !getAction("play")->isChecked()) {
725                         // Do not play while editing elements
726                         if (mscore->state() != STATE_NORMAL || !isRunning() || !canStart())
727                               return;
728                         getAction("play")->setChecked(true);
729                         getAction("play")->triggered(true);
730 
731                         // If we just launch MuseScore and press "Play" on JACK Transport with time 0:00
732                         // MuseScore doesn't seek to 0 and guiPos is uninitialized, so let's make it manually
733                         if (cachedPrefs.useJackTransport && getCurTick() == 0)
734                               seekRT(0);
735 
736                         // Switching to fake transport while playing count in
737                         // to prevent playing in other applications with our ticks simultaneously
738                         if (cachedPrefs.useJackTransport && mscore->countIn()) {
739                               // Stopping real JACK Transport
740                               stopTransport();
741                               // Starting fake transport
742                               useJackTransportSavedFlag = preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT);
743                               preferences.setPreference(PREF_IO_JACK_USEJACKTRANSPORT, false);
744                               startTransport();
745                               }
746                         }
747                   // Initializing instruments every time we start playback.
748                   // External synth can have wrong values, for example
749                   // if we switch between scores
750                   initInstruments(true);
751                   // Need to change state after calling collectEvents()
752                   state = Transport::PLAY;
753                   if (mscore->countIn() && cs->playMode() == PlayMode::SYNTHESIZER) {
754                         countInEvents.clear();
755                         inCountIn = true;
756                         }
757                   emit toGui('1');
758                   }
759             // Got a message from JACK Transport panel: Stop
760             else if (state == Transport::PLAY && driverState == Transport::STOP) {
761                   state = Transport::STOP;
762                   // Muting all notes
763                   stopNotes(-1, true);
764                   initInstruments(true);
765                   if (playPos == eventsEnd) {
766                         if (mscore->loop()) {
767                               qDebug("Seq.cpp - Process - Loop whole score. playPos = %d, cs->pos() = %d", playPos->first, cs->pos().ticks());
768                               emit toGui('4');
769                               return;
770                               }
771                         else {
772                               emit toGui('2');
773                               }
774                         }
775                   else {
776                      emit toGui('0');
777                      }
778                   }
779             else if (state != driverState)
780                   qDebug("Seq: state transition %d -> %d ?",
781                      (int)state, (int)driverState);
782             }
783 
784       memset(buffer, 0, sizeof(float) * framesPerPeriod * 2); // assume two channels
785       float* p = buffer;
786 
787       processMessages();
788 
789       if (state == Transport::PLAY) {
790             if (!cs)
791                   return;
792 
793             // if currently in count-in, these pointers will reference data in the count-in
794             EventMap::const_iterator* pPlayPos   = &playPos;
795             EventMap::const_iterator  pEventsEnd = eventsEnd;
796             int*                      pPlayFrame = &playFrame;
797             if (inCountIn) {
798                   if (countInEvents.size() == 0)
799                         addCountInClicks();
800                   pEventsEnd = countInEvents.cend();
801                   pPlayPos   = &countInPlayPos;
802                   pPlayFrame = &countInPlayFrame;
803                   }
804 
805             //
806             // play events for one segment
807             //
808             unsigned framePos = 0; // frame currently being processed relative to the first frame of this call to Seq::process
809             int periodEndFrame = *pPlayFrame + framesPerPeriod; // the ending frame (relative to start of playback) of the period being processed by this call to Seq::process
810             int scoreEndUTick = cs->repeatList().tick2utick(cs->lastMeasure()->endTick().ticks());
811             while (*pPlayPos != pEventsEnd) {
812                   int playPosUTick = (*pPlayPos)->first;
813                   int n; // current frame (relative to start of playback) that is being synthesized
814 
815                   if (inCountIn) {
816                         qreal beatsPerSecond = curTempo() * cs->tempomap()->relTempo(); // relTempo needed here to ensure that bps changes as we slide the tempo bar
817                         qreal ticksPerSecond = beatsPerSecond * MScore::division;
818                         qreal playPosSeconds = playPosUTick / ticksPerSecond;
819                         int playPosFrame = playPosSeconds * MScore::sampleRate;
820                         if (playPosFrame >= periodEndFrame)
821                               break;
822                         n = playPosFrame - *pPlayFrame;
823                         if (n < 0) {
824                               qDebug("Count-in: playPosUTick %d: n = %d - %d", playPosUTick, playPosFrame, *pPlayFrame);
825                               n = 0;
826                               }
827                         }
828                   else {
829                         qreal playPosSeconds = cs->utick2utime(playPosUTick);
830                         int playPosFrame = playPosSeconds * MScore::sampleRate;
831                         if (playPosFrame >= periodEndFrame)
832                               break;
833                         n = playPosFrame - *pPlayFrame;
834                         if (n < 0) {
835                               qDebug("%d:  %d - %d", playPosUTick, playPosFrame, *pPlayFrame);
836                               n = 0;
837                               }
838                         if (mscore->loop()) {
839                               int loopOutUTick = cs->repeatList().tick2utick(cs->loopOutTick().ticks());
840                               if (loopOutUTick < scoreEndUTick) {
841                                     qreal framesPerPeriodInTime = static_cast<qreal>(framesPerPeriod) / MScore::sampleRate;
842                                     int framesPerPeriodInTicks = cs->utime2utick(framesPerPeriodInTime);
843                                     // Also make sure we are inside the loop
844                                     if (playPosUTick >= loopOutUTick - 2 * framesPerPeriodInTicks || cs->repeatList().utick2tick(playPosUTick) < cs->loopInTick().ticks()) {
845                                           qDebug ("Process: playPosUTick = %d, cs->loopInTick().ticks() = %d, cs->loopOutTick().ticks() = %d, getCurTick() = %d, loopOutUTick = %d, playFrame = %d",
846                                                             playPosUTick,      cs->loopInTick().ticks(),      cs->loopOutTick().ticks(),      getCurTick(),      loopOutUTick,    *pPlayFrame);
847                                           if (cachedPrefs.useJackTransport) {
848                                                 int loopInUTick = cs->repeatList().tick2utick(cs->loopInTick().ticks());
849                                                 _driver->seekTransport(loopInUTick);
850                                                 if (loopInUTick != 0) {
851                                                       int seekto = loopInUTick - 2 * cs->utime2utick((qreal)_driver->bufferSize() / MScore::sampleRate);
852                                                       seekRT((seekto > 0) ? seekto : 0 );
853                                                       }
854                                                 }
855                                           else {
856                                                 emit toGui('3'); // calls loopStart()
857                                                 }
858                                           // Exit this function to avoid segmentation fault in Scoreview
859                                           return;
860                                           }
861                                     }
862                               }
863                         }
864                   if (n) {
865                         if (cs->playMode() == PlayMode::SYNTHESIZER) {
866                               metronome(n, p, inCountIn);
867                               _synti->process(n, p);
868                               p += n * 2;
869                               *pPlayFrame  += n;
870                               framesRemain -= n;
871                               framePos     += n;
872                               }
873                         else {
874                               while (n > 0) {
875                                     int section;
876                                     float** pcm;
877                                     long rn = ov_read_float(&vf, &pcm, n, &section);
878                                     if (rn == 0)
879                                           break;
880                                     for (int i = 0; i < rn; ++i) {
881                                           *p++ = pcm[0][i];
882                                           *p++ = pcm[1][i];
883                                           }
884                                     *pPlayFrame  += rn;
885                                     framesRemain -= rn;
886                                     framePos     += rn;
887                                     n            -= rn;
888                                     }
889                               }
890                         }
891                   const NPlayEvent& event = (*pPlayPos)->second;
892                   playEvent(event, framePos);
893                   if (event.type() == ME_TICK1) {
894                         tickRemain = tickLength;
895                         tickVolume = event.velo() ? qreal(event.value()) / 127.0 : 1.0;
896                         }
897                   else if (event.type() == ME_TICK2) {
898                         tackRemain = tackLength;
899                         tackVolume = event.velo() ? qreal(event.value()) / 127.0 : 1.0;
900                         }
901                   mutex.lock();
902                   ++(*pPlayPos);
903                   mutex.unlock();
904                   }
905             if (framesRemain) {
906                   if (cs->playMode() == PlayMode::SYNTHESIZER) {
907                         metronome(framesRemain, p, inCountIn);
908                         _synti->process(framesRemain, p);
909                         *pPlayFrame += framesRemain;
910                         }
911                   else {
912                         int n = framesRemain;
913                         while (n > 0) {
914                               int section;
915                               float** pcm;
916                               long rn = ov_read_float(&vf, &pcm, n, &section);
917                               if (rn == 0)
918                                     break;
919                               for (int i = 0; i < rn; ++i) {
920                                     *p++ = pcm[0][i];
921                                     *p++ = pcm[1][i];
922                                     }
923                               *pPlayFrame  += rn;
924                               framesRemain -= rn;
925                               framePos     += rn;
926                               n            -= rn;
927                               }
928                         }
929                   }
930             if (*pPlayPos == pEventsEnd) {
931                   if (inCountIn) {
932                         inCountIn = false;
933                         // Connecting to JACK Transport if MuseScore was temporarily disconnected from it
934                         if (useJackTransportSavedFlag) {
935                               // Stopping fake driver
936                               stopTransport();
937                               preferences.setPreference(PREF_IO_JACK_USEJACKTRANSPORT, true);
938                               // Starting the real JACK Transport. All applications play in sync now
939                               startTransport();
940                               }
941                         }
942                   else
943                         stopTransport();
944                   }
945             }
946       else {
947             // Outside of playback mode
948             while (!liveEventQueue()->empty()) {
949                   const NPlayEvent& event = liveEventQueue()->dequeue();
950                   if (event.type() == ME_TICK1) {
951                         tickRemain = tickLength;
952                         tickVolume = event.velo() ? qreal(event.value()) / 127.0 : 1.0;
953                         }
954                   else if (event.type() == ME_TICK2) {
955                         tackRemain = tackLength;
956                         tackVolume = event.velo() ? qreal(event.value()) / 127.0 : 1.0;
957                         }
958                   }
959             if (framesRemain) {
960                   metronome(framesRemain, p, true);
961                   _synti->process(framesRemain, p);
962                   }
963             }
964       //
965       // metering / master gain
966       //
967       qreal lv = 0.0f;
968       qreal rv = 0.0f;
969       p = buffer;
970       for (unsigned i = 0; i < framesRemain; ++i) {
971             qreal val = *p;
972             lv = qMax(lv, qAbs(val));
973             p++;
974 
975             val = *p;
976             rv = qMax(rv, qAbs(val));
977             p++;
978             }
979       meterValue[0] = lv;
980       meterValue[1] = rv;
981       if (meterPeakValue[0] < lv) {
982             meterPeakValue[0] = lv;
983             peakTimer[0] = 0;
984             }
985       if (meterPeakValue[1] < rv) {
986             meterPeakValue[1] = rv;
987             peakTimer[1] = 0;
988             }
989       }
990 
991 //---------------------------------------------------------
992 //   initInstruments
993 //---------------------------------------------------------
994 
initInstruments(bool realTime)995 void Seq::initInstruments(bool realTime)
996       {
997       // Add midi out ports if necessary
998       if (cs && (cachedPrefs.useJackMidi || cachedPrefs.useAlsaAudio)) {
999             // Increase the maximum number of midi ports if user adds staves/instruments
1000             int scoreMaxMidiPort = cs->masterScore()->midiPortCount();
1001             if (maxMidiOutPort < scoreMaxMidiPort)
1002                   maxMidiOutPort = scoreMaxMidiPort;
1003             // if maxMidiOutPort is equal to existing ports number, it will do nothing
1004             if (_driver)
1005                   _driver->updateOutPortCount(maxMidiOutPort + 1);
1006             }
1007 
1008       for (const MidiMapping& mm : cs->midiMapping()) {
1009             const Channel* channel = mm.articulation();
1010             for (const MidiCoreEvent& e : channel->initList()) {
1011                   if (e.type() == ME_INVALID)
1012                         continue;
1013                   NPlayEvent event(e.type(), channel->channel(), e.dataA(), e.dataB());
1014                   if (realTime)
1015                         putEvent(event);
1016                   else
1017                         sendEvent(event);
1018                   }
1019             // Setting pitch bend sensitivity to 12 semitones for external synthesizers
1020             if ((cachedPrefs.useJackMidi || cachedPrefs.useAlsaAudio) && mm.channel() != 9) {
1021                   if (realTime) {
1022                         putEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_LRPN, 0));
1023                         putEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_HRPN, 0));
1024                         putEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_HDATA,12));
1025                         putEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_LRPN, 127));
1026                         putEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_HRPN, 127));
1027                         }
1028                   else {
1029                         sendEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_LRPN, 0));
1030                         sendEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_HRPN, 0));
1031                         sendEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_HDATA,12));
1032                         sendEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_LRPN, 127));
1033                         sendEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_HRPN, 127));
1034                         }
1035                   }
1036             }
1037       }
1038 
1039 //---------------------------------------------------------
1040 //   renderChunk
1041 //---------------------------------------------------------
1042 
renderChunk(const MidiRenderer::Chunk & ch,EventMap * eventMap)1043 void Seq::renderChunk(const MidiRenderer::Chunk& ch, EventMap* eventMap)
1044       {
1045       SynthesizerState synState = mscore->synthesizerState();
1046       MidiRenderer::Context ctx(synState);
1047       ctx.metronome = true;
1048       ctx.renderHarmony = true;
1049       midi.renderChunk(ch, eventMap, ctx);
1050       renderEventsStatus.setOccupied(ch.utick1(), ch.utick2());
1051       }
1052 
1053 //---------------------------------------------------------
1054 //   updateEventsEnd
1055 //---------------------------------------------------------
1056 
updateEventsEnd()1057 void Seq::updateEventsEnd()
1058       {
1059       auto end = events.cend();
1060       eventsEnd = end;
1061       endUTick = events.empty() ? 0 : (--end)->first;
1062       }
1063 
1064 //---------------------------------------------------------
1065 //   collectEvents
1066 //---------------------------------------------------------
1067 
collectEvents(int utick)1068 void Seq::collectEvents(int utick)
1069       {
1070       //do not collect even while playing
1071       if (state == Transport::PLAY && playlistChanged)
1072             return;
1073 
1074       mutex.lock();
1075 
1076       if (midiRenderFuture.isRunning())
1077             midiRenderFuture.waitForFinished();
1078 
1079       if (playlistChanged) {
1080             midi.setScoreChanged();
1081             events.clear();
1082             renderEvents.clear();
1083             renderEventsStatus.clear();
1084             }
1085       else if (!renderEvents.empty()) {
1086             events.insert(renderEvents.begin(), renderEvents.end());
1087             renderEvents.clear();
1088             }
1089 
1090       int unrenderedUtick = renderEventsStatus.occupiedRangeEnd(utick);
1091       while (unrenderedUtick - utick < minUtickBufferSize) {
1092             const MidiRenderer::Chunk chunk = midi.getChunkAt(unrenderedUtick);
1093             if (!chunk)
1094                   break;
1095             renderChunk(chunk, &events);
1096             unrenderedUtick = renderEventsStatus.occupiedRangeEnd(utick);
1097             }
1098 
1099       updateEventsEnd();
1100       playPos = mscore->loop() ? events.find(cs->loopInTick().ticks()) : events.cbegin();
1101       playlistChanged = false;
1102       mutex.unlock();
1103       }
1104 
1105 //---------------------------------------------------------
1106 //   ensureBufferAsync
1107 //---------------------------------------------------------
1108 
ensureBufferAsync(int utick)1109 void Seq::ensureBufferAsync(int utick)
1110       {
1111       if (mutex.tryLock()) { // sync with possible collectEvents calls
1112 
1113             if (midiRenderFuture.isRunning() || !allowBackgroundRendering) {
1114                   mutex.unlock();
1115                   return;
1116                   }
1117 
1118             if (!renderEvents.empty()) {
1119                   // TODO: use C++17 map::merge()?
1120                   events.insert(renderEvents.begin(), renderEvents.end());
1121                   updateEventsEnd();
1122                   renderEvents.clear();
1123                   }
1124 
1125             const int unrenderedUtick = renderEventsStatus.occupiedRangeEnd(utick);
1126             if (unrenderedUtick - utick < minUtickBufferSize) {
1127                   const MidiRenderer::Chunk chunk = midi.getChunkAt(unrenderedUtick);
1128                   if (chunk) {
1129                         midiRenderFuture = QtConcurrent::run([this, chunk]() {
1130                               renderChunk(chunk, &renderEvents);
1131                               });
1132                         }
1133                   }
1134             mutex.unlock();
1135             }
1136       }
1137 
1138 //---------------------------------------------------------
1139 //   getCurTick
1140 //---------------------------------------------------------
1141 
getCurTick()1142 int Seq::getCurTick()
1143       {
1144       return cs->utime2utick(qreal(playFrame) / qreal(MScore::sampleRate));
1145       }
1146 
1147 //---------------------------------------------------------
1148 //   setRelTempo
1149 //    relTempo = 1.0 = normal tempo
1150 //---------------------------------------------------------
1151 
setRelTempo(double relTempo)1152 void Seq::setRelTempo(double relTempo)
1153       {
1154       guiToSeq(SeqMsg(SeqMsgId::TEMPO_CHANGE, relTempo));
1155       }
1156 
1157 //---------------------------------------------------------
1158 //   setPos
1159 //    seek
1160 //    realtime environment
1161 //---------------------------------------------------------
1162 
setPos(int utick)1163 void Seq::setPos(int utick)
1164       {
1165       if (cs == 0)
1166             return;
1167       stopNotes(-1, true);
1168 
1169       int ucur;
1170       mutex.lock();
1171       if (playPos != events.end())
1172             ucur = cs->repeatList().utick2tick(playPos->first);
1173       else
1174             ucur = utick - 1;
1175       if (utick != ucur)
1176             updateSynthesizerState(ucur, utick);
1177 
1178       playFrame = cs->utick2utime(utick) * MScore::sampleRate;
1179       playPos   = events.lower_bound(utick);
1180       mutex.unlock();
1181       }
1182 
1183 //---------------------------------------------------------
1184 //   getPlayStartUtick
1185 //---------------------------------------------------------
1186 
getPlayStartUtick()1187 int Seq::getPlayStartUtick()
1188       {
1189       if ((mscore->loop())) {
1190             if (preferences.getBool(PREF_APP_PLAYBACK_LOOPTOSELECTIONONPLAY)) {
1191                   setLoopSelection();
1192                   }
1193             return cs->repeatList().tick2utick(cs->loopInTick().ticks());
1194             }
1195       return cs->repeatList().tick2utick(cs->playPos().ticks());
1196       }
1197 
1198 //---------------------------------------------------------
1199 //   seekCommon
1200 //   a common part of seek() and seekRT(), contains code
1201 //   that could be safely called from any thread.
1202 //   Do not use explicitly, use seek() or seekRT()
1203 //---------------------------------------------------------
1204 
seekCommon(int utick)1205 void Seq::seekCommon(int utick)
1206       {
1207       if (cs == 0)
1208             return;
1209 
1210       collectEvents(utick);
1211 
1212       if (cs->playMode() == PlayMode::AUDIO) {
1213             ogg_int64_t sp = cs->utick2utime(utick) * MScore::sampleRate;
1214             ov_pcm_seek(&vf, sp);
1215             }
1216 
1217       guiPos = events.lower_bound(utick);
1218       mscore->setPos(Fraction::fromTicks(cs->repeatList().utick2tick(utick)));
1219       unmarkNotes();
1220       }
1221 
1222 //---------------------------------------------------------
1223 //   seek
1224 //   send seek message to sequencer
1225 //   gui thread
1226 //---------------------------------------------------------
1227 
seek(int utick)1228 void Seq::seek(int utick)
1229       {
1230       if (preferences.getBool(PREF_IO_JACK_USEJACKTRANSPORT)) {
1231             if (utick > endUTick)
1232                   utick = 0;
1233             _driver->seekTransport(utick);
1234             if (utick != 0)
1235                   return;
1236             }
1237       seekCommon(utick);
1238 
1239       int t = cs->repeatList().utick2tick(utick);
1240       Segment* seg = cs->tick2segment(Fraction::fromTicks(t));
1241       if (seg)
1242             mscore->currentScoreView()->moveCursor(seg->tick());
1243       cs->setPlayPos(Fraction::fromTicks(t));
1244       cs->update();
1245       guiToSeq(SeqMsg(SeqMsgId::SEEK, utick));
1246       }
1247 
1248 //---------------------------------------------------------
1249 //   seekRT
1250 //   realtime thread
1251 //---------------------------------------------------------
1252 
seekRT(int utick)1253 void Seq::seekRT(int utick)
1254       {
1255       if (cachedPrefs.useJackTransport && utick > endUTick)
1256                   utick = 0;
1257       seekCommon(utick);
1258       setPos(utick);
1259       // Update the screen in GUI thread
1260       emit toGui('5', cs->repeatList().utick2tick(utick));
1261       }
1262 
1263 //---------------------------------------------------------
1264 //   startNote
1265 //---------------------------------------------------------
1266 
startNote(int channel,int pitch,int velo,double nt)1267 void Seq::startNote(int channel, int pitch, int velo, double nt)
1268       {
1269       if (state != Transport::STOP && state != Transport::PLAY)
1270             return;
1271       NPlayEvent ev(ME_NOTEON, channel, pitch, velo);
1272       ev.setTuning(nt);
1273       sendEvent(ev);
1274       }
1275 
startNote(int channel,int pitch,int velo,int duration,double nt)1276 void Seq::startNote(int channel, int pitch, int velo, int duration, double nt)
1277       {
1278       stopNotes();
1279       startNote(channel, pitch, velo, nt);
1280       startNoteTimer(duration);
1281       }
1282 
1283 //---------------------------------------------------------
1284 //   playMetronomeBeat
1285 //---------------------------------------------------------
1286 
playMetronomeBeat(BeatType type)1287 void Seq::playMetronomeBeat(BeatType type)
1288       {
1289       if (state != Transport::STOP)
1290             return;
1291       liveEventQueue()->enqueue(NPlayEvent(type));
1292       }
1293 
1294 //---------------------------------------------------------
1295 //   startNoteTimer
1296 //---------------------------------------------------------
1297 
startNoteTimer(int duration)1298 void Seq::startNoteTimer(int duration)
1299       {
1300       if (duration) {
1301             noteTimer->setInterval(duration);
1302             noteTimer->start();
1303             }
1304       }
1305 //---------------------------------------------------------
1306 //   stopNoteTimer
1307 //---------------------------------------------------------
1308 
stopNoteTimer()1309 void Seq::stopNoteTimer()
1310       {
1311       if (noteTimer->isActive()) {
1312             noteTimer->stop();
1313             stopNotes();
1314             }
1315       }
1316 
1317 //---------------------------------------------------------
1318 //   stopNotes
1319 //---------------------------------------------------------
1320 
stopNotes(int channel,bool realTime)1321 void Seq::stopNotes(int channel, bool realTime)
1322       {
1323       auto send = [this, realTime](const NPlayEvent& event) {
1324             if (realTime)
1325                   putEvent(event);
1326             else
1327                   sendEvent(event);
1328             };
1329       // For VSTs/devices that do not support All Notes Off
1330       // CTRL_ALL_NOTES_OFF should still be evoked after calling this function, even if it seems redundant
1331       auto turnAllNotesOff = [send](int channel) {
1332             for (unsigned note = 0; note < 128; note++)
1333                   send(NPlayEvent(ME_NOTEOFF, channel, note, 0));
1334             };
1335       // Stop notes in all channels
1336       if (channel == -1) {
1337             for(unsigned ch = 0; ch < cs->midiMapping().size(); ch++) {
1338                   send(NPlayEvent(ME_CONTROLLER, ch, CTRL_SUSTAIN, 0));
1339                   turnAllNotesOff(ch);
1340                   send(NPlayEvent(ME_CONTROLLER, ch, CTRL_ALL_NOTES_OFF, 0));
1341                   if (cs->midiChannel(ch) != 9)
1342                         send(NPlayEvent(ME_PITCHBEND,  ch, 0, 64));
1343                   }
1344             }
1345       else {
1346             send(NPlayEvent(ME_CONTROLLER, channel, CTRL_SUSTAIN, 0));
1347             turnAllNotesOff(channel);
1348             send(NPlayEvent(ME_CONTROLLER, channel, CTRL_ALL_NOTES_OFF, 0));
1349             if (cs->midiChannel(channel) != 9)
1350                   send(NPlayEvent(ME_PITCHBEND,  channel, 0, 64));
1351             }
1352       if (cachedPrefs.useAlsaAudio || cachedPrefs.useJackAudio || cachedPrefs.usePulseAudio || cachedPrefs.usePortAudio) {
1353             guiToSeq(SeqMsg(SeqMsgId::ALL_NOTE_OFF, channel));
1354             }
1355       }
1356 
1357 //---------------------------------------------------------
1358 //   setController
1359 //---------------------------------------------------------
1360 
setController(int channel,int ctrl,int data)1361 void Seq::setController(int channel, int ctrl, int data)
1362       {
1363       NPlayEvent event(ME_CONTROLLER, channel, ctrl, data);
1364       sendEvent(event);
1365       }
1366 
1367 //---------------------------------------------------------
1368 //   sendEvent
1369 //    called from GUI context to send a midi event to
1370 //    midi out or synthesizer
1371 //---------------------------------------------------------
1372 
sendEvent(const NPlayEvent & ev)1373 void Seq::sendEvent(const NPlayEvent& ev)
1374       {
1375       guiToSeq(SeqMsg(SeqMsgId::PLAY, ev));
1376       }
1377 
1378 //---------------------------------------------------------
1379 //   nextMeasure
1380 //---------------------------------------------------------
1381 
nextMeasure()1382 void Seq::nextMeasure()
1383       {
1384       Measure* m = cs->tick2measure(Fraction::fromTicks(guiPos->first));
1385       if (m) {
1386             if (m->nextMeasure())
1387                   m = m->nextMeasure();
1388             seek(m->tick().ticks());
1389             }
1390       }
1391 
1392 //---------------------------------------------------------
1393 //   nextChord
1394 //---------------------------------------------------------
1395 
nextChord()1396 void Seq::nextChord()
1397       {
1398       int t = guiPos->first;
1399       for (auto i = guiPos; i != eventsEnd; ++i) {
1400             if (i->second.type() == ME_NOTEON && i->first > t && i->second.velo()) {
1401                   seek(i->first);
1402                   break;
1403                   }
1404             }
1405       }
1406 
1407 //---------------------------------------------------------
1408 //   prevMeasure
1409 //---------------------------------------------------------
1410 
prevMeasure()1411 void Seq::prevMeasure()
1412       {
1413       auto i = guiPos;
1414       if (i == events.begin())
1415             return;
1416       --i;
1417       Measure* m = cs->tick2measure(Fraction::fromTicks(i->first));
1418       if (m) {
1419             if ((i->first == m->tick().ticks()) && m->prevMeasure())
1420                   m = m->prevMeasure();
1421             seek(m->tick().ticks());
1422             }
1423       }
1424 
1425 //---------------------------------------------------------
1426 //   prevChord
1427 //---------------------------------------------------------
1428 
prevChord()1429 void Seq::prevChord()
1430       {
1431       int t  = playPos->first;
1432       //find the chord just before playpos
1433       EventMap::const_iterator i = events.upper_bound(cs->repeatList().tick2utick(t));
1434       for (;;) {
1435             if (i->second.type() == ME_NOTEON) {
1436                   const NPlayEvent& n = i->second;
1437                   if (i->first < t && n.velo()) {
1438                         t = i->first;
1439                         break;
1440                         }
1441                   }
1442             if (i == events.cbegin())
1443                   break;
1444             --i;
1445             }
1446       //go the previous chord
1447       if (i != events.cbegin()) {
1448             i = playPos;
1449             for (;;) {
1450                   if (i->second.type() == ME_NOTEON) {
1451                         const NPlayEvent& n = i->second;
1452                         if (i->first < t && n.velo()) {
1453                               seek(i->first);
1454                               break;
1455                               }
1456                         }
1457                   if (i == events.cbegin())
1458                         break;
1459                   --i;
1460                   }
1461             }
1462       }
1463 
1464 //---------------------------------------------------------
1465 //   seekEnd
1466 //---------------------------------------------------------
1467 
seekEnd()1468 void Seq::seekEnd()
1469       {
1470       qDebug("seek to end");
1471       }
1472 
1473 //---------------------------------------------------------
1474 //   guiToSeq
1475 //---------------------------------------------------------
1476 
guiToSeq(const SeqMsg & msg)1477 void Seq::guiToSeq(const SeqMsg& msg)
1478       {
1479       if (!_driver || !running)
1480             return;
1481       toSeq.enqueue(msg);
1482       }
1483 
1484 //---------------------------------------------------------
1485 //   eventToGui
1486 //---------------------------------------------------------
1487 
eventToGui(NPlayEvent e)1488 void Seq::eventToGui(NPlayEvent e)
1489       {
1490       fromSeq.enqueue(SeqMsg(SeqMsgId::MIDI_INPUT_EVENT, e));
1491       }
1492 
1493 //---------------------------------------------------------
1494 //   midiInputReady
1495 //---------------------------------------------------------
1496 
midiInputReady()1497 void Seq::midiInputReady()
1498       {
1499       if (_driver)
1500             _driver->midiRead();
1501       }
1502 
1503 //---------------------------------------------------------
1504 //   SeqMsgFifo
1505 //---------------------------------------------------------
1506 
SeqMsgFifo()1507 SeqMsgFifo::SeqMsgFifo()
1508       {
1509       maxCount = SEQ_MSG_FIFO_SIZE;
1510       clear();
1511       }
1512 
1513 //---------------------------------------------------------
1514 //   enqueue
1515 //---------------------------------------------------------
1516 
enqueue(const SeqMsg & msg)1517 void SeqMsgFifo::enqueue(const SeqMsg& msg)
1518       {
1519       int i = 0;
1520       int n = 50;
1521 
1522       QMutex mutex;
1523       QWaitCondition qwc;
1524       mutex.lock();
1525       for (; i < n; ++i) {
1526             if (!isFull())
1527                   break;
1528             qwc.wait(&mutex,100);
1529             }
1530       mutex.unlock();
1531       if (i == n) {
1532             qDebug("===SeqMsgFifo: overflow");
1533             return;
1534             }
1535       messages[widx] = msg;
1536       push();
1537       }
1538 
1539 //---------------------------------------------------------
1540 //   dequeue
1541 //---------------------------------------------------------
1542 
dequeue()1543 SeqMsg SeqMsgFifo::dequeue()
1544       {
1545       SeqMsg msg = messages[ridx];
1546       pop();
1547       return msg;
1548       }
1549 
1550 //---------------------------------------------------------
1551 //   putEvent
1552 //---------------------------------------------------------
1553 
putEvent(const NPlayEvent & event,unsigned framePos)1554 void Seq::putEvent(const NPlayEvent& event, unsigned framePos)
1555       {
1556       if (!cs)
1557             return;
1558       int channel = event.channel();
1559       if (channel >= int(cs->midiMapping().size())) {
1560             qDebug("bad channel value %d >= %d", channel, int(cs->midiMapping().size()));
1561             return;
1562             }
1563 
1564       // audio
1565       int syntiIdx= _synti->index(cs->midiMapping(channel)->articulation()->synti());
1566       _synti->play(event, syntiIdx);
1567 
1568       // midi
1569       if (_driver != 0 && (cachedPrefs.useJackMidi || cachedPrefs.useAlsaAudio || cachedPrefs.usePortAudio))
1570             _driver->putEvent(event, framePos);
1571       }
1572 
1573 //---------------------------------------------------------
1574 //   heartBeat
1575 //    update GUI
1576 //---------------------------------------------------------
1577 
heartBeatTimeout()1578 void Seq::heartBeatTimeout()
1579       {
1580       SynthControl* sc = mscore->getSynthControl();
1581       if (sc && _driver) {
1582             if (++peakTimer[0] >= peakHold)
1583                   meterPeakValue[0] *= .7f;
1584             if (++peakTimer[1] >= peakHold)
1585                   meterPeakValue[1] *= .7f;
1586             sc->setMeter(meterValue[0], meterValue[1], meterPeakValue[0], meterPeakValue[1]);
1587             }
1588 
1589       while (!fromSeq.empty()) {
1590             SeqMsg msg = fromSeq.dequeue();
1591             if (msg.id == SeqMsgId::MIDI_INPUT_EVENT) {
1592                   int type = msg.event.type();
1593                   if (type == ME_NOTEON)
1594                         mscore->midiNoteReceived(msg.event.channel(), msg.event.pitch(), msg.event.velo());
1595                   else if (type == ME_NOTEOFF)
1596                         mscore->midiNoteReceived(msg.event.channel(), msg.event.pitch(), 0);
1597                   else if (type == ME_CONTROLLER)
1598                         mscore->midiCtrlReceived(msg.event.controller(), msg.event.value());
1599                   }
1600             }
1601 
1602       if (state != Transport::PLAY || inCountIn)
1603             return;
1604 
1605       int endFrame = playFrame;
1606 
1607       mutex.lock();
1608       auto ppos = playPos;
1609       if (ppos != events.cbegin())
1610             --ppos;
1611       mutex.unlock();
1612 
1613       ensureBufferAsync(ppos->first);
1614 
1615       if (cs && cs->sigmap()->timesig(getCurTick()).nominal()!=prevTimeSig) {
1616             prevTimeSig = cs->sigmap()->timesig(getCurTick()).nominal();
1617             emit timeSigChanged();
1618             }
1619       if (cs && curTempo()!=prevTempo) {
1620             prevTempo = curTempo();
1621             emit tempoChanged();
1622             }
1623 
1624       QRectF r;
1625       for (;guiPos != eventsEnd; ++guiPos) {
1626             if (guiPos->first > ppos->first)
1627                   break;
1628             if (mscore->loop())
1629                   if (guiPos->first >= cs->repeatList().tick2utick(cs->loopOutTick().ticks()))
1630                         break;
1631             const NPlayEvent& n = guiPos->second;
1632             if (n.type() == ME_NOTEON) {
1633                   const Note* note1 = n.note();
1634                   if (n.velo()) {
1635                         while (note1) {
1636                               for (ScoreElement* se : note1->linkList()) {
1637                                     if (!se->isNote())
1638                                           continue;
1639                                     Note* currentNote = toNote(se);
1640                                     currentNote->setMark(true);
1641                                     markedNotes.append(currentNote);
1642                                     r |= currentNote->canvasBoundingRect();
1643                                     }
1644                               note1 = note1->tieFor() ? note1->tieFor()->endNote() : 0;
1645                               }
1646                         }
1647                   else {
1648                         while (note1) {
1649                               for (ScoreElement* se : note1->linkList()) {
1650                                     if (!se->isNote())
1651                                           continue;
1652                                     Note* currentNote = toNote(se);
1653                                     currentNote->setMark(false);
1654                                     r |= currentNote->canvasBoundingRect();
1655                                     markedNotes.removeOne(currentNote);
1656                                     }
1657                               note1 = note1->tieFor() ? note1->tieFor()->endNote() : 0;
1658                               }
1659                         }
1660                   }
1661             }
1662       int utick = ppos->first;
1663       int t = cs->repeatList().utick2tick(utick);
1664       mscore->currentScoreView()->moveCursor(Fraction::fromTicks(t));
1665       mscore->setPos(Fraction::fromTicks(t));
1666 
1667       emit(heartBeat(t, utick, endFrame));
1668 
1669       PianorollEditor* pre = mscore->getPianorollEditor();
1670       if (pre && pre->isVisible())
1671             pre->heartBeat(this);
1672 
1673       PianoTools* piano = mscore->pianoTools();
1674       if (piano && piano->isVisible())
1675             piano->setPlaybackNotes(markedNotes);
1676 
1677       cv->update(cv->toPhysical(r));
1678       }
1679 
1680 //---------------------------------------------------------
1681 //   updateSynthesizerState
1682 //    collect all controller events between tick1 and tick2
1683 //    and send them to the synthesizer
1684 //    Called from RT thread
1685 //---------------------------------------------------------
1686 
updateSynthesizerState(int tick1,int tick2)1687 void Seq::updateSynthesizerState(int tick1, int tick2)
1688       {
1689       if (tick1 > tick2)
1690             tick1 = 0;
1691       // Making a local copy of events to avoid touching it
1692       // from different threads at the same time
1693       EventMap ev = events;
1694       EventMap::const_iterator i1 = ev.lower_bound(tick1);
1695       EventMap::const_iterator i2 = ev.upper_bound(tick2);
1696 
1697       for (; i1 != i2; ++i1) {
1698             if (i1->second.type() == ME_CONTROLLER)
1699                   playEvent(i1->second, 0);
1700             }
1701       }
1702 
1703 //---------------------------------------------------------
1704 //   curTempo
1705 //---------------------------------------------------------
1706 
curTempo() const1707 double Seq::curTempo() const
1708       {
1709       if (playPos != events.end())
1710             return cs ? cs->tempomap()->tempo(playPos->first) : 0.0;
1711 
1712       return 0.0;
1713       }
1714 
1715 //---------------------------------------------------------
1716 //   set Loop in position
1717 //---------------------------------------------------------
1718 
setLoopIn()1719 void Seq::setLoopIn()
1720       {
1721       Fraction t;
1722       if (state == Transport::PLAY) {     // If in playback mode, set the In position where note is being played
1723             auto ppos = playPos;
1724             if (ppos != events.cbegin())
1725                   --ppos;                 // We have to go back one pos to get the correct note that has just been played
1726             t = Fraction::fromTicks(cs->repeatList().utick2tick(ppos->first));
1727             }
1728       else
1729             t = cs->pos();        // Otherwise, use the selected note.
1730       if (t >= cs->loopOutTick())         // If In pos >= Out pos, reset Out pos to end of score
1731             cs->setPos(POS::RIGHT, cs->lastMeasure()->endTick());
1732       cs->setPos(POS::LEFT, t);
1733       }
1734 
1735 //---------------------------------------------------------
1736 //   set Loop Out position
1737 //---------------------------------------------------------
1738 
setLoopOut()1739 void Seq::setLoopOut()
1740       {
1741       Fraction t;
1742       if (state == Transport::PLAY) {    // If in playback mode, set the Out position where note is being played
1743             t = Fraction::fromTicks(cs->repeatList().utick2tick(playPos->first));
1744             }
1745       else
1746             t = cs->pos() + cs->inputState().ticks();   // Otherwise, use the selected note.
1747       if (t <= cs->loopInTick())                        // If Out pos <= In pos, reset In pos to beginning of score
1748             cs->setPos(POS::LEFT, Fraction(0,1));
1749       else
1750           if (t > cs->lastMeasure()->endTick())
1751               t = cs->lastMeasure()->endTick();
1752       cs->setPos(POS::RIGHT, t);
1753       if (state == Transport::PLAY)
1754             guiToSeq(SeqMsg(SeqMsgId::SEEK, t.ticks()));
1755       }
1756 
setPos(POS,unsigned t)1757 void Seq::setPos(POS, unsigned t)
1758       {
1759       qDebug("seq: setPos %d", t);
1760       }
1761 
1762 //---------------------------------------------------------
1763 //   set Loop In/Out position based on the selection
1764 //---------------------------------------------------------
1765 
setLoopSelection()1766 void Seq::setLoopSelection()
1767       {
1768       const Score* score = mscore->currentScore();
1769       Q_ASSERT(!score || score->masterScore() == cs);
1770 
1771       if (score && score->selection().isRange()) {
1772             cs->setLoopInTick(score->selection().tickStart());
1773             cs->setLoopOutTick(score->selection().tickEnd());
1774             }
1775 
1776       // add a dummy event to loop end if it is not already there
1777       // this is to let the playback reach the end completely before starting again
1778       if (!events.count(cs->loopOutTick().ticks())) {
1779             NPlayEvent ev;
1780             ev.setValue(ME_INVALID);
1781             events.insert(std::pair<int, Ms::NPlayEvent>(cs->loopOutTick().ticks(), ev));
1782             }
1783       }
1784 
1785 //---------------------------------------------------------
1786 //   Called after tempo or time signature
1787 //   changed while playback
1788 //---------------------------------------------------------
1789 
handleTimeSigTempoChanged()1790 void Seq::handleTimeSigTempoChanged()
1791       {
1792       _driver->handleTimeSigTempoChanged();
1793       }
1794 
1795 //---------------------------------------------------------
1796 //  setInitialMillisecondTimestampWithLatency
1797 //   Called whenever seq->process() starts.
1798 //   Sets a starting reference time for which subsequent PortMidi events will be offset from.
1799 //   Time is relative to the start of PortMidi's initialization.
1800 //---------------------------------------------------------
1801 
setInitialMillisecondTimestampWithLatency()1802 void Seq::setInitialMillisecondTimestampWithLatency()
1803       {
1804      #ifdef USE_PORTMIDI
1805            initialMillisecondTimestampWithLatency = Pt_Time() + cachedPrefs.portMidiOutputLatencyMilliseconds;
1806            //qDebug("PortMidi initialMillisecondTimestampWithLatency: %d = %d + %d", initialMillisecondTimestampWithLatency, unsigned(Pt_Time()), preferences.getInt(PREF_IO_PORTMIDI_OUTPUTLATENCYMILLISECONDS));
1807      #endif
1808      }
1809 
1810 //---------------------------------------------------------
1811 //  getCurrentMillisecondTimestampWithLatency
1812 //   Called when midi messages are sent to PortMidi device.
1813 //   Returns the time in milliseconds of the current play cursor.
1814 //   Time is relative to the start of PortMidi's initialization.
1815 //---------------------------------------------------------
1816 
getCurrentMillisecondTimestampWithLatency(unsigned framePos) const1817 unsigned Seq::getCurrentMillisecondTimestampWithLatency(unsigned framePos) const
1818       {
1819 #ifdef USE_PORTMIDI
1820       unsigned playTimeMilliseconds = unsigned(framePos * 1000) / unsigned(MScore::sampleRate);
1821       //qDebug("PortMidi timestamp = %d + %d", initialMillisecondTimestampWithLatency, playTimeMilliseconds);
1822       return initialMillisecondTimestampWithLatency + playTimeMilliseconds;
1823 #else
1824       qDebug("Shouldn't be using this function if not using PortMidi");
1825       return 0;
1826 #endif
1827       }
1828 }
1829