drumstick  2.3.1
fluidsettingsdialog.cpp
Go to the documentation of this file.
1 /*
2  Drumstick MIDI Sequencer C++ library
3  Copyright (C) 2006-2021, Pedro Lopez-Cabanillas <plcl@users.sf.net>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <QDir>
20 #include <QFileDialog>
21 #include <QFileInfo>
22 #include <QPushButton>
23 #include <QStandardPaths>
24 #include <QToolButton>
25 #include <QMessageBox>
26 
27 #include "fluidsettingsdialog.h"
28 #include "ui_fluidsettingsdialog.h"
31 
37 namespace drumstick { namespace widgets {
38 
39 const QString FluidSettingsDialog::QSTR_PREFERENCES = QStringLiteral("FluidSynth");
40 const QString FluidSettingsDialog::QSTR_INSTRUMENTSDEFINITION = QStringLiteral("InstrumentsDefinition");
41 const QString FluidSettingsDialog::QSTR_DATADIR = QStringLiteral("soundfonts");
42 const QString FluidSettingsDialog::QSTR_DATADIR2 = QStringLiteral("sounds/sf2");
43 const QString FluidSettingsDialog::QSTR_SOUNDFONT = QStringLiteral("default.sf2");
44 const QString FluidSettingsDialog::QSTR_AUDIODRIVER = QStringLiteral("AudioDriver");
45 const QString FluidSettingsDialog::QSTR_PERIODSIZE = QStringLiteral("PeriodSize");
46 const QString FluidSettingsDialog::QSTR_PERIODS = QStringLiteral("Periods");
47 const QString FluidSettingsDialog::QSTR_SAMPLERATE = QStringLiteral("SampleRate");
48 const QString FluidSettingsDialog::QSTR_CHORUS = QStringLiteral("Chorus");
49 const QString FluidSettingsDialog::QSTR_REVERB = QStringLiteral("Reverb");
50 const QString FluidSettingsDialog::QSTR_GAIN = QStringLiteral("Gain");
51 const QString FluidSettingsDialog::QSTR_POLYPHONY = QStringLiteral("Polyphony");
52 const double FluidSettingsDialog::DEFAULT_SAMPLERATE = 48000.0;
53 const double FluidSettingsDialog::DEFAULT_GAIN = .5;
54 
55 FluidSettingsDialog::FluidSettingsDialog(QWidget *parent) :
56  QDialog(parent),
57  ui(new Ui::FluidSettingsDialog)
58 {
59  ui->setupUi(this);
60  connect(ui->btnFile, &QToolButton::clicked, this, &FluidSettingsDialog::showFileDialog);
61  connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked,
62  this, &FluidSettingsDialog::restoreDefaults);
63  ui->periodSize->setValidator(new QIntValidator(64, 8192, this));
64  ui->periods->setValidator(new QIntValidator(2, 64, this));
65  ui->sampleRate->setValidator(new QDoubleValidator(22050.0, 96000.0, 1, this));
66  ui->gain->setValidator(new QDoubleValidator(0.0, 10.0, 2, this));
67  ui->polyphony->setValidator(new QIntValidator(16, 4096, this));
68 
70  m_driver = man.outputBackendByName("FluidSynth");
71  if (m_driver != nullptr) {
72  QVariant v = m_driver->property("audiodrivers");
73  if (v.isValid()) {
74  ui->audioDriver->clear();
75  ui->audioDriver->addItems(v.toStringList());
76  }
77  }
78 }
79 
80 FluidSettingsDialog::~FluidSettingsDialog()
81 {
82  //qDebug() << Q_FUNC_INFO;
83  if (m_driver != nullptr) {
84  m_driver->close();
85  }
86  delete ui;
87 }
88 
89 void FluidSettingsDialog::accept()
90 {
91  writeSettings();
92  if (m_driver != nullptr) {
93  QString title;
94  QVariant varStatus = m_driver->property("status");
95  if (varStatus.isValid()) {
96  title = varStatus.toBool() ? tr("FluidSynth Initialized") : tr("FluidSynth Initialization Failed");
97  QVariant varDiag = m_driver->property("diagnostics");
98  if (varDiag.isValid()) {
99  QString text = varDiag.toStringList().join(QChar::LineFeed).trimmed();
100  if (varStatus.toBool()) {
101  if (!text.isEmpty()) {
102  QMessageBox::information(this, title, text);
103  }
104  } else {
105  QMessageBox::critical(this, title, text);
106  return;
107  }
108  }
109  }
110  }
111  QDialog::accept();
112 }
113 
114 void FluidSettingsDialog::showEvent(QShowEvent *event)
115 {
116  readSettings();
117  event->accept();
118 }
119 
120 QString FluidSettingsDialog::defaultAudioDriver() const
121 {
122  const QString QSTR_DEFAULT_AUDIODRIVER =
123 #if defined(Q_OS_LINUX)
124  QLatin1String("pulseaudio");
125 #elif defined(Q_OS_WIN)
126  QLatin1String("dsound");
127 #elif defined(Q_OS_OSX)
128  QLatin1String("coreaudio");
129 #else
130  QLatin1String("oss");
131 #endif
132  return QSTR_DEFAULT_AUDIODRIVER;
133 }
134 
135 void FluidSettingsDialog::chkDriverProperties(QSettings *settings)
136 {
137  if (m_driver != nullptr) {
139  m_driver->close();
140  m_driver->initialize(settings);
141  m_driver->open(conn);
142 
143  QVariant drivers = m_driver->property("audiodrivers");
144  if (drivers.isValid()) {
145  auto text = ui->audioDriver->currentText();
146  ui->audioDriver->clear();
147  ui->audioDriver->addItems(drivers.toStringList());
148  ui->audioDriver->setCurrentText(text);
149  }
150  QVariant varVersion = m_driver->property("libversion");
151  if (varVersion.isValid()) {
152  ui->lblVersion->clear();
153  ui->lblVersion->setText(varVersion.toString());
154  }
155  QVariant varStatus = m_driver->property("status");
156  if (varStatus.isValid()) {
157  ui->lblStatus->clear();
158  ui->lblStatus->setText(varStatus.toBool() ? tr("Ready") : tr("Failed") );
159  ui->lblStatusIcon->setPixmap(varStatus.toBool() ? QPixmap(":/checked.png") : QPixmap(":/error.png") );
160  }
161  }
162 }
163 
164 void FluidSettingsDialog::readSettings()
165 {
166  SettingsFactory settings;
167  QString fs_defSoundFont = QSTR_SOUNDFONT;
168  QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory));
169  if (!dir.exists()) {
170  dir = QDir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR2, QStandardPaths::LocateDirectory));
171  }
172  QFileInfo sf2(dir, QSTR_SOUNDFONT);
173  if (sf2.exists()) {
174  fs_defSoundFont = sf2.absoluteFilePath();
175  }
176 
177  settings->beginGroup(QSTR_PREFERENCES);
178  ui->audioDriver->setCurrentText( settings->value(QSTR_AUDIODRIVER, defaultAudioDriver()).toString() );
179  ui->periodSize->setText( settings->value(QSTR_PERIODSIZE, DEFAULT_PERIODSIZE).toString() );
180  ui->periods->setText( settings->value(QSTR_PERIODS, DEFAULT_PERIODS).toString() );
181  ui->sampleRate->setText( settings->value(QSTR_SAMPLERATE, DEFAULT_SAMPLERATE).toString() );
182  ui->chorus->setChecked( settings->value(QSTR_CHORUS, DEFAULT_CHORUS).toInt() != 0 );
183  ui->reverb->setChecked( settings->value(QSTR_REVERB, DEFAULT_REVERB).toInt() != 0 );
184  ui->gain->setText( settings->value(QSTR_GAIN, DEFAULT_GAIN).toString() );
185  ui->polyphony->setText( settings->value(QSTR_POLYPHONY, DEFAULT_POLYPHONY).toString() );
186  ui->soundFont->setText( settings->value(QSTR_INSTRUMENTSDEFINITION, fs_defSoundFont).toString() );
187  settings->endGroup();
188 
189  chkDriverProperties(settings.getQSettings());
190 }
191 
192 void FluidSettingsDialog::writeSettings()
193 {
194  SettingsFactory settings;
195  QString audioDriver;
196  QString soundFont(QSTR_SOUNDFONT);
197  int periodSize(DEFAULT_PERIODSIZE);
198  int periods(DEFAULT_PERIODS);
199  double sampleRate(DEFAULT_SAMPLERATE);
200  int chorus(DEFAULT_CHORUS);
201  int reverb(DEFAULT_REVERB);
202  double gain(DEFAULT_GAIN);
203  int polyphony(DEFAULT_POLYPHONY);
204 
205  audioDriver = ui->audioDriver->currentText();
206  if (audioDriver.isEmpty()) {
207  audioDriver = defaultAudioDriver();
208  }
209  soundFont = ui->soundFont->text();
210  periodSize = ui->periodSize->text().toInt();
211  periods = ui->periods->text().toInt();
212  sampleRate = ui->sampleRate->text().toDouble();
213  chorus = (ui->chorus->isChecked() ? 1 : 0);
214  reverb = (ui->reverb->isChecked() ? 1 : 0);
215  gain = ui->gain->text().toDouble();
216  polyphony = ui->polyphony->text().toInt();
217 
218  settings->beginGroup(QSTR_PREFERENCES);
219  settings->setValue(QSTR_INSTRUMENTSDEFINITION, soundFont);
220  settings->setValue(QSTR_AUDIODRIVER, audioDriver);
221  settings->setValue(QSTR_PERIODSIZE, periodSize);
222  settings->setValue(QSTR_PERIODS, periods);
223  settings->setValue(QSTR_SAMPLERATE, sampleRate);
224  settings->setValue(QSTR_CHORUS, chorus);
225  settings->setValue(QSTR_REVERB, reverb);
226  settings->setValue(QSTR_GAIN, gain);
227  settings->setValue(QSTR_POLYPHONY, polyphony);
228  settings->endGroup();
229  settings->sync();
230 
231  chkDriverProperties(settings.getQSettings());
232 }
233 
234 void FluidSettingsDialog::restoreDefaults()
235 {
236  ui->audioDriver->setCurrentText( defaultAudioDriver() );
237  ui->periodSize->setText( QString::number( DEFAULT_PERIODSIZE ));
238  ui->periods->setText( QString::number( DEFAULT_PERIODS ));
239  ui->sampleRate->setText( QString::number( DEFAULT_SAMPLERATE ));
240  ui->chorus->setChecked( DEFAULT_CHORUS != 0 );
241  ui->reverb->setChecked( DEFAULT_REVERB != 0 );
242  ui->gain->setText( QString::number( DEFAULT_GAIN ) );
243  ui->polyphony->setText( QString::number( DEFAULT_POLYPHONY ));
244  ui->soundFont->setText( QSTR_SOUNDFONT );
245 }
246 
247 void FluidSettingsDialog::showFileDialog()
248 {
249  QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory));
250  if (!dir.exists()) {
251  dir = QDir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR2, QStandardPaths::LocateDirectory));
252  }
253  QString fileName = QFileDialog::getOpenFileName(this, tr("Select SoundFont"), dir.absolutePath(), tr("SoundFont Files (*.sf2)"));
254  if (!fileName.isEmpty()) {
255  ui->soundFont->setText(fileName);
256  }
257 }
258 
259 void FluidSettingsDialog::changeSoundFont(const QString& fileName)
260 {
261  readSettings();
262  ui->soundFont->setText(fileName);
263  writeSettings();
264 }
265 
266 } // namespace widgets
267 } // namespace drumstick
BackendManager class declaration.
The QSettings class provides persistent platform-independent application settings.
The BackendManager class manages lists of dynamic and static backends for applications based on drums...
MIDIOutput * outputBackendByName(const QString name)
outputBackendByName
virtual void close()=0
close the MIDI port
Declaration of the Fluidsynth configuration dialog.
QPair< QString, QVariant > MIDIConnection
MIDIConnection represents a connection identifier.
Definition: rtmidioutput.h:106
void DRUMSTICK_EXPORT changeSoundFont(const QString driver, const QString fileName, QWidget *parent=nullptr)
Changes the sound font configuration Some RT output drivers accept soundfonts.
Drumstick common.
Definition: alsaclient.cpp:68
SettingsFactory class declaration.