fix #167161 Make Fluid and Zerberus options the same

Make unification for Zerberus and Fluid GUI
Make logic for 'up' and 'down' arrows in Zerberus

Logic of adding SF in fluid are the same as zerberus
Create Progress Bar in Fluid
This commit is contained in:
alexandr 2018-07-04 13:06:47 +02:00
parent cb43b90e5a
commit 923b8dbf7d
10 changed files with 344 additions and 68 deletions

View file

@ -308,6 +308,9 @@ class Fluid : public Synthesizer {
float _masterTuning; // usually 440.0
double _tuning[128]; // the pitch of every key, in cents
int _loadProgress = 0;
bool _loadWasCanceled = false;
QMutex mutex;
void updatePatchList();
@ -343,6 +346,11 @@ class Fluid : public Synthesizer {
virtual void allSoundsOff(int);
virtual void allNotesOff(int);
int loadProgress() { return _loadProgress; }
void setLoadProgress(int val) { _loadProgress = val; }
bool loadWasCanceled() { return _loadWasCanceled; }
void setLoadWasCanceled(bool status) { _loadWasCanceled = status; }
Preset* get_preset(unsigned int sfontnum, unsigned int banknum, unsigned int prognum);
Preset* find_preset(unsigned int banknum, unsigned int prognum);
void modulate_voices(int chan, bool is_cc, int ctrl);

View file

@ -22,10 +22,23 @@ SfListDialog::SfListDialog(QWidget* parent)
setWindowTitle(tr("SoundFont Files"));
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
list = new QListWidget;
list->setSelectionMode(QAbstractItemView::ExtendedSelection);
okButton = new QPushButton;
cancelButton = new QPushButton;
okButton->setText(tr("Load"));
cancelButton->setText(tr("Cancel"));
QVBoxLayout* layout = new QVBoxLayout;
buttonBox = new QDialogButtonBox;
layout->addWidget(list);
layout->addWidget(buttonBox);
buttonBox->addButton(okButton, QDialogButtonBox::AcceptRole);
buttonBox->addButton(cancelButton, QDialogButtonBox::RejectRole);
setLayout(layout);
connect(list, SIGNAL(itemClicked(QListWidgetItem*)), SLOT(itemSelected(QListWidgetItem*)));
connect(okButton, SIGNAL(clicked()), SLOT(okClicked()));
connect(cancelButton, SIGNAL(clicked()), SLOT(cancelClicked()));
}
void SfListDialog::add(const QString& name, const QString& path)
@ -37,15 +50,30 @@ void SfListDialog::add(const QString& name, const QString& path)
}
//---------------------------------------------------------
// itemSelected
// okClicked
//---------------------------------------------------------
void SfListDialog::itemSelected(QListWidgetItem* item)
void SfListDialog::okClicked()
{
_idx = list->row(item);
for (auto item : list->selectedItems()) {
_namePaths.push_back({item->text(), item->data(Qt::UserRole).toString()});
}
accept();
}
//---------------------------------------------------------
// cancelClicked
//---------------------------------------------------------
void SfListDialog::cancelClicked()
{
reject();
}
//---------------------------------------------------------
// name
//---------------------------------------------------------
QString SfListDialog::name()
{
if (_idx == -1)
@ -53,6 +81,10 @@ QString SfListDialog::name()
return list->item(_idx)->text();
}
//---------------------------------------------------------
// path
//---------------------------------------------------------
QString SfListDialog::path()
{
if (_idx == -1)
@ -84,6 +116,13 @@ FluidGui::FluidGui(Synthesizer* s)
connect(soundFontAdd, SIGNAL(clicked()), SLOT(soundFontAddClicked()));
connect(soundFontDelete, SIGNAL(clicked()), SLOT(soundFontDeleteClicked()));
connect(soundFonts, SIGNAL(itemSelectionChanged ()), SLOT(updateUpDownButtons()));
connect(&_futureWatcher, SIGNAL(finished()), this, SLOT(onSoundFontLoaded()));
_progressDialog = new QProgressDialog(tr("Loading..."), tr("Cancel"), 0, 100, 0, Qt::FramelessWindowHint);
_progressDialog->reset(); // required for Qt 5.5, see QTBUG-47042
connect(_progressDialog, SIGNAL(canceled()), this, SLOT(cancelLoadClicked()));
_progressTimer = new QTimer(this);
connect(_progressTimer, SIGNAL(timeout()), this, SLOT(updateProgress()));
connect(soundFonts, SIGNAL(itemSelectionChanged()), this, SLOT(updateUpDownButtons()));
updateUpDownButtons();
}
@ -110,12 +149,12 @@ void FluidGui::soundFontUpClicked()
if (row <= 0)
return;
QStringList sfonts = fluid()->soundFonts();
sfonts.swap(row, row-1);
sfonts.swap(row, row - 1);
fluid()->loadSoundFonts(sfonts);
sfonts = fluid()->soundFonts();
soundFonts->clear();
soundFonts->addItems(sfonts);
soundFonts->setCurrentRow(row-1);
soundFonts->setCurrentRow(row - 1);
emit sfChanged();
}
@ -131,12 +170,12 @@ void FluidGui::soundFontDownClicked()
return;
QStringList sfonts = fluid()->soundFonts();
sfonts.swap(row, row+1);
sfonts.swap(row, row + 1);
fluid()->loadSoundFonts(sfonts);
sfonts = fluid()->soundFonts();
soundFonts->clear();
soundFonts->addItems(sfonts);
soundFonts->setCurrentRow(row+1);
soundFonts->setCurrentRow(row + 1);
emit sfChanged();
}
@ -184,34 +223,92 @@ void FluidGui::soundFontAddClicked()
if (!ld.exec())
return;
QString sfName = ld.name();
QString sfPath = ld.path();
for (auto item : ld.getNamePaths()) {
_sfToLoad.push_back(item);
}
loadSf();
int n = soundFonts->count();
QStringList sl;
for (int i = 0; i < n; ++i) {
QListWidgetItem* item = soundFonts->item(i);
sl.append(item->text());
}
if (sl.contains(sfPath)) {
QMessageBox::warning(this,
tr("MuseScore"),
tr("SoundFont %1 already loaded").arg(sfPath));
}
else {
bool loaded = fluid()->addSoundFont(sfPath);
if (!loaded) {
QMessageBox::warning(this,
tr("MuseScore"),
tr("Cannot load SoundFont %1").arg(sfPath));
}
else {
soundFonts->insertItem(0, sfName);
emit sfChanged();
emit valueChanged();
}
}
updateUpDownButtons();
}
//---------------------------------------------------------
// cancelLoad
//---------------------------------------------------------
void FluidGui::cancelLoadClicked()
{
fluid()->setLoadWasCanceled(true);
}
//---------------------------------------------------------
// updateProgress
//---------------------------------------------------------
void FluidGui::updateProgress()
{
_progressDialog->setValue(fluid()->loadProgress());
}
//---------------------------------------------------------
// loadSf
//---------------------------------------------------------
void FluidGui::loadSf()
{
if (_sfToLoad.empty())
return;
struct SfNamePath item = _sfToLoad.front();
QString sfName = item.name;
QString sfPath = item.path;
_sfToLoad.pop_front();
QStringList sl;
for (int i = 0; i < soundFonts->count(); ++i) {
QListWidgetItem* item = soundFonts->item(i);
sl.append(item->text());
}
if (sl.contains(sfPath)) {
QMessageBox::warning(this,
tr("MuseScore"),
tr("SoundFont %1 already loaded").arg(sfPath));
}
else {
_loadedSfName = sfName;
_loadedSfPath = sfPath;
QFuture<bool> future = QtConcurrent::run(fluid(), &FluidS::Fluid::addSoundFont, sfPath);
_futureWatcher.setFuture(future);
_progressTimer->start(1);
_progressDialog->exec();
}
}
//---------------------------------------------------------
// onSoundFontLoaded
//---------------------------------------------------------
void FluidGui::onSoundFontLoaded()
{
bool loaded = _futureWatcher.result();
bool wasNotCanceled = !_progressDialog->wasCanceled();
_progressTimer->stop();
_progressDialog->reset();
if (loaded) {
QListWidgetItem* item = new QListWidgetItem;
item->setText(_loadedSfName);
item->setData(Qt::UserRole, _loadedSfPath);
//files->insertItem(0, item);
soundFonts->insertItem(0, item);
emit valueChanged();
emit sfChanged();
}
else if (wasNotCanceled) {
QMessageBox::warning(this,
tr("MuseScore"),
tr("Cannot load SoundFont %1").arg(_loadedSfPath));
}
loadSf();
}

