Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ release:
cd build.release; \
export PATH=${BINPATH}; \
cmake -DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_EXPORT_COMPILE_COMMANDS=1 \
-DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \
-DCMAKE_INSTALL_PREFIX="${PREFIX}" \
-DMSCORE_INSTALL_SUFFIX="${SUFFIX}" \
Expand Down Expand Up @@ -91,6 +92,7 @@ debug:
cd build.debug; \
export PATH=${BINPATH}; \
cmake -DCMAKE_BUILD_TYPE=DEBUG \
-DCMAKE_EXPORT_COMPILE_COMMANDS=1 \
-DCMAKE_INSTALL_PREFIX="${PREFIX}" \
-DMSCORE_INSTALL_SUFFIX="${SUFFIX}" \
-DMUSESCORE_LABEL="${LABEL}" \
Expand Down Expand Up @@ -222,5 +224,3 @@ unix:

zip:
zip -q -r MuseScore-${VERSION}.zip * -x .git\* -x vtest/html\*


2 changes: 1 addition & 1 deletion mscore/drumroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ DrumrollEditor::DrumrollEditor(QWidget* parent)
tb->addSeparator();
#ifdef HAS_MIDI
tb->addAction(getAction("midi-on"));
tb->addAction(getAction("play-along"));
#endif
QAction* a = getAction("follow");
a->setCheckable(true);
Expand Down Expand Up @@ -427,4 +428,3 @@ void DrumrollEditor::cmd(QAction* a)
gv->setStaff(staff, locator);
}
}

5 changes: 5 additions & 0 deletions mscore/musescore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const std::list<const char*> MuseScore::_allPlaybackControlEntries {
#ifdef HAS_MIDI
"midi-on",
"",
"play-along",
"",
#endif
"rewind",
"play",
Expand Down Expand Up @@ -6592,6 +6594,9 @@ void MuseScore::cmd(QAction* a, const QString& cmd)
}
}
#endif
else if (cmd == "play-along") {
seq->setPlayAlong(a->isChecked());
}
else {
if (cv) {
//isAncestorOf is called to see if a widget from inspector has focus
Expand Down
1 change: 1 addition & 0 deletions mscore/pianoroll/pianoroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ PianorollEditor::PianorollEditor(QWidget* parent)
tbMain->addSeparator();
#ifdef HAS_MIDI
tbMain->addAction(getAction("midi-on"));
tbMain->addAction(getAction("play-along"));
#endif
tbMain->addSeparator();

Expand Down
49 changes: 49 additions & 0 deletions mscore/seq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ static long ovTell(void* datasource)
Seq::Seq()
: midi(nullptr)
{
playAlong = false;
running = false;
playlistChanged = false;
cs = 0;
Expand Down Expand Up @@ -617,6 +618,10 @@ void Seq::processMessages()
break;
case SeqMsgId::PLAY:
putEvent(msg.event);
if (playAlong) {
qDebug("Event: %d %d %d", msg.event.type(), msg.event.pitch(), msg.event.channel());
handlePlayAlong(msg.event);
}
break;
case SeqMsgId::SEEK:
setPos(msg.intVal);
Expand All @@ -630,6 +635,37 @@ void Seq::processMessages()
}
}

void Seq::handlePlayAlong(NPlayEvent &event)
{
if (event.type() == ME_NOTEON && event.velo() != 0){
pressed_notes.insert(event.pitch());
}

for (auto pending_note : pending_notes) {
bool note_found = false;
for (auto pressed_note : pressed_notes) {
if (pending_note->pitch() == pressed_note) {
pending_notes.erase(pending_note);
note_found = true;
break;
}
}

if(note_found) {
break;
}
}

if (event.velo() == 0 || event.type() == ME_NOTEOFF){
for (auto pressed_note : pressed_notes){
if (event.pitch() == pressed_note) {
pressed_notes.erase(pressed_note);
break;
}
}
}
}

//---------------------------------------------------------
// metronome
//---------------------------------------------------------
Expand Down Expand Up @@ -787,6 +823,10 @@ void Seq::process(unsigned framesPerPeriod, float* buffer)
processMessages();

if (state == Transport::PLAY) {
if (playAlong && !pending_notes.empty()) {
return;
}

if (!cs)
return;

Expand Down Expand Up @@ -889,7 +929,9 @@ void Seq::process(unsigned framesPerPeriod, float* buffer)
}
}
const NPlayEvent& event = (*pPlayPos)->second;

