2012-05-26 14:49:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
// MuseScore
|
|
|
|
// Linux Music Score Editor
|
|
|
|
// $Id: playpanel.cpp 4775 2011-09-12 14:25:31Z wschweer $
|
|
|
|
//
|
|
|
|
// Copyright (C) 2002-2011 Werner Schweer and others
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "playpanel.h"
|
|
|
|
#include "libmscore/sig.h"
|
|
|
|
#include "libmscore/score.h"
|
2012-07-02 18:43:11 +02:00
|
|
|
#include "libmscore/repeatlist.h"
|
2012-05-26 14:49:10 +02:00
|
|
|
#include "seq.h"
|
|
|
|
#include "musescore.h"
|
|
|
|
#include "libmscore/measure.h"
|
|
|
|
|
|
|
|
const int MIN_VOL = -60;
|
|
|
|
const int MAX_VOL = 10;
|
|
|
|
|
2013-05-02 19:56:26 +02:00
|
|
|
static const int DEFAULT_POS_X = 300;
|
|
|
|
static const int DEFAULT_POS_Y = 100;
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// PlayPanel
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
PlayPanel::PlayPanel(QWidget* parent)
|
|
|
|
: QWidget(parent, Qt::Dialog)
|
|
|
|
{
|
|
|
|
cachedTickPosition = -1;
|
|
|
|
cachedTimePosition = -1;
|
|
|
|
cs = 0;
|
|
|
|
setupUi(this);
|
2013-02-07 13:10:46 +01:00
|
|
|
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-05-02 19:56:26 +02:00
|
|
|
QSettings settings;
|
|
|
|
restoreGeometry(settings.value("playPanel/geometry").toByteArray());
|
|
|
|
move(settings.value("playPanel/pos", QPoint(DEFAULT_POS_X, DEFAULT_POS_Y)).toPoint());
|
|
|
|
|
2013-02-07 13:10:46 +01:00
|
|
|
setScore(0);
|
2012-05-26 14:49:10 +02:00
|
|
|
playButton->setDefaultAction(getAction("play"));
|
|
|
|
rewindButton->setDefaultAction(getAction("rewind"));
|
|
|
|
metronomeButton->setDefaultAction(getAction("metronome"));
|
|
|
|
|
|
|
|
connect(volumeSlider, SIGNAL(valueChanged(double,int)), SLOT(volumeChanged(double,int)));
|
|
|
|
connect(posSlider, SIGNAL(sliderMoved(int)), SLOT(setPos(int)));
|
|
|
|
connect(tempoSlider, SIGNAL(valueChanged(double,int)), SLOT(relTempoChanged(double,int)));
|
2013-05-03 11:37:28 +02:00
|
|
|
connect(seq, SIGNAL(heartBeat(int,int,int)), SLOT(heartBeat(int,int,int)));
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
2013-05-02 19:56:26 +02:00
|
|
|
PlayPanel::~PlayPanel()
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
// if widget is visible, store geometry and pos into settings
|
|
|
|
// if widget is not visible/closed, pos is not reliable (and anyway
|
|
|
|
// has been stored into settings when the widget has been hidden)
|
|
|
|
if (isVisible()) {
|
|
|
|
settings.setValue("playPanel/pos", pos());
|
|
|
|
settings.setValue("playPanel/geometry", saveGeometry());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// relTempoChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::relTempoChanged(double d, int)
|
|
|
|
{
|
2013-05-03 11:37:28 +02:00
|
|
|
double relTempo = d * .01;
|
|
|
|
emit relTempoChanged(relTempo);
|
|
|
|
|
|
|
|
setTempo(seq->curTempo() * relTempo);
|
|
|
|
setRelTempo(relTempo);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// closeEvent
|
2013-05-02 19:56:26 +02:00
|
|
|
//
|
|
|
|
// Called when the PlyPanel is colsed with its own button
|
|
|
|
// but not when it is hidden with the main menu command
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::closeEvent(QCloseEvent* ev)
|
|
|
|
{
|
|
|
|
emit closed();
|
|
|
|
QWidget::closeEvent(ev);
|
|
|
|
}
|
|
|
|
|
2013-05-02 19:56:26 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// hideEvent
|
|
|
|
//
|
|
|
|
// Called both when the PlayPanel is closed with its own button and
|
|
|
|
// when it is hidden via the main menu command
|
|
|
|
//
|
|
|
|
// Stores widget geometry and position into settings.
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::hideEvent(QHideEvent* ev)
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
settings.setValue("playPanel/pos", pos());
|
|
|
|
settings.setValue("playPanel/geometry", saveGeometry());
|
|
|
|
QWidget::hideEvent(ev);
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// setScore
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::setScore(Score* s)
|
|
|
|
{
|
|
|
|
if (cs != 0 && cs == s)
|
|
|
|
return;
|
|
|
|
cs = s;
|
|
|
|
bool enable = cs != 0;
|
|
|
|
volumeSlider->setEnabled(enable);
|
|
|
|
posSlider->setEnabled(enable);
|
|
|
|
tempoSlider->setEnabled(enable);
|
2012-07-02 18:43:11 +02:00
|
|
|
if (cs && seq && seq->canStart()) {
|
2012-05-26 14:49:10 +02:00
|
|
|
setTempo(cs->tempomap()->tempo(0));
|
|
|
|
setRelTempo(cs->tempomap()->relTempo());
|
2012-07-02 18:43:11 +02:00
|
|
|
setEndpos(cs->repeatList()->ticks());
|
2012-05-26 14:49:10 +02:00
|
|
|
int tick = cs->playPos();
|
2013-05-03 11:37:28 +02:00
|
|
|
heartBeat(tick, tick, 0);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
setTempo(120.0);
|
|
|
|
setRelTempo(1.0);
|
|
|
|
setEndpos(0);
|
2013-05-03 11:37:28 +02:00
|
|
|
heartBeat(0, 0, 0);
|
2012-07-02 21:25:06 +02:00
|
|
|
updatePosLabel(0);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setEndpos
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::setEndpos(int val)
|
|
|
|
{
|
|
|
|
posSlider->setRange(0, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setTempo
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::setTempo(double val)
|
|
|
|
{
|
|
|
|
int tempo = lrint(val * 60.0);
|
|
|
|
tempoLabel->setText(QString("%1 bpm").arg(tempo, 3, 10, QLatin1Char(' ')));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setRelTempo
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::setRelTempo(qreal val)
|
|
|
|
{
|
|
|
|
val *= 100;
|
|
|
|
relTempo->setText(QString("%1 %").arg(val, 3, 'f', 0));
|
|
|
|
tempoSlider->setValue(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setGain
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::setGain(float val)
|
|
|
|
{
|
|
|
|
volumeSlider->setValue(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// volumeChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::volumeChanged(double val, int)
|
|
|
|
{
|
|
|
|
emit gainChange(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setPos
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2012-07-02 18:43:11 +02:00
|
|
|
void PlayPanel::setPos(int utick)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2012-07-02 18:43:11 +02:00
|
|
|
if(!cs)
|
|
|
|
return;
|
|
|
|
if (cachedTickPosition != utick)
|
|
|
|
emit posChange(utick);
|
|
|
|
updatePosLabel(utick);
|
|
|
|
updateTimeLabel(cs->utick2utime(utick));
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// heartBeat
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-05-03 11:37:28 +02:00
|
|
|
void PlayPanel::heartBeat(int tick, int utick, int samples)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2013-05-03 11:37:28 +02:00
|
|
|
if (cachedTickPosition != utick) {
|
|
|
|
updatePosLabel(utick);
|
|
|
|
posSlider->setValue(utick);
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
int sec = samples/MScore::sampleRate;
|
|
|
|
if (sec == cachedTimePosition)
|
|
|
|
return;
|
2012-07-02 18:43:11 +02:00
|
|
|
updateTimeLabel(sec);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// updateTime
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayPanel::updateTimeLabel(int sec)
|
|
|
|
{
|
2012-05-26 14:49:10 +02:00
|
|
|
cachedTimePosition = sec;
|
|
|
|
int m = sec / 60;
|
|
|
|
sec = sec % 60;
|
|
|
|
int h = m / 60;
|
|
|
|
m = m % 60;
|
|
|
|
char buffer[32];
|
|
|
|
sprintf(buffer, "%d:%02d:%02d", h, m, sec);
|
|
|
|
timeLabel->setText(QString(buffer));
|
|
|
|
}
|
|
|
|
|
2012-07-02 18:43:11 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// updatePos
|
|
|
|
//---------------------------------------------------------
|
2013-05-03 11:37:28 +02:00
|
|
|
|
|
|
|
void PlayPanel::updatePosLabel(int utick)
|
2012-07-02 18:43:11 +02:00
|
|
|
{
|
|
|
|
cachedTickPosition = utick;
|
2012-07-02 21:25:06 +02:00
|
|
|
int bar = 0;
|
|
|
|
int beat = 0;
|
|
|
|
int t = 0;
|
|
|
|
int tick = 0;
|
|
|
|
if (cs) {
|
|
|
|
tick = cs->repeatList()->utick2tick(utick);
|
|
|
|
cs->sigmap()->tickValues(tick, &bar, &beat, &t);
|
2013-04-30 20:45:04 +02:00
|
|
|
double tpo = cs->tempomap()->tempo(tick) * cs->tempomap()->relTempo();
|
|
|
|
setTempo(tpo);
|
2012-07-02 21:25:06 +02:00
|
|
|
}
|
2012-07-02 18:43:11 +02:00
|
|
|
char buffer[32];
|
|
|
|
sprintf(buffer, "%03d.%02d", bar+1, beat+1);
|
|
|
|
posLabel->setText(QString(buffer));
|
|
|
|
}
|