2012-05-26 14:49:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
// MuseScore
|
2013-04-19 17:15:30 +02:00
|
|
|
// Music Composition & Notation
|
2012-05-26 14:49:10 +02:00
|
|
|
//
|
2013-04-19 17:15:30 +02:00
|
|
|
// Copyright (C) 2002-2013 Werner Schweer
|
2012-05-26 14:49:10 +02:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
2013-04-19 17:15:30 +02:00
|
|
|
// it under the terms of the GNU General Public License version 2
|
|
|
|
// as published by the Free Software Foundation and appearing in
|
|
|
|
// the file LICENCE.GPL
|
2012-05-26 14:49:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "synthcontrol.h"
|
|
|
|
#include "musescore.h"
|
|
|
|
#include "seq.h"
|
2013-04-02 20:46:07 +02:00
|
|
|
#include "synthesizer/msynthesizer.h"
|
2013-03-26 19:59:51 +01:00
|
|
|
#include "synthesizer/synthesizer.h"
|
2013-04-02 20:46:07 +02:00
|
|
|
#include "synthesizer/synthesizergui.h"
|
2013-04-22 17:17:19 +02:00
|
|
|
// #include "aeolus/aeolus/aeolus.h"
|
2012-05-26 14:49:10 +02:00
|
|
|
#include "mixer.h"
|
|
|
|
#include "file.h"
|
|
|
|
#include "icons.h"
|
2013-04-02 20:46:07 +02:00
|
|
|
#include "libmscore/score.h"
|
2012-05-26 14:49:10 +02:00
|
|
|
#include "libmscore/mscore.h"
|
2013-04-19 17:15:30 +02:00
|
|
|
#include "libmscore/xml.h"
|
2013-04-02 20:46:07 +02:00
|
|
|
#include "libmscore/undo.h"
|
|
|
|
#include "effects/effectgui.h"
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-03-26 19:59:51 +01:00
|
|
|
extern MasterSynthesizer* synti;
|
2013-04-02 20:46:07 +02:00
|
|
|
extern bool useFactorySettings;
|
|
|
|
|
|
|
|
static std::vector<const char*> effectNames = { "None", "Freeverb", "Zita1" };
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// SynthControl
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
SynthControl::SynthControl(QWidget* parent)
|
|
|
|
: QWidget(parent, Qt::Dialog)
|
|
|
|
{
|
|
|
|
setupUi(this);
|
2013-04-02 20:46:07 +02:00
|
|
|
_score = 0;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-04-03 20:20:36 +02:00
|
|
|
int idx = 0;
|
2013-04-19 17:15:30 +02:00
|
|
|
for (Synthesizer* s : synti->synthesizer()) {
|
2013-04-03 20:20:36 +02:00
|
|
|
tabWidget->insertTab(idx++, s->gui(), tr(s->name()));
|
2013-04-19 21:13:52 +02:00
|
|
|
s->gui()->synthesizerChanged();
|
2013-04-19 17:15:30 +02:00
|
|
|
connect(s->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
// effectA combo box
|
|
|
|
// effectStackA widget stack
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
effectA->clear();
|
|
|
|
for (Effect* e : synti->effectList(0)) {
|
|
|
|
effectA->addItem(tr(e->name()));
|
|
|
|
effectStackA->addWidget(e->gui());
|
2013-04-19 17:15:30 +02:00
|
|
|
connect(e->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
2013-04-02 20:46:07 +02:00
|
|
|
}
|
2013-03-27 20:10:14 +01:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
effectB->clear();
|
|
|
|
for (Effect* e : synti->effectList(1)) {
|
|
|
|
effectB->addItem(tr(e->name()));
|
|
|
|
effectStackB->addWidget(e->gui());
|
2013-04-19 17:15:30 +02:00
|
|
|
connect(e->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
2013-04-02 20:46:07 +02:00
|
|
|
}
|
2013-03-27 20:10:14 +01:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
if (!useFactorySettings) {
|
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup("SynthControl");
|
|
|
|
resize(settings.value("size", QSize(600, 268)).toSize());
|
|
|
|
move(settings.value("pos", QPoint(10, 10)).toPoint());
|
|
|
|
settings.endGroup();
|
|
|
|
}
|
2013-03-26 19:59:51 +01:00
|
|
|
|
2013-04-19 21:13:52 +02:00
|
|
|
updateGui();
|
2013-04-03 18:11:38 +02:00
|
|
|
|
2013-04-03 12:13:23 +02:00
|
|
|
tabWidget->setCurrentIndex(0);
|
2013-04-19 17:15:30 +02:00
|
|
|
storeButton->setEnabled(false);
|
|
|
|
recallButton->setEnabled(false);
|
|
|
|
changeTuningButton->setEnabled(false);
|
2013-04-03 12:13:23 +02:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
connect(effectA, SIGNAL(currentIndexChanged(int)), SLOT(effectAChanged(int)));
|
|
|
|
connect(effectB, SIGNAL(currentIndexChanged(int)), SLOT(effectBChanged(int)));
|
|
|
|
connect(gain, SIGNAL(valueChanged(double,int)), SLOT(gainChanged(double,int)));
|
|
|
|
connect(masterTuning, SIGNAL(valueChanged(double)), SLOT(masterTuningChanged(double)));
|
2013-04-19 17:15:30 +02:00
|
|
|
connect(changeTuningButton, SIGNAL(clicked()), SLOT(changeMasterTuning()));
|
2013-04-03 12:13:23 +02:00
|
|
|
connect(loadButton, SIGNAL(clicked()), SLOT(loadButtonClicked()));
|
|
|
|
connect(saveButton, SIGNAL(clicked()), SLOT(saveButtonClicked()));
|
2013-04-19 17:15:30 +02:00
|
|
|
connect(storeButton, SIGNAL(clicked()), SLOT(storeButtonClicked()));
|
|
|
|
connect(recallButton, SIGNAL(clicked()), SLOT(recallButtonClicked()));
|
|
|
|
connect(gain, SIGNAL(valueChanged(double,int)), SLOT(setDirty()));
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setGain
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::setGain(float val)
|
|
|
|
{
|
|
|
|
gain->setValue(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// closeEvent
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::closeEvent(QCloseEvent* ev)
|
|
|
|
{
|
|
|
|
emit closed(false);
|
|
|
|
QWidget::closeEvent(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// showSynthControl
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void MuseScore::showSynthControl()
|
|
|
|
{
|
|
|
|
QAction* a = getAction("synth-control");
|
|
|
|
|
|
|
|
if (synthControl == 0) {
|
|
|
|
synthControl = new SynthControl(this);
|
|
|
|
synthControl->setScore(cs);
|
|
|
|
connect(synthControl, SIGNAL(closed(bool)), a, SLOT(setChecked(bool)));
|
2013-04-03 12:49:55 +02:00
|
|
|
connect(synti, SIGNAL(gainChanged(float)), synthControl, SLOT(setGain(float)));
|
|
|
|
connect(synthControl, SIGNAL(gainChanged(float)), synti, SLOT(setGain(float)));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-04-03 12:13:23 +02:00
|
|
|
if (mixer) {
|
|
|
|
connect(synthControl, SIGNAL(soundFontChanged()), mixer,
|
2012-05-26 14:49:10 +02:00
|
|
|
SLOT(patchListChanged()));
|
|
|
|
}
|
|
|
|
}
|
2012-05-31 16:24:35 +02:00
|
|
|
synthControl->setVisible(a->isChecked());
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// gainChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::gainChanged(double val, int)
|
|
|
|
{
|
|
|
|
emit gainChanged(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// masterTuningChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::masterTuningChanged(double val)
|
|
|
|
{
|
2013-04-19 17:15:30 +02:00
|
|
|
changeTuningButton->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// changeMasterTuning
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::changeMasterTuning()
|
|
|
|
{
|
|
|
|
synti->setMasterTuning(masterTuning->value());
|
|
|
|
changeTuningButton->setEnabled(false);
|
|
|
|
setDirty();
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setMeter
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::setMeter(float l, float r, float left_peak, float right_peak)
|
|
|
|
{
|
|
|
|
gain->setMeterVal(0, l, left_peak);
|
|
|
|
gain->setMeterVal(1, r, right_peak);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// stop
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::stop()
|
|
|
|
{
|
|
|
|
gain->setMeterVal(0, .0, .0);
|
|
|
|
gain->setMeterVal(1, .0, .0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2013-04-02 20:46:07 +02:00
|
|
|
// effectAChanged
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
void SynthControl::effectAChanged(int idx)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2013-04-02 20:46:07 +02:00
|
|
|
synti->setEffect(0, idx);
|
|
|
|
effectStackA->setCurrentIndex(idx);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2013-04-02 20:46:07 +02:00
|
|
|
// effectBChanged
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
void SynthControl::effectBChanged(int idx)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2013-04-02 20:46:07 +02:00
|
|
|
synti->setEffect(1, idx);
|
|
|
|
effectStackB->setCurrentIndex(idx);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2013-04-02 20:46:07 +02:00
|
|
|
// loadButtonClicked
|
|
|
|
// load synthesizer settings from score
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
void SynthControl::loadButtonClicked()
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2013-04-19 17:15:30 +02:00
|
|
|
if (!_score)
|
|
|
|
return;
|
2013-04-02 20:46:07 +02:00
|
|
|
synti->setState(_score->synthesizerState());
|
2013-04-19 21:13:52 +02:00
|
|
|
updateGui();
|
2013-04-19 17:15:30 +02:00
|
|
|
loadButton->setEnabled(false);
|
|
|
|
saveButton->setEnabled(false);
|
|
|
|
storeButton->setEnabled(true);
|
|
|
|
recallButton->setEnabled(true);
|
|
|
|
changeTuningButton->setEnabled(false);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2013-04-02 20:46:07 +02:00
|
|
|
// saveButtonClicked
|
|
|
|
// save synthesizer settings to score
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
void SynthControl::saveButtonClicked()
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2013-04-19 17:15:30 +02:00
|
|
|
if (!_score)
|
|
|
|
return;
|
|
|
|
_score->startCmd();
|
|
|
|
_score->undo()->push(new ChangeSynthesizerState(_score, synti->state()));
|
|
|
|
_score->endCmd();
|
|
|
|
mscore->endCmd();
|
|
|
|
|
|
|
|
loadButton->setEnabled(false);
|
|
|
|
saveButton->setEnabled(false);
|
|
|
|
storeButton->setEnabled(true);
|
|
|
|
recallButton->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// recallButtonClicked
|
|
|
|
// load stored synthesizer settings
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::recallButtonClicked()
|
|
|
|
{
|
|
|
|
if (!_score) {
|
|
|
|
qDebug("no score");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SynthesizerState state;
|
|
|
|
QString s(dataPath + "/synthesizer.xml");
|
|
|
|
QFile f(s);
|
|
|
|
if (!f.open(QIODevice::ReadOnly)) {
|
|
|
|
qDebug("cannot read synthesizer settings <%s>", qPrintable(s));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
XmlReader e(&f);
|
|
|
|
while (e.readNextStartElement()) {
|
|
|
|
if (e.name() == "Synthesizer")
|
|
|
|
state.read(e);
|
|
|
|
else
|
|
|
|
e.unknown();
|
|
|
|
}
|
|
|
|
synti->setState(state);
|
2013-04-19 21:13:52 +02:00
|
|
|
updateGui();
|
2013-04-19 17:15:30 +02:00
|
|
|
|
|
|
|
storeButton->setEnabled(false);
|
|
|
|
recallButton->setEnabled(false);
|
|
|
|
|
|
|
|
loadButton->setEnabled(true);
|
|
|
|
saveButton->setEnabled(true);
|
|
|
|
changeTuningButton->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// storeButtonClicked
|
|
|
|
// save synthesizer settings
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::storeButtonClicked()
|
|
|
|
{
|
|
|
|
if (!_score) {
|
|
|
|
qDebug("no score");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
QString s(dataPath + "/synthesizer.xml");
|
|
|
|
QFile f(s);
|
|
|
|
if (!f.open(QIODevice::WriteOnly)) {
|
|
|
|
qDebug("cannot write synthesizer settings <%s>", qPrintable(s));
|
|
|
|
return;
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2013-04-19 17:15:30 +02:00
|
|
|
Xml xml(&f);
|
|
|
|
xml.header();
|
|
|
|
synti->state().write(xml);
|
|
|
|
|
|
|
|
storeButton->setEnabled(false);
|
|
|
|
recallButton->setEnabled(false);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2013-04-19 21:13:52 +02:00
|
|
|
// Gui
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-04-19 21:13:52 +02:00
|
|
|
void SynthControl::updateGui()
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2013-04-02 20:46:07 +02:00
|
|
|
masterTuning->setValue(synti->masterTuning());
|
2013-04-03 12:49:55 +02:00
|
|
|
setGain(synti->gain());
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
int idx = synti->indexOfEffect(0);
|
|
|
|
effectA->setCurrentIndex(idx);
|
|
|
|
effectStackA->setCurrentIndex(idx);
|
|
|
|
synti->effect(0)->gui()->updateValues();
|
|
|
|
synti->effect(1)->gui()->updateValues();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-04-02 20:46:07 +02:00
|
|
|
idx = synti->indexOfEffect(1);
|
|
|
|
effectB->setCurrentIndex(idx);
|
|
|
|
effectStackB->setCurrentIndex(idx);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
2013-04-19 17:15:30 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// setDirty
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void SynthControl::setDirty()
|
|
|
|
{
|
|
|
|
loadButton->setEnabled(true);
|
|
|
|
saveButton->setEnabled(true);
|
|
|
|
storeButton->setEnabled(true);
|
|
|
|
recallButton->setEnabled(true);
|
|
|
|
}
|
|
|
|
|