View file

@ -21,18 +21,29 @@
// ListDialog
//---------------------------------------------------------
struct SfNamePath {
QString name;
QString path;
};
class SfListDialog : public QDialog {
Q_OBJECT
int _idx = -1;
std::vector<struct SfNamePath> _namePaths;
QListWidget* list;
QDialogButtonBox* buttonBox;
QPushButton* okButton;
QPushButton* cancelButton;
private slots:
void itemSelected(QListWidgetItem*);
void okClicked();
void cancelClicked();
public:
SfListDialog(QWidget* parent = 0);
QString name();
QString path();
std::vector<struct SfNamePath> getNamePaths() { return _namePaths; }
void add(const QString& name, const QString& path);
};
@ -43,14 +54,22 @@ class SfListDialog : public QDialog {
class FluidGui : public Ms::SynthesizerGui, Ui::FluidGui {
Q_OBJECT
FluidS::Fluid* fluid() { return static_cast<FluidS::Fluid*>(synthesizer()); }
QFutureWatcher<bool> _futureWatcher;
QString _loadedSfPath;
QString _loadedSfName;
QProgressDialog* _progressDialog;
QTimer * _progressTimer;
std::list<struct SfNamePath> _sfToLoad;
void loadSf();
private slots:
void soundFontUpClicked();
void soundFontDownClicked();
void soundFontAddClicked();
void soundFontDeleteClicked();
void onSoundFontLoaded();
void updateProgress();
void cancelLoadClicked();
void updateUpDownButtons();
public slots:
@ -58,6 +77,7 @@ class FluidGui : public Ms::SynthesizerGui, Ui::FluidGui {
public:
FluidGui(Ms::Synthesizer*);
FluidS::Fluid* fluid() { return static_cast<FluidS::Fluid*>(synthesizer()); }
};
#endif

View file

@ -80,13 +80,23 @@ bool SFont::read(const QString& s)
if (!load())
return false;
foreach(Instrument* i, instruments) {
if (!i->import_sfont())
synth->setLoadProgress(0);
int currentInstument = 0;
for (auto instrument : instruments) {
synth->setLoadProgress(currentInstument++ * 100 / instruments.count() / 2);
if (synth->loadWasCanceled())
return false;
if (!instrument->import_sfont())
return false;
}
foreach(Preset* p, presets) {
if (!p->importSfont())
for (auto preset : presets) {
synth->setLoadProgress(currentInstument++ * 100 / instruments.count() / 2);
if (synth->loadWasCanceled())
return false;
if (!preset->importSfont())
return false;
}
return true;

View file

@ -119,6 +119,7 @@ class SFont {
SFVersion version() const { return _version; }
int bankOffset() const { return _bankOffset; }
void setBankOffset(int val) { _bankOffset = val; }
friend class Preset;
};

View file

@ -297,6 +297,19 @@ bool Zerberus::loadSoundFonts(const QStringList& sl)
return true;
}
//---------------------------------------------------------
// removeSoundFonts
//---------------------------------------------------------
bool Zerberus::removeSoundFonts(const QStringList& fileNames)
{
for (auto fileName : fileNames) {
if (!removeSoundFont(QFileInfo(fileName).absoluteFilePath()))
return false;
}
return true;
}
//---------------------------------------------------------
// soundFonts
//---------------------------------------------------------
@ -315,6 +328,7 @@ QStringList Zerberus::soundFonts() const
bool Zerberus::addSoundFont(const QString& s)
{
QMutexLocker locker(&mutex);
return loadInstrument(s);
}

View file

@ -83,6 +83,8 @@ class Zerberus : public Ms::Synthesizer {
int _loadProgress = 0;
bool _loadWasCanceled = false;
QMutex mutex;
void programChange(int channel, int program);
void trigger(Channel*, int key, int velo, Trigger, int cc, int ccVal, double durSinceNoteOn);
void processNoteOff(Channel*, int pitch);
@ -122,6 +124,7 @@ class Zerberus : public Ms::Synthesizer {
virtual bool addSoundFont(const QString&);
virtual bool removeSoundFont(const QString&);
virtual bool loadSoundFonts(const QStringList&);
virtual bool removeSoundFonts(const QStringList& fileNames);
virtual QStringList soundFonts() const;
virtual Ms::SynthesizerGui* gui();

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>332</width>
<height>131</height>
<width>311</width>
<height>158</height>
</rect>
</property>
<property name="sizePolicy">
@ -20,10 +20,68 @@
<string/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1" rowspan="2">
<property name="leftMargin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer_4">
<widget class="QToolButton" name="soundFontUp">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="toolTip">
<string>Move SoundFont up</string>
</property>
<property name="accessibleDescription">
<string/>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset resource="../mscore/musescore.qrc">
<normaloff>:/data/icons/arrow_up.svg</normaloff>:/data/icons/arrow_up.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="soundFontDown">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="toolTip">
<string>Move SoundFont down</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset resource="../mscore/musescore.qrc">
<normaloff>:/data/icons/arrow_down.svg</normaloff>:/data/icons/arrow_down.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@ -36,7 +94,13 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="remove">
<widget class="QPushButton" name="soundFontDelete">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
@ -46,7 +110,7 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="add">
<widget class="QPushButton" name="soundFontAdd">
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
@ -57,15 +121,14 @@
</item>
</layout>
</item>
<item row="0" column="0" rowspan="2">
<item row="0" column="0">
<widget class="QListWidget" name="files">
<property name="spacing">
<number>4</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="../mscore/musescore.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -25,10 +25,12 @@ SfzListDialog::SfzListDialog(QWidget* parent)
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
list = new QListWidget;
list->setSelectionMode(QAbstractItemView::ExtendedSelection);
okButton = new QPushButton;
cancelButton = new QPushButton;
okButton->setText(tr("Load"));
cancelButton->setText(tr("Cancel"));
QVBoxLayout* layout = new QVBoxLayout;
buttonBox = new QDialogButtonBox;
layout->addWidget(list);
@ -92,8 +94,10 @@ ZerberusGui::ZerberusGui(Ms::Synthesizer* s)
: SynthesizerGui(s)
{
setupUi(this);
connect(add, SIGNAL(clicked()), SLOT(addClicked()));
connect(remove, SIGNAL(clicked()), SLOT(removeClicked()));
connect(soundFontUp, SIGNAL(clicked()), SLOT(soundFontUpClicked()));
connect(soundFontDown, SIGNAL(clicked()), SLOT(soundFontDownClicked()));
connect(soundFontAdd, SIGNAL(clicked()), SLOT(soundFontAddClicked()));
connect(soundFontDelete, SIGNAL(clicked()), SLOT(soundFontDeleteClicked()));
connect(&_futureWatcher, SIGNAL(finished()), this, SLOT(onSoundFontLoaded()));
_progressDialog = new QProgressDialog(tr("Loading..."), tr("Cancel"), 0, 100, 0, Qt::FramelessWindowHint);
_progressDialog->reset(); // required for Qt 5.5, see QTBUG-47042
@ -104,6 +108,51 @@ ZerberusGui::ZerberusGui(Ms::Synthesizer* s)
updateButtons();
}
void ZerberusGui::soundFontUpClicked()
{
int row = files->currentRow();
if (row <= 0)
return;
QStringList sfonts = zerberus()->soundFonts();
sfonts.swap(row, row-1);
zerberus()->removeSoundFonts(zerberus()->soundFonts());
loadSoundFontsAsync(sfonts);
files->setCurrentRow(row-1);
emit sfChanged();
}
void ZerberusGui::soundFontDownClicked()
{
int rows = files->count();
int row = files->currentRow();
if (row + 1 >= rows)
return;
QStringList sfonts = zerberus()->soundFonts();
sfonts.swap(row, row + 1);
zerberus()->removeSoundFonts(zerberus()->soundFonts());
loadSoundFontsAsync(sfonts);
files->setCurrentRow(row + 1);
emit sfChanged();
}
//---------------------------------------------------------
// loadSounfFontsAsync
//---------------------------------------------------------
void ZerberusGui::loadSoundFontsAsync(QStringList sfonts)
{
QFuture<bool> future = QtConcurrent::run(zerberus(), &Zerberus::loadSoundFonts, sfonts);
_futureWatcher.setFuture(future);
_progressTimer->start(1000);
_progressDialog->exec();
synthesizerChanged();
}
//---------------------------------------------------------
// collectFiles
//---------------------------------------------------------
@ -146,15 +195,19 @@ QFileInfoList Zerberus::sfzFiles()
return l;
}
//---------------------------------------------------------
// loadSfz
//---------------------------------------------------------
void ZerberusGui::loadSfz() {
if (_sfzToLoad.empty())
return;
struct SfzNamePath item = _sfzToLoad.back();
struct SfNamePath item = _sfzToLoad.front();
QString sfName = item.name;
QString sfPath = item.path;
_sfzToLoad.pop_back();
_sfzToLoad.pop_front();
QStringList sl;
for (int i = 0; i < files->count(); ++i) {
@ -162,7 +215,7 @@ void ZerberusGui::loadSfz() {
sl.append(item->text());
}
if (sl.contains(sfPath)) {
if (sl.contains(sfName)) {
QMessageBox::warning(this,
tr("MuseScore"),
tr("SoundFont %1 already loaded").arg(sfPath));
@ -181,7 +234,7 @@ void ZerberusGui::loadSfz() {
// addClicked
//---------------------------------------------------------
void ZerberusGui::addClicked()
void ZerberusGui::soundFontAddClicked()
{
zerberus()->setLoadWasCanceled(false);
@ -224,7 +277,9 @@ void ZerberusGui::updateProgress()
void ZerberusGui::updateButtons()
{
int row = files->currentRow();
remove->setEnabled(row != -1);
soundFontDelete->setEnabled(row != -1);
soundFontUp->setEnabled(row != -1);
soundFontDown->setEnabled(row != -1);
}
//---------------------------------------------------------
@ -241,7 +296,8 @@ void ZerberusGui::onSoundFontLoaded()
QListWidgetItem* item = new QListWidgetItem;
item->setText(_loadedSfName);
item->setData(Qt::UserRole, _loadedSfPath);
files->insertItem(0, item);
//files->insertItem(0, item);
files->addItem(item);
emit valueChanged();
emit sfChanged();
}
@ -257,7 +313,7 @@ void ZerberusGui::onSoundFontLoaded()
// removeClicked
//---------------------------------------------------------
void ZerberusGui::removeClicked()
void ZerberusGui::soundFontDeleteClicked()
{
int row = files->currentRow();
if (row >= 0) {

View file

@ -20,7 +20,7 @@
class QProgressDialog;
struct SfzNamePath {
struct SfNamePath {
QString name;
QString path;
};
@ -32,7 +32,7 @@ struct SfzNamePath {
class SfzListDialog : public QDialog {
Q_OBJECT
int _idx = -1;
std::vector<struct SfzNamePath> _namePaths;
std::vector<struct SfNamePath> _namePaths;
QListWidget* list;
QDialogButtonBox* buttonBox;
QPushButton* okButton;
@ -44,7 +44,7 @@ class SfzListDialog : public QDialog {
public:
SfzListDialog(QWidget* parent = 0);
std::vector<struct SfzNamePath> getNamePaths() { return _namePaths; }
std::vector<struct SfNamePath> getNamePaths() { return _namePaths; }
void add(const QString& name, const QString& path);
};
@ -60,13 +60,17 @@ class ZerberusGui : public Ms::SynthesizerGui, Ui::ZerberusGui {
QString _loadedSfName;
QProgressDialog* _progressDialog;
QTimer * _progressTimer;
std::vector<struct SfzNamePath> _sfzToLoad;
std::list<struct SfNamePath> _sfzToLoad;
void loadSfz();
void loadSoundFontsAsync(QStringList sfonts);
private slots:
void addClicked();
void soundFontUpClicked();
void soundFontDownClicked();
void soundFontAddClicked();
void cancelLoadClicked();
void removeClicked();
void soundFontDeleteClicked();
void onSoundFontLoaded();
void updateProgress();
void updateButtons();
@ -76,7 +80,7 @@ class ZerberusGui : public Ms::SynthesizerGui, Ui::ZerberusGui {
public:
ZerberusGui(Ms::Synthesizer*);
Zerberus* zerberus() { return (Zerberus*)synthesizer(); }
Zerberus* zerberus() { return static_cast<Zerberus*>(synthesizer()); }
};
#endif