playEvent(event, framePos);

if (event.type() == ME_TICK1) {
tickRemain = tickLength;
tickVolume = event.velo() ? qreal(event.value()) / 127.0 : 1.0;
Expand Down Expand Up @@ -944,6 +986,7 @@ void Seq::process(unsigned framesPerPeriod, float* buffer)
}
}
else {
pending_notes.clear();
// Outside of playback mode
while (!liveEventQueue()->empty()) {
const NPlayEvent& event = liveEventQueue()->dequeue();
Expand Down Expand Up @@ -1154,6 +1197,10 @@ void Seq::setRelTempo(double relTempo)
guiToSeq(SeqMsg(SeqMsgId::TEMPO_CHANGE, relTempo));
}

void Seq::setPlayAlong(bool play)
{
playAlong = play;
}
//---------------------------------------------------------
// setPos
// seek
Expand Down Expand Up @@ -1637,6 +1684,7 @@ void Seq::heartBeatTimeout()
if (!se->isNote())
continue;
Note* currentNote = toNote(se);
pending_notes.insert(currentNote);
currentNote->setMark(true);
markedNotes.append(currentNote);
r |= currentNote->canvasBoundingRect();
Expand All @@ -1651,6 +1699,7 @@ void Seq::heartBeatTimeout()
continue;
Note* currentNote = toNote(se);
currentNote->setMark(false);
currentNote->setColor(Qt::blue);
r |= currentNote->canvasBoundingRect();
markedNotes.removeOne(currentNote);
}
Expand Down
8 changes: 7 additions & 1 deletion mscore/seq.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "libmscore/fraction.h"
#include "libmscore/fifo.h"
#include "libmscore/tempo.h"
#include <set>

#include "audio/midi/event.h"
#include "audio/drivers/driver.h"
Expand Down Expand Up @@ -107,6 +108,9 @@ class Seq : public QObject, public Sequencer {
Q_OBJECT

mutable QMutex mutex;
std::set<Note*> pending_notes;
std::set<int> pressed_notes;
bool playAlong;

MasterScore* cs;
ScoreView* cv;
Expand Down Expand Up @@ -205,6 +209,8 @@ class Seq : public QObject, public Sequencer {

inline QQueue<NPlayEvent>* liveEventQueue() { return &_liveEventQueue; }

void handlePlayAlong(NPlayEvent &event);

private slots:
void seqMessage(int msg, int arg = 0);
void heartBeatTimeout();
Expand Down Expand Up @@ -292,6 +298,7 @@ class Seq : public QObject, public Sequencer {
unsigned getCurrentMillisecondTimestampWithLatency(unsigned framePos) const;

void preferencesChanged() { cachedPrefs.update(); }
void setPlayAlong(bool);
};

extern Seq* seq;
Expand All @@ -300,4 +307,3 @@ extern bool initMidi();

} // namespace Ms
#endif

12 changes: 11 additions & 1 deletion mscore/shortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,17 @@ Shortcut Shortcut::_sc[] = {
Qt::WindowShortcut,
ShortcutFlags::A_CHECKABLE
},
{
MsWidget::MAIN_WINDOW,
STATE_NORMAL | STATE_NOTE_ENTRY,
"play-along",
QT_TRANSLATE_NOOP("action","Play along"),
QT_TRANSLATE_NOOP("action","Toggle 'Play Along'"),
0,
Icons::midiin_ICON,
Qt::WindowShortcut,
ShortcutFlags::A_CHECKABLE
},
{
MsWidget::SCORE_TAB,
STATE_NORMAL | STATE_NOTE_ENTRY,
Expand Down Expand Up @@ -4779,4 +4790,3 @@ QKeySequence Shortcut::keySeqFromString(const QString& str, QKeySequence::Sequen
return keySeq;
}
}

1 change: 1 addition & 0 deletions share/workspaces/Advanced.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3355,6 +3355,7 @@
<action>repeat</action>
<action>pan</action>
<action>metronome</action>
<action>play-along</action>
</Toolbar>
</Workspace>
</museScore>
3 changes: 2 additions & 1 deletion share/workspaces/Basic.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.00">
<Workspace>
<Workspace>
<source>Basic</source>
<PaletteBox>
<Palette name="Clefs">
Expand Down Expand Up @@ -923,6 +923,7 @@
<action>repeat</action>
<action>pan</action>
<action>metronome</action>
<action>play-along</action>
</Toolbar>
</Workspace>
</museScore>