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)
|
||||
{
|
||||
_effect->setValue(msg, val);
|
||||
if (_effect->value(msg) != val) {
|
||||
_effect->setValue(msg, val);
|
||||
emit valueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -23,6 +23,9 @@ class EffectGui : public QDeclarativeView {
|
|||
Q_OBJECT
|
||||
Effect* _effect;
|
||||
|
||||
signals:
|
||||
void valueChanged();
|
||||
|
||||
public slots:
|
||||
void valueChanged(const QString& name, qreal);
|
||||
|
||||
|
|
|
@ -199,6 +199,7 @@ void FluidGui::soundFontAddClicked()
|
|||
else {
|
||||
soundFonts->insertItem(0, sfName);
|
||||
emit sfChanged();
|
||||
emit valueChanged();
|
||||
}
|
||||
}
|
||||
updateUpDownButtons();
|
||||
|
|
|
@ -40,7 +40,9 @@ class SynthesizerGroup : public std::list<IdValue> {
|
|||
public:
|
||||
const QString& name() const { return _name; }
|
||||
void setName(const QString& s) { _name = s; }
|
||||
|
||||
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> {
|
||||
|
||||
public:
|
||||
SynthesizerState(std::initializer_list<SynthesizerGroup> l) {
|
||||
insert(end(), l.begin(), l.end());
|
||||
}
|
||||
SynthesizerState() : std::list<SynthesizerGroup>() {}
|
||||
|
||||
void write(Xml&) const;
|
||||
void read(XmlReader&);
|
||||
};
|
||||
|
|
|
@ -2171,25 +2171,12 @@ MasterSynthesizer* synthesizerFactory()
|
|||
|
||||
FluidS::Fluid* fluid = new FluidS::Fluid();
|
||||
ms->registerSynthesizer(fluid);
|
||||
if (!preferences.defaultSf.isEmpty()) {
|
||||
QStringList sfl;
|
||||
sfl.append(preferences.defaultSf);
|
||||
fluid->loadSoundFonts(sfl);
|
||||
fluid->gui()->synthesizerChanged();
|
||||
}
|
||||
|
||||
#ifdef AEOLUS
|
||||
ms->registerSynthesizer(new Aeolus());
|
||||
#endif
|
||||
#ifdef ZERBERUS
|
||||
Zerberus* zerberus = new Zerberus();
|
||||
ms->registerSynthesizer(zerberus);
|
||||
if (!preferences.defaultSfz.isEmpty()) {
|
||||
QStringList sfz;
|
||||
sfz.append(preferences.defaultSfz);
|
||||
zerberus->loadSoundFonts(sfz);
|
||||
zerberus->gui()->synthesizerChanged();
|
||||
}
|
||||
ms->registerSynthesizer(new Zerberus);
|
||||
#endif
|
||||
ms->registerEffect(0, new NoEffect);
|
||||
ms->registerEffect(0, new ZitaReverb);
|
||||
|
@ -2450,6 +2437,7 @@ int main(int argc, char* av[])
|
|||
synti = synthesizerFactory();
|
||||
MScore::sampleRate = driver->sampleRate();
|
||||
synti->setSampleRate(MScore::sampleRate);
|
||||
synti->init();
|
||||
|
||||
seq->setDriver(driver);
|
||||
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();
|
||||
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)
|
||||
nudgeStep50 = 5.0; // Alt + cursor key (default 5.0)
|
||||
|
||||
|
@ -268,8 +265,6 @@ void Preferences::write()
|
|||
s.setValue("enableMidiInput", enableMidiInput);
|
||||
s.setValue("playNotes", playNotes);
|
||||
|
||||
s.setValue("defaultSf", defaultSf);
|
||||
s.setValue("defaultSfz", defaultSfz);
|
||||
s.setValue("lPort", lPort);
|
||||
s.setValue("rPort", rPort);
|
||||
s.setValue("showNavigator", showNavigator);
|
||||
|
@ -430,8 +425,6 @@ void Preferences::read()
|
|||
lPort = s.value("lPort", lPort).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();
|
||||
showStatusBar = s.value("showStatusBar", showStatusBar).toBool();
|
||||
showPlayPanel = s.value("showPlayPanel", showPlayPanel).toBool();
|
||||
|
@ -856,18 +849,6 @@ void PreferenceDialog::updateValues()
|
|||
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);
|
||||
playPanelShow->setChecked(prefs.showPlayPanel);
|
||||
webPanelShow->setChecked(prefs.showWebPanel);
|
||||
|
@ -1299,8 +1280,6 @@ void PreferenceDialog::apply()
|
|||
prefs.lPort = jackLPort->currentText();
|
||||
prefs.rPort = jackRPort->currentText();
|
||||
}
|
||||
prefs.defaultSf = defaultSf->itemData(defaultSf->currentIndex()).toString();
|
||||
prefs.defaultSfz = defaultSfz->itemData(defaultSfz->currentIndex()).toString();
|
||||
prefs.showNavigator = navigatorShow->isChecked();
|
||||
prefs.showPlayPanel = playPanelShow->isChecked();
|
||||
prefs.showWebPanel = webPanelShow->isChecked();
|
||||
|
|
|
@ -168,8 +168,6 @@ struct Preferences {
|
|||
|
||||
QString sfPath;
|
||||
QString sfzPath;
|
||||
QString defaultSf;
|
||||
QString defaultSfz;
|
||||
|
||||
double nudgeStep10; // Ctrl + cursor key (default 1.0)
|
||||
double nudgeStep50; // Alt + cursor key (default 5.0)
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>845</width>
|
||||
<height>624</height>
|
||||
<width>873</width>
|
||||
<height>641</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -75,7 +75,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>5</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<property name="accessibleName">
|
||||
|
@ -2087,49 +2087,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="QGroupBox" name="portmidiDriverInput">
|
||||
<property name="sizePolicy">
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Linux Music Score Editor
|
||||
// $Id: select.cpp 2054 2009-08-28 16:15:01Z wschweer $
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
// 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
|
||||
//=============================================================================
|
||||
|
||||
#include "synthcontrol.h"
|
||||
|
@ -31,6 +23,7 @@
|
|||
#include "icons.h"
|
||||
#include "libmscore/score.h"
|
||||
#include "libmscore/mscore.h"
|
||||
#include "libmscore/xml.h"
|
||||
#include "libmscore/undo.h"
|
||||
#include "effects/effectgui.h"
|
||||
|
||||
|
@ -52,8 +45,10 @@ SynthControl::SynthControl(QWidget* parent)
|
|||
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
int idx = 0;
|
||||
for (Synthesizer* s : synti->synthesizer())
|
||||
for (Synthesizer* s : synti->synthesizer()) {
|
||||
tabWidget->insertTab(idx++, s->gui(), tr(s->name()));
|
||||
connect(s->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
||||
}
|
||||
|
||||
// effectA combo box
|
||||
// effectStackA widget stack
|
||||
|
@ -62,12 +57,14 @@ SynthControl::SynthControl(QWidget* parent)
|
|||
for (Effect* e : synti->effectList(0)) {
|
||||
effectA->addItem(tr(e->name()));
|
||||
effectStackA->addWidget(e->gui());
|
||||
connect(e->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
||||
}
|
||||
|
||||
effectB->clear();
|
||||
for (Effect* e : synti->effectList(1)) {
|
||||
effectB->addItem(tr(e->name()));
|
||||
effectStackB->addWidget(e->gui());
|
||||
connect(e->gui(), SIGNAL(valueChanged()), SLOT(setDirty()));
|
||||
}
|
||||
|
||||
if (!useFactorySettings) {
|
||||
|
@ -81,13 +78,20 @@ SynthControl::SynthControl(QWidget* parent)
|
|||
updateSyntiValues();
|
||||
|
||||
tabWidget->setCurrentIndex(0);
|
||||
storeButton->setEnabled(false);
|
||||
recallButton->setEnabled(false);
|
||||
changeTuningButton->setEnabled(false);
|
||||
|
||||
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)));
|
||||
connect(changeTuningButton, SIGNAL(clicked()), SLOT(changeMasterTuning()));
|
||||
connect(loadButton, SIGNAL(clicked()), SLOT(loadButtonClicked()));
|
||||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
if (!_score)
|
||||
return;
|
||||
synti->setState(_score->synthesizerState());
|
||||
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()
|
||||
{
|
||||
if (_score && synti) {
|
||||
_score->startCmd();
|
||||
_score->undo()->push(new ChangeSynthesizerState(_score, synti->state()));
|
||||
_score->endCmd();
|
||||
mscore->endCmd();
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// 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:
|
||||
void gainChanged(double, int);
|
||||
void masterTuningChanged(double);
|
||||
void changeMasterTuning();
|
||||
void effectAChanged(int);
|
||||
void effectBChanged(int);
|
||||
void loadButtonClicked();
|
||||
void saveButtonClicked();
|
||||
void storeButtonClicked();
|
||||
void recallButtonClicked();
|
||||
void setDirty();
|
||||
|
||||
signals:
|
||||
void closed(bool);
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>594</width>
|
||||
<height>269</height>
|
||||
<width>616</width>
|
||||
<height>281</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -16,13 +16,20 @@
|
|||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="loadButton">
|
||||
<item row="0" column="3">
|
||||
<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">
|
||||
<string>Load from Score</string>
|
||||
<string>Save to Score</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -39,39 +46,20 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_39">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="loadButton">
|
||||
<property name="toolTip">
|
||||
<string>Load from Score</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Master Tuning</string>
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<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="0">
|
||||
<widget class="QPushButton" name="saveButton">
|
||||
<property name="toolTip">
|
||||
<string>Save to Score</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="recallButton">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
<string>Recall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -110,7 +98,7 @@
|
|||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="masterEffectsTab">
|
||||
<attribute name="title">
|
||||
|
@ -179,6 +167,72 @@
|
|||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -18,6 +18,31 @@
|
|||
#include "libmscore/xml.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
|
||||
//---------------------------------------------------------
|
||||
|
@ -29,10 +54,35 @@ MasterSynthesizer::MasterSynthesizer()
|
|||
lock2 = true;
|
||||
_synthesizer.reserve(4);
|
||||
_gain = 1.0;
|
||||
_masterTuning = 440.0;
|
||||
for (int i = 0; i < MAX_EFFECTS; ++i)
|
||||
_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
|
||||
//---------------------------------------------------------
|
||||
|
@ -286,6 +336,9 @@ void MasterSynthesizer::setState(const SynthesizerState& ss)
|
|||
setGain(f);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
setMasterTuning(v.data.toDouble());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,9 +366,10 @@ SynthesizerState MasterSynthesizer::state() const
|
|||
SynthesizerState ss;
|
||||
SynthesizerGroup g;
|
||||
g.setName("master");
|
||||
g.push_back(IdValue(0, QString("%1").arg(_effect[0] ? _effect[0]->name() : "none")));
|
||||
g.push_back(IdValue(1, QString("%1").arg(_effect[1] ? _effect[1]->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() : "NoEffect")));
|
||||
g.push_back(IdValue(2, QString("%1").arg(gain())));
|
||||
g.push_back(IdValue(3, QString("%1").arg(masterTuning())));
|
||||
ss.push_back(g);
|
||||
for (Synthesizer* s : _synthesizer)
|
||||
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
|
||||
|
||||
float _gain;
|
||||
double _masterTuning;
|
||||
|
||||
public:
|
||||
static const int MAX_BUFFERSIZE = 4096;
|
||||
|
@ -48,7 +49,6 @@ class MasterSynthesizer : public QObject {
|
|||
|
||||
float effect1Buffer[MAX_BUFFERSIZE];
|
||||
float effect2Buffer[MAX_BUFFERSIZE];
|
||||
void init();
|
||||
int indexOfEffect(int ab, const QString& name);
|
||||
|
||||
public slots:
|
||||
|
@ -64,14 +64,16 @@ class MasterSynthesizer : public QObject {
|
|||
~MasterSynthesizer();
|
||||
void registerSynthesizer(Synthesizer*);
|
||||
|
||||
void init();
|
||||
|
||||
float sampleRate() { return _sampleRate; }
|
||||
void setSampleRate(float val);
|
||||
|
||||
void process(unsigned, float*);
|
||||
void play(const Event&, unsigned);
|
||||
|
||||
void setMasterTuning(double) {}
|
||||
double masterTuning() const { return 440.0; }
|
||||
void setMasterTuning(double val);
|
||||
double masterTuning() const { return _masterTuning; }
|
||||
|
||||
int index(const QString&) const;
|
||||
QString name(unsigned) const;
|
||||
|
|
|
@ -25,6 +25,7 @@ class SynthesizerGui : public QWidget {
|
|||
|
||||
signals:
|
||||
void sfChanged();
|
||||
void valueChanged();
|
||||
|
||||
public slots:
|
||||
virtual void synthesizerChanged() {}
|
||||
|
|
|
@ -115,7 +115,7 @@ void Voice::start(Channel* c, int key, int v, const Zone* z)
|
|||
|
||||
phase.set(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;
|
||||
last_fres = -1.0;
|
||||
|
@ -217,7 +217,7 @@ void Voice::process(int frames, float* p)
|
|||
float modlfo_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
|
||||
+ modenv_val * modenv_to_fc);
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ class Zerberus : public QObject, public Synthesizer {
|
|||
static bool initialized;
|
||||
static std::list<ZInstrument*> globalInstruments;
|
||||
|
||||
double _masterTuning = 440.0;
|
||||
std::atomic<bool> busy;
|
||||
|
||||
std::list<ZInstrument*> instruments;
|
||||
|
@ -102,7 +103,10 @@ class Zerberus : public QObject, public Synthesizer {
|
|||
Channel* channel(int n) { return _channel[n]; }
|
||||
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 QList<MidiPatch*>& getPatchInfo() const;
|
||||
|
|
|
@ -188,6 +188,7 @@ void ZerberusGui::onSoundFontLoaded()
|
|||
else {
|
||||
files->insertItem(0, _loadedSfName);
|
||||
}
|
||||
emit valueChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -201,6 +202,7 @@ void ZerberusGui::removeClicked()
|
|||
QString s(files->item(row)->text());
|
||||
zerberus()->removeSoundFont(s);
|
||||
delete files->takeItem(row);
|
||||
emit valueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue