diff --git a/libmscore/score.cpp b/libmscore/score.cpp index 99edd34918..b4235b14f7 100644 --- a/libmscore/score.cpp +++ b/libmscore/score.cpp @@ -311,6 +311,8 @@ void Score::init() _dirty = false; _saved = false; _playPos = 0; + _loopInTick = -1; + _loopOutTick = -1; _fileDivision = MScore::division; _creditsRead = false; _defaultsRead = false; @@ -3498,5 +3500,31 @@ void Score::insertTime(int tick, int len) } } + +//--------------------------------------------------------- +// set Loop In position +//--------------------------------------------------------- + +void Score::setLoopInTick(int tick) + { + qDebug ("setLoopInTick : tick = %d", tick); + if ((tick < 0) || (tick > lastMeasure()->endTick()-1)) + tick = 0; + _loopInTick = tick; + } + +//--------------------------------------------------------- +// set Loop Out position +//--------------------------------------------------------- + +void Score::setLoopOutTick(int tick) + { + qDebug ("setLoopOutTick : tick = %d", tick); + int lastTick = lastMeasure()->endTick()-1; + if ((tick > lastTick) || (tick < 0)) + _loopOutTick = lastTick; + else + _loopOutTick = tick; + } } diff --git a/libmscore/score.h b/libmscore/score.h index 8099f489e1..fdf6db209c 100644 --- a/libmscore/score.h +++ b/libmscore/score.h @@ -333,6 +333,8 @@ class Score : public QObject { QList _staves; int _playPos; ///< sequencer seek position + int _loopInTick; ///< In tick for loop play position + int _loopOutTick; ///< Out tick for loop play position bool _foundPlayPosAfterRepeats; ///< Temporary used during playback rendering ///< indicating if playPos after expanded repeats @@ -632,6 +634,10 @@ class Score : public QObject { bool playlistDirty(); void setPlaylistDirty(bool val) { _playlistDirty = val; } + int loopInTick() { return _loopInTick; } + int loopOutTick() { return _loopOutTick; } + void setLoopInTick(int tick); + void setLoopOutTick(int tick); void cmd(const QAction*); int fileDivision(int t) const { return (t * MScore::division + _fileDivision/2) / _fileDivision; } diff --git a/mscore/actions.cpp b/mscore/actions.cpp index 2f041bfe54..8ddf125517 100644 --- a/mscore/actions.cpp +++ b/mscore/actions.cpp @@ -2031,7 +2031,7 @@ Shortcut Shortcut::sc[] = { QT_TRANSLATE_NOOP("action","Show OMR Panel") ), Shortcut( - STATE_NORMAL | STATE_NOTE_ENTRY | STATE_PLAY | STATE_EDIT | STATE_LYRICS_EDIT, + STATE_NORMAL | STATE_NOTE_ENTRY | STATE_PLAY, 0, "loop", QT_TRANSLATE_NOOP("action","Loop"), @@ -2040,7 +2040,7 @@ Shortcut Shortcut::sc[] = { loop_ICON ), Shortcut( - STATE_NORMAL | STATE_NOTE_ENTRY | STATE_PLAY | STATE_EDIT | STATE_LYRICS_EDIT, + STATE_NORMAL | STATE_NOTE_ENTRY | STATE_PLAY, 0, "loop-in", QT_TRANSLATE_NOOP("action","Loop in"), @@ -2049,7 +2049,7 @@ Shortcut Shortcut::sc[] = { loopIn_ICON ), Shortcut( - STATE_NORMAL | STATE_NOTE_ENTRY | STATE_PLAY | STATE_EDIT | STATE_LYRICS_EDIT, + STATE_NORMAL | STATE_NOTE_ENTRY | STATE_PLAY, 0, "loop-out", QT_TRANSLATE_NOOP("action","Loop out"), diff --git a/mscore/musescore.cpp b/mscore/musescore.cpp index 08b9643b7e..7aaa70ef65 100644 --- a/mscore/musescore.cpp +++ b/mscore/musescore.cpp @@ -4154,13 +4154,16 @@ void MuseScore::cmd(QAction* a, const QString& cmd) else if (cmd == "loop") { qDebug("loopAction = %d", loopAction->isChecked()); if (loopAction->isChecked()) { - cv->showLoopInCursor(); - cv->showLoopOutCursor(); + if(cs->selection().state() == SEL_RANGE) { + seq->setLoopSelection(); + loopInAction->setChecked(true); + loopOutAction->setChecked(true); + } + cv->showLoopCursors(); } else { seq->loopStop(); - cv->hideLoopInCursor(); - cv->hideLoopOutCursor(); + cv->hideLoopCursors(); } } else if (cmd == "loop-in") { @@ -4168,7 +4171,7 @@ void MuseScore::cmd(QAction* a, const QString& cmd) seq->setLoopIn(); if (!loopAction->isChecked()) loopAction->trigger(); - cv->showLoopInCursor(); + //cv->showLoopCursors(); } else { seq->unsetLoopIn(); @@ -4179,7 +4182,7 @@ void MuseScore::cmd(QAction* a, const QString& cmd) seq->setLoopOut(); if (!loopAction->isChecked()) loopAction->trigger(); - cv->showLoopOutCursor(); + //cv->showLoopCursors(); } else { seq->unsetLoopOut(); diff --git a/mscore/scoreview.cpp b/mscore/scoreview.cpp index b620905934..3e172f6f94 100644 --- a/mscore/scoreview.cpp +++ b/mscore/scoreview.cpp @@ -658,7 +658,6 @@ ScoreView::ScoreView(QWidget* parent) editObject = 0; addSelect = false; - // Create and initialize the Loop In/Out cursors _curLoopIn = new TextCursor; QColor cIn(Qt::green); cIn.setAlpha(80); @@ -1449,8 +1448,7 @@ void ScoreView::setCursorOn(bool val) void ScoreView::setLoopCursor(TextCursor *curLoop, int tick, bool isInPos) { - if (tick > _score->lastMeasure()->endTick()-1) - tick = _score->lastMeasure()->endTick()-1; + qDebug ("setLoopCursor : tick=%d, isInPos=%d",tick, isInPos); // // set mark height for whole system // @@ -1537,9 +1535,11 @@ void ScoreView::setLoopCursor(TextCursor *curLoop, int tick, bool isInPos) // adjust the cursor shape and position to mark the beginning of the loop //--------------------------------------------------------- -void ScoreView::setLoopInCursor(int tick) +void ScoreView::setLoopInCursor() { - setLoopCursor(_curLoopIn, tick, true); + if (_score->loopInTick() < 0) + _score->setLoopInTick(-1); + setLoopCursor(_curLoopIn, _score->loopInTick(), true); update(); } @@ -1548,9 +1548,11 @@ void ScoreView::setLoopInCursor(int tick) // adjust the cursor shape and position to mark the end of the loop //--------------------------------------------------------- -void ScoreView::setLoopOutCursor(int tick) +void ScoreView::setLoopOutCursor() { - setLoopCursor(_curLoopOut, tick, false); + if (_score->loopOutTick() < 0) + _score->setLoopOutTick(-1); + setLoopCursor(_curLoopOut, _score->loopOutTick(),false); update(); } @@ -1561,55 +1563,35 @@ void ScoreView::setLoopOutCursor(int tick) void ScoreView::updateLoopCursors() { - setLoopCursor(_curLoopIn, _curLoopIn->tick(), true); - setLoopCursor(_curLoopOut, _curLoopOut->tick(), false); + setLoopInCursor(); // In pos + setLoopOutCursor(); // Out pos } //--------------------------------------------------------- -// showLoopInCursor -// show the In mark for the loop +// showLoopCursors +// show the In/Out marks for the loop //--------------------------------------------------------- -void ScoreView::showLoopInCursor() +void ScoreView::showLoopCursors() { if (_curLoopIn->tick() < 0) - setLoopInCursor(0); + setLoopInCursor(); + if (_curLoopOut->tick() < 0) + setLoopOutCursor(); _curLoopIn->setVisible(true); - qDebug("==== Show loop in tick = %d",_curLoopIn->tick()); - update(); - } - -//--------------------------------------------------------- -// showLoopOutCursor -// show the Out mark for the loop -//--------------------------------------------------------- - -void ScoreView::showLoopOutCursor() - { - if ((_curLoopOut->tick() < 0) || (_curLoopOut->tick() > _score->lastMeasure()->endTick()-1)) - setLoopOutCursor(_score->lastMeasure()->endTick()-1); _curLoopOut->setVisible(true); + //qDebug("==== Show loop in tick = %d",_curLoopIn->tick()); update(); } //--------------------------------------------------------- -// hideLoopInCursor -// hide the In mark for the loop +// hideLoopCursors +// hide the In/Out marks for the loop //--------------------------------------------------------- -void ScoreView::hideLoopInCursor() +void ScoreView::hideLoopCursors() { _curLoopIn->setVisible(false); - update(); - } - -//--------------------------------------------------------- -// hideLoopOutCursor -// hide the Out mark for the loop -//--------------------------------------------------------- - -void ScoreView::hideLoopOutCursor() - { _curLoopOut->setVisible(false); update(); } diff --git a/mscore/scoreview.h b/mscore/scoreview.h index 523072a4c7..1144bd821f 100644 --- a/mscore/scoreview.h +++ b/mscore/scoreview.h @@ -269,8 +269,6 @@ class ScoreView : public QWidget, public MuseScoreView { void paintPageBorder(QPainter& p, Page* page); bool dropCanvas(Element*); void editCmd(const QString&); - void resetLoopInCursors(); - void resetLoopOutCursors(); void setLoopCursor(TextCursor *curLoop, int tick, bool isInPos); private slots: @@ -424,13 +422,15 @@ class ScoreView : public QWidget, public MuseScoreView { int loopInPos() { return _curLoopIn->tick(); } int loopOutPos() { return _curLoopOut->tick(); } - void setLoopInCursor(int tick); - void setLoopOutCursor(int tick); + void setLoopInCursor(); + void setLoopOutCursor(); void updateLoopCursors(); void showLoopInCursor(); + void showLoopCursors(); void showLoopOutCursor(); void hideLoopInCursor(); void hideLoopOutCursor(); + void hideLoopCursors(); virtual void moveCursor(); virtual void layoutChanged(); diff --git a/mscore/seq.cpp b/mscore/seq.cpp index ad5dfac4a5..55f1c0858d 100644 --- a/mscore/seq.cpp +++ b/mscore/seq.cpp @@ -333,20 +333,21 @@ void Seq::start() oggInit = true; } } - if ((mscore->loop())) { // && (cv->loopOutPos() > cv->loopInPos()) + if ((mscore->loop())) { if (mscore->isLoopOut()) { // Add loop Out event NPlayEvent event; event.setType(ME_LOOP); // insert ME_LOOP as first event if there are events with same tick - auto hint = events.lower_bound(cv->loopOutPos()); - events.insert(hint, std::pair(cv->loopOutPos(), event)); - if (cv->loopOutPos() < cv->loopInPos()) + auto hint = events.lower_bound(cs->loopOutTick()); + events.insert(hint, std::pair(cs->loopOutTick(), event)); + qDebug ("Add loop event at tick %d (loopInTick = %d)", cs->loopOutTick(), cs->loopInTick()); + if (cs->loopOutTick() < cs->loopInTick()) seek(0); // If Out pos < In pos, restart playback at the beginning. else - seek(cv->loopInPos()); + seek(cs->loopInTick()); } else - seek(cv->loopInPos()); + seek(cs->loopInTick()); } else @@ -692,8 +693,8 @@ void Seq::process(unsigned n, float* buffer) else if (event.type() == ME_TICK2) tackRest = tackLength; else if (event.type() == ME_LOOP) { - qDebug ("event.type() == ME_LOOP loopOutPos = %d | getCurTick() = %d ", cv->loopOutPos(), getCurTick()); - seek(cv->loopInPos()); + qDebug ("event.type() == ME_LOOP in/out tick = %d/%d loop | getCurTick() = %d ", cs->loopInTick(), cs->loopOutTick(), getCurTick()); + seek(cs->loopInTick()); return; } mutex.lock(); @@ -1270,7 +1271,8 @@ void Seq::setLoopIn() tick = playPos->first; // En mode playback, set the In position where note is being played else tick = cs->pos(); // Otherwise, use the selected note. - cv->setLoopInCursor(tick); + cs->setLoopInTick(tick); + cv->updateLoopCursors(); // qDebug ("setLoopIn : tick = %d\n",tick); } @@ -1286,8 +1288,22 @@ void Seq::setLoopOut() else tick = cs->pos()+cs->inputState().ticks(); // Otherwise, use the selected note. // cv->setLoopOutCursor(tick-1); // Remove 1 to avoid overlapping the following events and elements - cv->setLoopOutCursor(tick); + cs->setLoopOutTick(tick); // qDebug ("setLoopOut : loopOutPos = %d ; cs->pos() = %d + cs->inputState().ticks() = %d\n",loopOutPos, cs->pos(), cs->inputState().ticks()); + cv->updateLoopCursors(); + } + + +//--------------------------------------------------------- +// set Loop In/Out position based on the selection +//--------------------------------------------------------- + +void Seq::setLoopSelection() + { + cs->setLoopInTick(cs->selection().tickStart()); + cs->setLoopOutTick(cs->selection().tickEnd()); + qDebug ("setLoopSelection : loopInTick = %d loopOutTick = %d\n",cs->selection().tickStart(), cs->pos(), cs->selection().tickEnd()); + cv->updateLoopCursors(); } //--------------------------------------------------------- @@ -1297,7 +1313,8 @@ void Seq::setLoopOut() void Seq::unsetLoopIn() { // Reinitialize the In loop position - cv->setLoopInCursor(0); + cs->setLoopInTick(-1); + cv->updateLoopCursors(); } //--------------------------------------------------------- @@ -1309,6 +1326,7 @@ void Seq::unsetLoopOut() loopStop(); // Erase the loop event // Reinitialize the Out loop position - cv->setLoopOutCursor(cs->lastMeasure()->endTick()-1); + cs->setLoopOutTick(-1); + cv->updateLoopCursors(); } } diff --git a/mscore/seq.h b/mscore/seq.h index 7a2a7543e1..ec13a351a5 100644 --- a/mscore/seq.h +++ b/mscore/seq.h @@ -177,6 +177,7 @@ class Seq : public QObject, public Sequencer { void setLoopOut(); void unsetLoopIn(); void unsetLoopOut(); + void setLoopSelection(); bool init(); void exit();