add store/recall global synthesizer settings; connect tuning settings
This commit is contained in:
parent
725882fcdb
commit
2deb49be5a
17 changed files with 314 additions and 146 deletions
|
@ -51,7 +51,10 @@ void EffectGui::init(QUrl& url)
|
||||||
|
|
||||||
void EffectGui::valueChanged(const QString& msg, qreal val)
|
void EffectGui::valueChanged(const QString& msg, qreal val)
|
||||||
{
|
{
|
||||||
|
if (_effect->value(msg) != val) {
|
||||||
_effect->setValue(msg, val);
|
_effect->setValue(msg, val);
|
||||||
|
emit valueChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
|
@ -23,6 +23,9 @@ class EffectGui : public QDeclarativeView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Effect* _effect;
|
Effect* _effect;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void valueChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void valueChanged(const QString& name, qreal);
|
void valueChanged(const QString& name, qreal);
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,7 @@ void FluidGui::soundFontAddClicked()
|
||||||
else {
|
else {
|
||||||
soundFonts->insertItem(0, sfName);
|
soundFonts->insertItem(0, sfName);
|
||||||
emit sfChanged();
|
emit sfChanged();
|
||||||
|
emit valueChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateUpDownButtons();
|
updateUpDownButtons();
|
||||||
|
|
|
@ -40,7 +40,9 @@ class SynthesizerGroup : public std::list<IdValue> {
|
||||||
public:
|
public:
|
||||||
const QString& name() const { return _name; }
|
const QString& name() const { return _name; }
|
||||||
void setName(const QString& s) { _name = s; }
|
void setName(const QString& s) { _name = s; }
|
||||||
|
|
||||||
SynthesizerGroup() : std::list<IdValue>() {}
|
SynthesizerGroup() : std::list<IdValue>() {}
|
||||||
|
SynthesizerGroup(const char* n, std::list<IdValue> l) : std::list<IdValue>(l), _name(n) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -50,7 +52,11 @@ class SynthesizerGroup : public std::list<IdValue> {
|
||||||
class SynthesizerState : public std::list<SynthesizerGroup> {
|
class SynthesizerState : public std::list<SynthesizerGroup> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
SynthesizerState(std::initializer_list<SynthesizerGroup> l) {
|
||||||
|
insert(end(), l.begin(), l.end());
|
||||||
|
}
|
||||||
SynthesizerState() : std::list<SynthesizerGroup>() {}
|
SynthesizerState() : std::list<SynthesizerGroup>() {}
|
||||||
|
|
||||||
void write(Xml&) const;
|
void write(Xml&) const;
|
||||||
void read(XmlReader&);
|
void read(XmlReader&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2171,25 +2171,12 @@ MasterSynthesizer* synthesizerFactory()
|
||||||
|
|
||||||
FluidS::Fluid* fluid = new FluidS::Fluid();
|
FluidS::Fluid* fluid = new FluidS::Fluid();
|
||||||
ms->registerSynthesizer(fluid);
|
ms->registerSynthesizer(fluid);
|
||||||
if (!preferences.defaultSf.isEmpty()) {
|
|
||||||
QStringList sfl;
|
|
||||||
sfl.append(preferences.defaultSf);
|
|
||||||
fluid->loadSoundFonts(sfl);
|
|
||||||
fluid->gui()->synthesizerChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef AEOLUS
|
#ifdef AEOLUS
|
||||||
ms->registerSynthesizer(new Aeolus());
|
ms->registerSynthesizer(new Aeolus());
|
||||||
#endif
|
#endif
|
||||||
#ifdef ZERBERUS
|
#ifdef ZERBERUS
|
||||||
Zerberus* zerberus = new Zerberus();
|
ms->registerSynthesizer(new Zerberus);
|
||||||
ms->registerSynthesizer(zerberus);
|
|
||||||
if (!preferences.defaultSfz.isEmpty()) {
|
|
||||||
QStringList sfz;
|
|
||||||
sfz.append(preferences.defaultSfz);
|
|
||||||
zerberus->loadSoundFonts(sfz);
|
|
||||||
zerberus->gui()->synthesizerChanged();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
ms->registerEffect(0, new NoEffect);
|
ms->registerEffect(0, new NoEffect);
|
||||||
ms->registerEffect(0, new ZitaReverb);
|
ms->registerEffect(0, new ZitaReverb);
|
||||||
|
@ -2450,6 +2437,7 @@ int main(int argc, char* av[])
|
||||||
synti = synthesizerFactory();
|
synti = synthesizerFactory();
|
||||||
MScore::sampleRate = driver->sampleRate();
|
MScore::sampleRate = driver->sampleRate();
|
||||||
synti->setSampleRate(MScore::sampleRate);
|
synti->setSampleRate(MScore::sampleRate);
|
||||||
|
synti->init();
|
||||||
|
|
||||||
seq->setDriver(driver);
|
seq->setDriver(driver);
|
||||||
seq->setMasterSynthesizer(synti);
|
seq->setMasterSynthesizer(synti);
|
||||||
|
|
|
@ -218,9 +218,6 @@ void Preferences::init()
|
||||||
sfPath = QDir(QString("%1%2;%3/%4").arg(mscoreGlobalShare).arg("sound").arg(wd).arg(QCoreApplication::translate("soundfonts_directory", "Soundfonts"))).absolutePath();
|
sfPath = QDir(QString("%1%2;%3/%4").arg(mscoreGlobalShare).arg("sound").arg(wd).arg(QCoreApplication::translate("soundfonts_directory", "Soundfonts"))).absolutePath();
|
||||||
sfzPath = QDir(QString("%1/%2").arg(wd).arg(QCoreApplication::translate("sfz_files_directory", "SfzFiles"))).absolutePath();
|
sfzPath = QDir(QString("%1/%2").arg(wd).arg(QCoreApplication::translate("sfz_files_directory", "SfzFiles"))).absolutePath();
|
||||||
|
|
||||||
defaultSf = "fluid.sf3";
|
|
||||||
defaultSfz = "";
|
|
||||||
|
|
||||||
nudgeStep10 = 1.0; // Ctrl + cursor key (default 1.0)
|
nudgeStep10 = 1.0; // Ctrl + cursor key (default 1.0)
|
||||||
nudgeStep50 = 5.0; // Alt + cursor key (default 5.0)
|
nudgeStep50 = 5.0; // Alt + cursor key (default 5.0)
|
||||||
|
|
||||||
|
@ -268,8 +265,6 @@ void Preferences::write()
|
||||||
s.setValue("enableMidiInput", enableMidiInput);
|
s.setValue("enableMidiInput", enableMidiInput);
|
||||||
s.setValue("playNotes", playNotes);
|
s.setValue("playNotes", playNotes);
|
||||||
|
|
||||||
s.setValue("defaultSf", defaultSf);
|
|
||||||
s.setValue("defaultSfz", defaultSfz);
|
|
||||||
s.setValue("lPort", lPort);
|
s.setValue("lPort", lPort);
|
||||||
s.setValue("rPort", rPort);
|
s.setValue("rPort", rPort);
|
||||||
s.setValue("showNavigator", showNavigator);
|
s.setValue("showNavigator", showNavigator);
|
||||||
|
@ -430,8 +425,6 @@ void Preferences::read()
|
||||||
lPort = s.value("lPort", lPort).toString();
|
lPort = s.value("lPort", lPort).toString();
|
||||||
rPort = s.value("rPort", rPort).toString();
|
rPort = s.value("rPort", rPort).toString();
|
||||||
|
|
||||||
defaultSf = s.value("defaultSf", defaultSf).toString();
|
|
||||||
defaultSfz = s.value("defaultSfz", defaultSfz).toString();
|
|
||||||
showNavigator = s.value("showNavigator", showNavigator).toBool();
|
showNavigator = s.value("showNavigator", showNavigator).toBool();
|
||||||
showStatusBar = s.value("showStatusBar", showStatusBar).toBool();
|
showStatusBar = s.value("showStatusBar", showStatusBar).toBool();
|
||||||
showPlayPanel = s.value("showPlayPanel", showPlayPanel).toBool();
|
showPlayPanel = s.value("showPlayPanel", showPlayPanel).toBool();
|
||||||
|
@ -856,18 +849,6 @@ void PreferenceDialog::updateValues()
|
||||||
jackLPort->setEnabled(false);
|
jackLPort->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QFileInfoList l = FluidS::Fluid::sfFiles();
|
|
||||||
defaultSf->addItem("", "");
|
|
||||||
foreach (const QFileInfo& fi, l)
|
|
||||||
defaultSf->addItem(fi.fileName(), fi.fileName());
|
|
||||||
defaultSf->setCurrentIndex(defaultSf->findData(prefs.defaultSf));
|
|
||||||
|
|
||||||
l = Zerberus::sfzFiles();
|
|
||||||
defaultSfz->addItem("", "");
|
|
||||||
foreach (const QFileInfo& fi, l)
|
|
||||||
defaultSfz->addItem(fi.fileName(), fi.fileName());
|
|
||||||
defaultSfz->setCurrentIndex(defaultSfz->findData(prefs.defaultSfz));
|
|
||||||
|
|
||||||
navigatorShow->setChecked(prefs.showNavigator);
|
navigatorShow->setChecked(prefs.showNavigator);
|
||||||
playPanelShow->setChecked(prefs.showPlayPanel);
|
playPanelShow->setChecked(prefs.showPlayPanel);
|
||||||
webPanelShow->setChecked(prefs.showWebPanel);
|
webPanelShow->setChecked(prefs.showWebPanel);
|
||||||
|
@ -1299,8 +1280,6 @@ void PreferenceDialog::apply()
|
||||||
prefs.lPort = jackLPort->currentText();
|
prefs.lPort = jackLPort->currentText();
|
||||||
prefs.rPort = jackRPort->currentText();
|
prefs.rPort = jackRPort->currentText();
|
||||||
}
|
}
|
||||||
prefs.defaultSf = defaultSf->itemData(defaultSf->currentIndex()).toString();
|
|
||||||
prefs.defaultSfz = defaultSfz->itemData(defaultSfz->currentIndex()).toString();
|
|
||||||
prefs.showNavigator = navigatorShow->isChecked();
|
prefs.showNavigator = navigatorShow->isChecked();
|
||||||
prefs.showPlayPanel = playPanelShow->isChecked();
|
prefs.showPlayPanel = playPanelShow->isChecked();
|
||||||
prefs.showWebPanel = webPanelShow->isChecked();
|
prefs.showWebPanel = webPanelShow->isChecked();
|
||||||
|
|
|
@ -168,8 +168,6 @@ struct Preferences {
|
||||||
|
|
||||||
QString sfPath;
|
QString sfPath;
|
||||||
QString sfzPath;
|
QString sfzPath;
|
||||||
QString defaultSf;
|
|
||||||
QString defaultSfz;
|
|
||||||
|
|
||||||
double nudgeStep10; // Ctrl + cursor key (default 1.0)
|
double nudgeStep10; // Ctrl + cursor key (default 1.0)
|
||||||
double nudgeStep50; // Alt + cursor key (default 5.0)
|
double nudgeStep50; // Alt + cursor key (default 5.0)
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>845</width>
|
<width>873</width>
|
||||||
<height>624</height>
|
<height>641</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab">
|
||||||
<property name="accessibleName">
|
<property name="accessibleName">
|
||||||
|
@ -2087,49 +2087,6 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_14">
|
|
||||||
<property name="title">
|
|
||||||
<string>Default SoundFont</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_23">
|
|
||||||
<property name="text">
|
|
||||||
<string>Soundfont:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="defaultSf">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_29">
|
|
||||||
<property name="text">
|
|
||||||
<string>SFZ:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="defaultSfz">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="portmidiDriverInput">
|
<widget class="QGroupBox" name="portmidiDriverInput">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|
|
@ -1,21 +1,13 @@
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// MuseScore
|
// MuseScore
|
||||||
// Linux Music Score Editor
|
// Music Composition & Notation
|
||||||
// $Id: select.cpp 2054 2009-08-28 16:15:01Z wschweer $
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2010 Werner Schweer and others
|
// Copyright (C) 2002-2013 Werner Schweer
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License version 2.
|
// it under the terms of the GNU General Public License version 2
|
||||||
//
|
// as published by the Free Software Foundation and appearing in
|
||||||
// This program is distributed in the hope that it will be useful,
|
// the file LICENCE.GPL
|
||||||
// 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 "synthcontrol.h"
|
#include "synthcontrol.h"
|
||||||
|
@ -31,6 +23,7 @@
|
||||||
#include "icons.h"
|
#include "icons.h"
|
||||||
#include "libmscore/score.h"
|
#include "libmscore/score.h"
|
||||||
#include "libmscore/mscore.h"
|
#include "libmscore/mscore.h"
|
||||||
|
#include "libmscore/xml.h"
|
||||||
#include "libmscore/undo.h"
|
#include "libmscore/undo.h"
|
||||||
#include "effects/effectgui.h"
|
#include "effects/effectgui.h"
|
||||||
|
|
||||||
|
@ -52,8 +45,10 @@ SynthControl::SynthControl(QWidget* parent)
|
||||||
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (Synthesizer* s : synti->synthesizer())
|
for (Synthesizer* s : synti->synthesizer()) {
|
||||||
tabWidget->insertTab(idx++, s->gui(), tr(s->name()));
|
tabWidget->insertTab(idx++, s->gui(), tr(s->name()));
|
||||||
|
connect(s->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
||||||
|
}
|
||||||
|
|
||||||
// effectA combo box
|
// effectA combo box
|
||||||
// effectStackA widget stack
|
// effectStackA widget stack
|
||||||
|
@ -62,12 +57,14 @@ SynthControl::SynthControl(QWidget* parent)
|
||||||
for (Effect* e : synti->effectList(0)) {
|
for (Effect* e : synti->effectList(0)) {
|
||||||
effectA->addItem(tr(e->name()));
|
effectA->addItem(tr(e->name()));
|
||||||
effectStackA->addWidget(e->gui());
|
effectStackA->addWidget(e->gui());
|
||||||
|
connect(e->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
effectB->clear();
|
effectB->clear();
|
||||||
for (Effect* e : synti->effectList(1)) {
|
for (Effect* e : synti->effectList(1)) {
|
||||||
effectB->addItem(tr(e->name()));
|
effectB->addItem(tr(e->name()));
|
||||||
effectStackB->addWidget(e->gui());
|
effectStackB->addWidget(e->gui());
|
||||||
|
connect(e->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!useFactorySettings) {
|
if (!useFactorySettings) {
|
||||||
|
@ -81,13 +78,20 @@ SynthControl::SynthControl(QWidget* parent)
|
||||||
updateSyntiValues();
|
updateSyntiValues();
|
||||||
|
|
||||||
tabWidget->setCurrentIndex(0);
|
tabWidget->setCurrentIndex(0);
|
||||||
|
storeButton->setEnabled(false);
|
||||||
|
recallButton->setEnabled(false);
|
||||||
|
changeTuningButton->setEnabled(false);
|
||||||
|
|
||||||
connect(effectA, SIGNAL(currentIndexChanged(int)), SLOT(effectAChanged(int)));
|
connect(effectA, SIGNAL(currentIndexChanged(int)), SLOT(effectAChanged(int)));
|
||||||
connect(effectB, SIGNAL(currentIndexChanged(int)), SLOT(effectBChanged(int)));
|
connect(effectB, SIGNAL(currentIndexChanged(int)), SLOT(effectBChanged(int)));
|
||||||
connect(gain, SIGNAL(valueChanged(double,int)), SLOT(gainChanged(double,int)));
|
connect(gain, SIGNAL(valueChanged(double,int)), SLOT(gainChanged(double,int)));
|
||||||
connect(masterTuning, SIGNAL(valueChanged(double)), SLOT(masterTuningChanged(double)));
|
connect(masterTuning, SIGNAL(valueChanged(double)), SLOT(masterTuningChanged(double)));
|
||||||
|
connect(changeTuningButton, SIGNAL(clicked()), SLOT(changeMasterTuning()));
|
||||||
connect(loadButton, SIGNAL(clicked()), SLOT(loadButtonClicked()));
|
connect(loadButton, SIGNAL(clicked()), SLOT(loadButtonClicked()));
|
||||||
connect(saveButton, SIGNAL(clicked()), SLOT(saveButtonClicked()));
|
connect(saveButton, SIGNAL(clicked()), SLOT(saveButtonClicked()));
|
||||||
|
connect(storeButton, SIGNAL(clicked()), SLOT(storeButtonClicked()));
|
||||||
|
connect(recallButton, SIGNAL(clicked()), SLOT(recallButtonClicked()));
|
||||||
|
connect(gain, SIGNAL(valueChanged(double,int)), SLOT(setDirty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -175,7 +179,18 @@ void SynthControl::gainChanged(double val, int)
|
||||||
|
|
||||||
void SynthControl::masterTuningChanged(double val)
|
void SynthControl::masterTuningChanged(double val)
|
||||||
{
|
{
|
||||||
synti->setMasterTuning(val);
|
changeTuningButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// changeMasterTuning
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
void SynthControl::changeMasterTuning()
|
||||||
|
{
|
||||||
|
synti->setMasterTuning(masterTuning->value());
|
||||||
|
changeTuningButton->setEnabled(false);
|
||||||
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -225,8 +240,15 @@ void SynthControl::effectBChanged(int idx)
|
||||||
|
|
||||||
void SynthControl::loadButtonClicked()
|
void SynthControl::loadButtonClicked()
|
||||||
{
|
{
|
||||||
|
if (!_score)
|
||||||
|
return;
|
||||||
synti->setState(_score->synthesizerState());
|
synti->setState(_score->synthesizerState());
|
||||||
updateSyntiValues();
|
updateSyntiValues();
|
||||||
|
loadButton->setEnabled(false);
|
||||||
|
saveButton->setEnabled(false);
|
||||||
|
storeButton->setEnabled(true);
|
||||||
|
recallButton->setEnabled(true);
|
||||||
|
changeTuningButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -236,12 +258,79 @@ void SynthControl::loadButtonClicked()
|
||||||
|
|
||||||
void SynthControl::saveButtonClicked()
|
void SynthControl::saveButtonClicked()
|
||||||
{
|
{
|
||||||
if (_score && synti) {
|
if (!_score)
|
||||||
|
return;
|
||||||
_score->startCmd();
|
_score->startCmd();
|
||||||
_score->undo()->push(new ChangeSynthesizerState(_score, synti->state()));
|
_score->undo()->push(new ChangeSynthesizerState(_score, synti->state()));
|
||||||
_score->endCmd();
|
_score->endCmd();
|
||||||
mscore->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);
|
||||||
|
updateSyntiValues();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Xml xml(&f);
|
||||||
|
xml.header();
|
||||||
|
synti->state().write(xml);
|
||||||
|
|
||||||
|
storeButton->setEnabled(false);
|
||||||
|
recallButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -264,3 +353,15 @@ void SynthControl::updateSyntiValues()
|
||||||
effectStackB->setCurrentIndex(idx);
|
effectStackB->setCurrentIndex(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// setDirty
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
void SynthControl::setDirty()
|
||||||
|
{
|
||||||
|
loadButton->setEnabled(true);
|
||||||
|
saveButton->setEnabled(true);
|
||||||
|
storeButton->setEnabled(true);
|
||||||
|
recallButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,14 @@ class SynthControl : public QWidget, Ui::SynthControl {
|
||||||
private slots:
|
private slots:
|
||||||
void gainChanged(double, int);
|
void gainChanged(double, int);
|
||||||
void masterTuningChanged(double);
|
void masterTuningChanged(double);
|
||||||
|
void changeMasterTuning();
|
||||||
void effectAChanged(int);
|
void effectAChanged(int);
|
||||||
void effectBChanged(int);
|
void effectBChanged(int);
|
||||||
void loadButtonClicked();
|
void loadButtonClicked();
|
||||||
void saveButtonClicked();
|
void saveButtonClicked();
|
||||||
|
void storeButtonClicked();
|
||||||
|
void recallButtonClicked();
|
||||||
|
void setDirty();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void closed(bool);
|
void closed(bool);
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>594</width>
|
<width>616</width>
|
||||||
<height>269</height>
|
<height>281</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -16,13 +16,20 @@
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="0" column="1">
|
<item row="0" column="3">
|
||||||
<widget class="QPushButton" name="loadButton">
|
<widget class="QPushButton" name="storeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Store</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QPushButton" name="saveButton">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Load from Score</string>
|
<string>Save to Score</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load</string>
|
<string>Save</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -39,39 +46,20 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="3">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_39">
|
<widget class="QPushButton" name="loadButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Load from Score</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Master Tuning</string>
|
<string>Load</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="4">
|
<item row="0" column="4">
|
||||||
<widget class="QDoubleSpinBox" name="masterTuning">
|
<widget class="QPushButton" name="recallButton">
|
||||||
<property name="suffix">
|
|
||||||
<string extracomment="Frequency Herz">Hz</string>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>300.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>600.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>440.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QPushButton" name="saveButton">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Save to Score</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Save</string>
|
<string>Recall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -110,7 +98,7 @@
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="masterEffectsTab">
|
<widget class="QWidget" name="masterEffectsTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
@ -179,6 +167,72 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tuning</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_39">
|
||||||
|
<property name="text">
|
||||||
|
<string>Master Tuning</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="masterTuning">
|
||||||
|
<property name="suffix">
|
||||||
|
<string extracomment="Frequency Herz">Hz</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>300.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>600.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>440.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>275</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>127</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QPushButton" name="changeTuningButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Change Tuning</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -18,6 +18,31 @@
|
||||||
#include "libmscore/xml.h"
|
#include "libmscore/xml.h"
|
||||||
#include "midipatch.h"
|
#include "midipatch.h"
|
||||||
|
|
||||||
|
extern QString dataPath;
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// default buildin SynthesizerState
|
||||||
|
// used if synthesizer.xml does not exist or is not
|
||||||
|
// readable
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
static SynthesizerState defaultState = {
|
||||||
|
{ "master", {
|
||||||
|
{ 0, "Zita1" },
|
||||||
|
{ 2, "1.0" },
|
||||||
|
{ 3, "440" }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ "Fluid", {
|
||||||
|
{ 0, "FluidR3.SF2" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// { "Zerberus", {
|
||||||
|
// { 0, "SalamanderGrandPiano.sfz" },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// MasterSynthesizer
|
// MasterSynthesizer
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -29,10 +54,35 @@ MasterSynthesizer::MasterSynthesizer()
|
||||||
lock2 = true;
|
lock2 = true;
|
||||||
_synthesizer.reserve(4);
|
_synthesizer.reserve(4);
|
||||||
_gain = 1.0;
|
_gain = 1.0;
|
||||||
|
_masterTuning = 440.0;
|
||||||
for (int i = 0; i < MAX_EFFECTS; ++i)
|
for (int i = 0; i < MAX_EFFECTS; ++i)
|
||||||
_effect[i] = 0;
|
_effect[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// init
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
void MasterSynthesizer::init()
|
||||||
|
{
|
||||||
|
SynthesizerState state;
|
||||||
|
QString s(dataPath + "/synthesizer.xml");
|
||||||
|
QFile f(s);
|
||||||
|
if (!f.open(QIODevice::ReadOnly)) {
|
||||||
|
qDebug("cannot read synthesizer settings <%s>", qPrintable(s));
|
||||||
|
// setState(defaultState);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XmlReader e(&f);
|
||||||
|
while (e.readNextStartElement()) {
|
||||||
|
if (e.name() == "Synthesizer")
|
||||||
|
state.read(e);
|
||||||
|
else
|
||||||
|
e.unknown();
|
||||||
|
}
|
||||||
|
setState(state);
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// MasterSynthesizer
|
// MasterSynthesizer
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -286,6 +336,9 @@ void MasterSynthesizer::setState(const SynthesizerState& ss)
|
||||||
setGain(f);
|
setGain(f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
setMasterTuning(v.data.toDouble());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,9 +366,10 @@ SynthesizerState MasterSynthesizer::state() const
|
||||||
SynthesizerState ss;
|
SynthesizerState ss;
|
||||||
SynthesizerGroup g;
|
SynthesizerGroup g;
|
||||||
g.setName("master");
|
g.setName("master");
|
||||||
g.push_back(IdValue(0, QString("%1").arg(_effect[0] ? _effect[0]->name() : "none")));
|
g.push_back(IdValue(0, QString("%1").arg(_effect[0] ? _effect[0]->name() : "NoEffect")));
|
||||||
g.push_back(IdValue(1, QString("%1").arg(_effect[1] ? _effect[1]->name() : "none")));
|
g.push_back(IdValue(1, QString("%1").arg(_effect[1] ? _effect[1]->name() : "NoEffect")));
|
||||||
g.push_back(IdValue(2, QString("%1").arg(gain())));
|
g.push_back(IdValue(2, QString("%1").arg(gain())));
|
||||||
|
g.push_back(IdValue(3, QString("%1").arg(masterTuning())));
|
||||||
ss.push_back(g);
|
ss.push_back(g);
|
||||||
for (Synthesizer* s : _synthesizer)
|
for (Synthesizer* s : _synthesizer)
|
||||||
ss.push_back(s->state());
|
ss.push_back(s->state());
|
||||||
|
@ -338,3 +392,14 @@ void MasterSynthesizer::setGain(float f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// setMasterTuning
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
void MasterSynthesizer::setMasterTuning(double val)
|
||||||
|
{
|
||||||
|
_masterTuning = val;
|
||||||
|
for (Synthesizer* s : _synthesizer)
|
||||||
|
s->setMasterTuning(_masterTuning);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ class MasterSynthesizer : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
float _gain;
|
float _gain;
|
||||||
|
double _masterTuning;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int MAX_BUFFERSIZE = 4096;
|
static const int MAX_BUFFERSIZE = 4096;
|
||||||
|
@ -48,7 +49,6 @@ class MasterSynthesizer : public QObject {
|
||||||
|
|
||||||
float effect1Buffer[MAX_BUFFERSIZE];
|
float effect1Buffer[MAX_BUFFERSIZE];
|
||||||
float effect2Buffer[MAX_BUFFERSIZE];
|
float effect2Buffer[MAX_BUFFERSIZE];
|
||||||
void init();
|
|
||||||
int indexOfEffect(int ab, const QString& name);
|
int indexOfEffect(int ab, const QString& name);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -64,14 +64,16 @@ class MasterSynthesizer : public QObject {
|
||||||
~MasterSynthesizer();
|
~MasterSynthesizer();
|
||||||
void registerSynthesizer(Synthesizer*);
|
void registerSynthesizer(Synthesizer*);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
float sampleRate() { return _sampleRate; }
|
float sampleRate() { return _sampleRate; }
|
||||||
void setSampleRate(float val);
|
void setSampleRate(float val);
|
||||||
|
|
||||||
void process(unsigned, float*);
|
void process(unsigned, float*);
|
||||||
void play(const Event&, unsigned);
|
void play(const Event&, unsigned);
|
||||||
|
|
||||||
void setMasterTuning(double) {}
|
void setMasterTuning(double val);
|
||||||
double masterTuning() const { return 440.0; }
|
double masterTuning() const { return _masterTuning; }
|
||||||
|
|
||||||
int index(const QString&) const;
|
int index(const QString&) const;
|
||||||
QString name(unsigned) const;
|
QString name(unsigned) const;
|
||||||
|
|
|
@ -25,6 +25,7 @@ class SynthesizerGui : public QWidget {
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sfChanged();
|
void sfChanged();
|
||||||
|
void valueChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void synthesizerChanged() {}
|
virtual void synthesizerChanged() {}
|
||||||
|
|
|
@ -115,7 +115,7 @@ void Voice::start(Channel* c, int key, int v, const Zone* z)
|
||||||
|
|
||||||
phase.set(0);
|
phase.set(0);
|
||||||
double sr = double(s->sampleRate()) / 44100.0;
|
double sr = double(s->sampleRate()) / 44100.0;
|
||||||
phaseIncr.set(Zerberus::ct2hz(key * 100 + z->tune) * sr/Zerberus::ct2hz(z->keyBase * 100.0));
|
phaseIncr.set(_zerberus->ct2hz(key * 100 + z->tune) * sr/_zerberus->ct2hz(z->keyBase * 100.0));
|
||||||
|
|
||||||
fres = 13500.0;
|
fres = 13500.0;
|
||||||
last_fres = -1.0;
|
last_fres = -1.0;
|
||||||
|
@ -217,7 +217,7 @@ void Voice::process(int frames, float* p)
|
||||||
float modlfo_to_fc = 0.0;
|
float modlfo_to_fc = 0.0;
|
||||||
float modenv_to_fc = 0.0;
|
float modenv_to_fc = 0.0;
|
||||||
|
|
||||||
float _fres = Zerberus::ct2hz(fres
|
float _fres = _zerberus->ct2hz(fres
|
||||||
+ modlfo_val * modlfo_to_fc
|
+ modlfo_val * modlfo_to_fc
|
||||||
+ modenv_val * modenv_to_fc);
|
+ modenv_val * modenv_to_fc);
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ class Zerberus : public QObject, public Synthesizer {
|
||||||
static bool initialized;
|
static bool initialized;
|
||||||
static std::list<ZInstrument*> globalInstruments;
|
static std::list<ZInstrument*> globalInstruments;
|
||||||
|
|
||||||
|
double _masterTuning = 440.0;
|
||||||
std::atomic<bool> busy;
|
std::atomic<bool> busy;
|
||||||
|
|
||||||
std::list<ZInstrument*> instruments;
|
std::list<ZInstrument*> instruments;
|
||||||
|
@ -102,7 +103,10 @@ class Zerberus : public QObject, public Synthesizer {
|
||||||
Channel* channel(int n) { return _channel[n]; }
|
Channel* channel(int n) { return _channel[n]; }
|
||||||
int loadProgress() { return _loadProgress; }
|
int loadProgress() { return _loadProgress; }
|
||||||
|
|
||||||
static double ct2hz(float c) { return 8.176 * pow(2.0, (double)c / 1200.0); }
|
virtual void setMasterTuning(double val) { _masterTuning = val; }
|
||||||
|
virtual double masterTuning() const { return _masterTuning; }
|
||||||
|
|
||||||
|
double ct2hz(double c) { return pow(2.0, (c-6900.0) / 1200.0) * _masterTuning; }
|
||||||
|
|
||||||
virtual const char* name() const;
|
virtual const char* name() const;
|
||||||
virtual const QList<MidiPatch*>& getPatchInfo() const;
|
virtual const QList<MidiPatch*>& getPatchInfo() const;
|
||||||
|
|
|
@ -188,6 +188,7 @@ void ZerberusGui::onSoundFontLoaded()
|
||||||
else {
|
else {
|
||||||
files->insertItem(0, _loadedSfName);
|
files->insertItem(0, _loadedSfName);
|
||||||
}
|
}
|
||||||
|
emit valueChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -201,6 +202,7 @@ void ZerberusGui::removeClicked()
|
||||||
QString s(files->item(row)->text());
|
QString s(files->item(row)->text());
|
||||||
zerberus()->removeSoundFont(s);
|
zerberus()->removeSoundFont(s);
|
||||||
delete files->takeItem(row);
|
delete files->takeItem(row);
|
||||||
|
emit valueChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue