24#include <QStandardPaths>
27#include <QVersionNumber>
30#include "ui_fluidsettingsdialog.h"
41const QString FluidSettingsDialog::QSTR_PREFERENCES = QStringLiteral(
"FluidSynth");
42const QString FluidSettingsDialog::QSTR_INSTRUMENTSDEFINITION = QStringLiteral(
"InstrumentsDefinition");
43const QString FluidSettingsDialog::QSTR_DATADIR = QStringLiteral(
"soundfonts");
44const QString FluidSettingsDialog::QSTR_DATADIR2 = QStringLiteral(
"sounds/sf2");
45const QString FluidSettingsDialog::QSTR_AUDIODRIVER = QStringLiteral(
"AudioDriver");
46const QString FluidSettingsDialog::QSTR_PERIODSIZE = QStringLiteral(
"PeriodSize");
47const QString FluidSettingsDialog::QSTR_PERIODS = QStringLiteral(
"Periods");
48const QString FluidSettingsDialog::QSTR_SAMPLERATE = QStringLiteral(
"SampleRate");
49const QString FluidSettingsDialog::QSTR_CHORUS = QStringLiteral(
"Chorus");
50const QString FluidSettingsDialog::QSTR_REVERB = QStringLiteral(
"Reverb");
51const QString FluidSettingsDialog::QSTR_GAIN = QStringLiteral(
"Gain");
52const QString FluidSettingsDialog::QSTR_POLYPHONY = QStringLiteral(
"Polyphony");
53const QString FluidSettingsDialog::QSTR_BUFFERTIME = QStringLiteral(
"BufferTime");
54const QString FluidSettingsDialog::QSTR_PULSEAUDIO = QStringLiteral(
"pulseaudio");
55const QString FluidSettingsDialog::QSTR_CHORUS_DEPTH = QStringLiteral(
"chorus_depth");
56const QString FluidSettingsDialog::QSTR_CHORUS_LEVEL = QStringLiteral(
"chorus_level");
57const QString FluidSettingsDialog::QSTR_CHORUS_NR = QStringLiteral(
"chorus_nr");
58const QString FluidSettingsDialog::QSTR_CHORUS_SPEED = QStringLiteral(
"chorus_speed");
59const QString FluidSettingsDialog::QSTR_REVERB_DAMP = QStringLiteral(
"reverb_damp");
60const QString FluidSettingsDialog::QSTR_REVERB_LEVEL = QStringLiteral(
"reverb_level");
61const QString FluidSettingsDialog::QSTR_REVERB_SIZE = QStringLiteral(
"reverb_size");
62const QString FluidSettingsDialog::QSTR_REVERB_WIDTH = QStringLiteral(
"reverb_width");
64FluidSettingsDialog::FluidSettingsDialog(QWidget *parent) :
66 ui(new Ui::FluidSettingsDialog)
69 connect(ui->audioDriver, &QComboBox::currentTextChanged,
this, &FluidSettingsDialog::audioDriverChanged);
70 connect(ui->bufferTime, QOverload<int>::of(&QSpinBox::valueChanged),
this, &FluidSettingsDialog::bufferTimeChanged);
71 connect(ui->periodSize, QOverload<int>::of(&QSpinBox::valueChanged),
this, &FluidSettingsDialog::bufferSizeChanged);
72 connect(ui->periods, QOverload<int>::of(&QSpinBox::valueChanged),
this, &FluidSettingsDialog::bufferSizeChanged);
73 connect(ui->btnFile, &QToolButton::clicked,
this, &FluidSettingsDialog::showFileDialog);
74 connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked,
75 this, &FluidSettingsDialog::restoreDefaults);
76 auto sampleRateValidator =
new QDoubleValidator(8000.0, 96000.0, 1,
this);
77 sampleRateValidator->setNotation(QDoubleValidator::StandardNotation);
78 sampleRateValidator->setLocale(QLocale::c());
79 ui->sampleRate->setValidator(sampleRateValidator);
80 auto gainValidator =
new QDoubleValidator(0.1, 10.0, 2,
this);
81 gainValidator->setNotation(QDoubleValidator::StandardNotation);
82 gainValidator->setLocale(QLocale::c());
83 ui->gain->setValidator(gainValidator);
84 auto polyphonyValidator =
new QIntValidator(1, 65535,
this);
85 ui->polyphony->setValidator(polyphonyValidator);
86 connect(ui->chorus_depth, &QAbstractSlider::valueChanged,
this, [=](
int val) {
87 setWidgetTip(ui->chorus_depth, QString::number(val / 10.0));
89 connect(ui->chorus_level, &QAbstractSlider::valueChanged,
this, [=](
int val) {
90 setWidgetTip(ui->chorus_level, QString::number(val / 10.0));
92 connect(ui->chorus_nr, &QAbstractSlider::valueChanged,
this, [=](
int val) {
93 setWidgetTip(ui->chorus_nr, QString::number(val));
95 connect(ui->chorus_speed, &QAbstractSlider::valueChanged,
this, [=](
int val) {
96 setWidgetTip(ui->chorus_speed, QString::number(val / 10.0));
99 connect(ui->reverb_damp, &QAbstractSlider::valueChanged,
this, [=](
int val) {
100 setWidgetTip(ui->reverb_damp, QString::number(val / 10.0));
102 connect(ui->reverb_level, &QAbstractSlider::valueChanged,
this, [=](
int val) {
103 setWidgetTip(ui->reverb_level, QString::number(val / 10.0));
105 connect(ui->reverb_size, &QAbstractSlider::valueChanged,
this, [=](
int val) {
106 setWidgetTip(ui->reverb_size, QString::number(val / 10.0));
108 connect(ui->reverb_width, &QAbstractSlider::valueChanged,
this, [=](
int val) {
109 setWidgetTip(ui->reverb_width, QString::number(val / 10.0));
114 if (m_driver !=
nullptr) {
115 QVariant v = m_driver->property(
"audiodrivers");
117 ui->audioDriver->blockSignals(
true);
118 ui->audioDriver->clear();
119 ui->audioDriver->addItems(v.toStringList());
120 ui->audioDriver->blockSignals(
false);
122 v = m_driver->property(
"soundfont");
124 m_defSoundFont = v.toString();
127 ui->bufferTime->blockSignals(
true);
128 ui->periodSize->blockSignals(
true);
129 ui->periods->blockSignals(
true);
133FluidSettingsDialog::~FluidSettingsDialog()
136 if (m_driver !=
nullptr) {
142bool FluidSettingsDialog::checkRanges()
const
145 if (ui->gain->hasAcceptableInput()) {
146 ui->gain->deselect();
148 ui->gain->selectAll();
150 if (ui->polyphony->hasAcceptableInput()) {
151 ui->polyphony->deselect();
153 ui->polyphony->selectAll();
155 if (ui->sampleRate->hasAcceptableInput()) {
156 ui->sampleRate->deselect();
158 ui->sampleRate->selectAll();
161 ui->bufferTime->hasAcceptableInput() &&
162 ui->periodSize->hasAcceptableInput() &&
163 ui->periods->hasAcceptableInput() &&
164 ui->gain->hasAcceptableInput() &&
165 ui->polyphony->hasAcceptableInput() &&
166 ui->sampleRate->hasAcceptableInput();
169void FluidSettingsDialog::accept()
174 if (m_driver !=
nullptr) {
176 QVariant varStatus = m_driver->property(
"status");
177 if (varStatus.isValid()) {
178 title = varStatus.toBool() ? tr(
"FluidSynth Initialized") : tr(
"FluidSynth Initialization Failed");
179 QVariant varDiag = m_driver->property(
"diagnostics");
180 if (varDiag.isValid()) {
181 QString text = varDiag.toStringList().join(QChar::LineFeed).trimmed();
182 if (varStatus.toBool()) {
183 if (!text.isEmpty()) {
184 QMessageBox::information(this, title, text);
187 QMessageBox::critical(this, title, text);
197void FluidSettingsDialog::showEvent(QShowEvent *event)
203QString FluidSettingsDialog::defaultAudioDriver()
const
205 const QString QSTR_DEFAULT_AUDIODRIVER =
207 QLatin1String(
"wasapi");
208#elif defined(Q_OS_OSX)
209 QLatin1String(
"coreaudio");
210#elif defined(Q_OS_LINUX)
213 QLatin1String(
"oss");
215 return QSTR_DEFAULT_AUDIODRIVER;
218void FluidSettingsDialog::chkDriverProperties(
QSettings *settings)
221 if (m_driver !=
nullptr) {
224 m_driver->initialize(settings);
225 m_driver->open(conn);
227 QVariant drivers = m_driver->property(
"audiodrivers");
228 if (drivers.isValid()) {
229 auto text = ui->audioDriver->currentText();
230 ui->audioDriver->blockSignals(
true);
231 ui->audioDriver->clear();
232 ui->audioDriver->addItems(drivers.toStringList());
233 ui->audioDriver->setCurrentText(text);
234 ui->audioDriver->blockSignals(
false);
236 ui->lblVersion->clear();
237 ui->lblVersion->setText(driverVersion());
238 QVariant varStatus = m_driver->property(
"status");
239 if (varStatus.isValid()) {
240 ui->lblStatus->clear();
241 ui->lblStatus->setText(varStatus.toBool() ? tr(
"Ready") : tr(
"Failed") );
242 ui->lblStatusIcon->setPixmap(varStatus.toBool() ? QPixmap(
":/checked.png") : QPixmap(
":/error.png") );
247void FluidSettingsDialog::setWidgetTip(QWidget *w,
const QString &tip)
250 QToolTip::showText(w->parentWidget()->mapToGlobal(w->pos()), tip);
253void drumstick::widgets::FluidSettingsDialog::initBuffer()
255 if ((ui->audioDriver->currentText() == QSTR_PULSEAUDIO) && driverVersionLessThan_2_2_8()) {
257 int bufferTime = ui->bufferTime->value();
258 int minBufTime = ui->bufferTime->minimum();
259 if (bufferTime < minBufTime) {
260 bufferTime = minBufTime;
262 ui->bufferTime->setValue( bufferTime );
263 bufferTimeChanged( bufferTime );
270QString FluidSettingsDialog::driverVersion()
const
272 static QString result;
273 if (m_driver !=
nullptr && result.isEmpty()) {
274 QVariant varVersion = m_driver->property(
"libversion");
275 if (varVersion.isValid()) {
276 result = varVersion.toString();
282bool FluidSettingsDialog::driverVersionLessThan_2_2_8()
284 static const QVersionNumber check_2_2_8(2, 2, 8);
285 QVersionNumber driverV = QVersionNumber::fromString(driverVersion());
286 return driverV < check_2_2_8;
289void FluidSettingsDialog::readSettings()
292 SettingsFactory settings;
293 settings->beginGroup(QSTR_PREFERENCES);
294 ui->audioDriver->setCurrentText( settings->value(QSTR_AUDIODRIVER, defaultAudioDriver()).toString() );
295 ui->bufferTime->setValue( settings->value(QSTR_BUFFERTIME, DEFAULT_BUFFERTIME).toInt() );
296 ui->periodSize->setValue( settings->value(QSTR_PERIODSIZE, DEFAULT_PERIODSIZE).toInt() );
297 ui->periods->setValue( settings->value(QSTR_PERIODS, DEFAULT_PERIODS).toInt() );
298 ui->sampleRate->setText( settings->value(QSTR_SAMPLERATE, DEFAULT_SAMPLERATE).toString() );
299 ui->gain->setText( settings->value(QSTR_GAIN, DEFAULT_GAIN).toString() );
300 ui->polyphony->setText( settings->value(QSTR_POLYPHONY, DEFAULT_POLYPHONY).toString() );
301 ui->soundFont->setText( settings->value(QSTR_INSTRUMENTSDEFINITION, m_defSoundFont).toString() );
303 ui->chorus_depth->setValue(settings->value(QSTR_CHORUS_DEPTH, DEFAULT_CHORUS_DEPTH).toFloat()
305 ui->chorus_level->setValue(settings->value(QSTR_CHORUS_LEVEL, DEFAULT_CHORUS_LEVEL).toFloat()
307 ui->chorus_nr->setValue(settings->value(QSTR_CHORUS_NR, DEFAULT_CHORUS_NR).toInt());
308 ui->chorus_speed->setValue(settings->value(QSTR_CHORUS_SPEED, DEFAULT_CHORUS_SPEED).toFloat()
311 ui->reverb_damp->setValue(settings->value(QSTR_REVERB_DAMP, DEFAULT_REVERB_DAMP).toFloat() * 10);
312 ui->reverb_level->setValue(settings->value(QSTR_REVERB_LEVEL, DEFAULT_REVERB_LEVEL).toFloat()
314 ui->reverb_size->setValue(settings->value(QSTR_REVERB_SIZE, DEFAULT_REVERB_SIZE).toFloat() * 10);
315 ui->reverb_width->setValue(settings->value(QSTR_REVERB_WIDTH, DEFAULT_REVERB_WIDTH).toFloat()
318 ui->chorus->setChecked(settings->value(QSTR_CHORUS, DEFAULT_CHORUS).toInt() != 0);
319 ui->reverb->setChecked(settings->value(QSTR_REVERB, DEFAULT_REVERB).toInt() != 0);
321 settings->endGroup();
323 audioDriverChanged( ui->audioDriver->currentText() );
324 chkDriverProperties(settings.getQSettings());
327void FluidSettingsDialog::writeSettings()
330 SettingsFactory settings;
332 QString soundFont(m_defSoundFont);
333 int bufferTime(DEFAULT_BUFFERTIME);
334 int periodSize(DEFAULT_PERIODSIZE);
335 int periods(DEFAULT_PERIODS);
336 double sampleRate(DEFAULT_SAMPLERATE);
337 int chorus(DEFAULT_CHORUS);
338 int reverb(DEFAULT_REVERB);
339 double gain(DEFAULT_GAIN);
340 int polyphony(DEFAULT_POLYPHONY);
342 double chorus_depth(DEFAULT_CHORUS_DEPTH);
343 double chorus_level(DEFAULT_CHORUS_LEVEL);
344 int chorus_nr(DEFAULT_CHORUS_NR);
345 double chorus_speed(DEFAULT_CHORUS_SPEED);
347 double reverb_damp(DEFAULT_REVERB_DAMP);
348 double reverb_level(DEFAULT_REVERB_LEVEL);
349 double reverb_size(DEFAULT_REVERB_SIZE);
350 double reverb_width(DEFAULT_REVERB_WIDTH);
352 audioDriver = ui->audioDriver->currentText();
353 if (audioDriver.isEmpty()) {
354 audioDriver = defaultAudioDriver();
356 soundFont = ui->soundFont->text();
357 bufferTime = ui->bufferTime->value();
358 periodSize = ui->periodSize->value();
359 periods = ui->periods->value();
360 sampleRate = ui->sampleRate->text().toDouble();
361 chorus = (ui->chorus->isChecked() ? 1 : 0);
362 reverb = (ui->reverb->isChecked() ? 1 : 0);
363 gain = ui->gain->text().toDouble();
364 polyphony = ui->polyphony->text().toInt();
366 chorus_depth = ui->chorus_depth->value() / 10.0;
367 chorus_level = ui->chorus_level->value() / 10.0;
368 chorus_nr = ui->chorus_nr->value();
369 chorus_speed = ui->chorus_speed->value() / 10.0;
370 reverb_damp = ui->reverb_damp->value() / 10.0;
371 reverb_level = ui->reverb_level->value() / 10.0;
372 reverb_size = ui->reverb_size->value() / 10.0;
373 reverb_width = ui->reverb_width->value() / 10.0;
375 settings->beginGroup(QSTR_PREFERENCES);
376 settings->setValue(QSTR_INSTRUMENTSDEFINITION, soundFont);
377 settings->setValue(QSTR_AUDIODRIVER, audioDriver);
378 settings->setValue(QSTR_BUFFERTIME, bufferTime);
379 settings->setValue(QSTR_PERIODSIZE, periodSize);
380 settings->setValue(QSTR_PERIODS, periods);
381 settings->setValue(QSTR_SAMPLERATE, sampleRate);
382 settings->setValue(QSTR_CHORUS, chorus);
383 settings->setValue(QSTR_REVERB, reverb);
384 settings->setValue(QSTR_GAIN, gain);
385 settings->setValue(QSTR_POLYPHONY, polyphony);
386 settings->setValue(QSTR_CHORUS_DEPTH, chorus_depth);
387 settings->setValue(QSTR_CHORUS_LEVEL, chorus_level);
388 settings->setValue(QSTR_CHORUS_NR, chorus_nr);
389 settings->setValue(QSTR_CHORUS_SPEED, chorus_speed);
390 settings->setValue(QSTR_REVERB_DAMP, reverb_damp);
391 settings->setValue(QSTR_REVERB_LEVEL, reverb_level);
392 settings->setValue(QSTR_REVERB_SIZE, reverb_size);
393 settings->setValue(QSTR_REVERB_WIDTH, reverb_width);
394 settings->endGroup();
397 chkDriverProperties(settings.getQSettings());
400void FluidSettingsDialog::restoreDefaults()
403 ui->audioDriver->setCurrentText(defaultAudioDriver());
404 ui->bufferTime->setValue(DEFAULT_BUFFERTIME);
405 ui->periodSize->setValue(DEFAULT_PERIODSIZE);
406 ui->periods->setValue(DEFAULT_PERIODS);
407 ui->sampleRate->setText(QString::number(DEFAULT_SAMPLERATE));
408 ui->gain->setText(QString::number(DEFAULT_GAIN));
409 ui->polyphony->setText(QString::number(DEFAULT_POLYPHONY));
410 ui->soundFont->setText(m_defSoundFont);
411 ui->chorus_depth->setValue(DEFAULT_CHORUS_DEPTH * 10);
412 ui->chorus_level->setValue(DEFAULT_CHORUS_LEVEL * 10);
413 ui->chorus_nr->setValue(DEFAULT_CHORUS_NR);
414 ui->chorus_speed->setValue(DEFAULT_CHORUS_SPEED * 10);
415 ui->reverb_damp->setValue(DEFAULT_REVERB_DAMP * 10);
416 ui->reverb_level->setValue(DEFAULT_REVERB_LEVEL * 10);
417 ui->reverb_size->setValue(DEFAULT_REVERB_SIZE * 10);
418 ui->reverb_width->setValue(DEFAULT_REVERB_WIDTH * 10);
419 ui->chorus->setChecked(DEFAULT_CHORUS != 0);
420 ui->reverb->setChecked(DEFAULT_REVERB != 0);
424void FluidSettingsDialog::showFileDialog()
426 QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory));
428 dir = QDir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR2, QStandardPaths::LocateDirectory));
430 QStringList fileNames
431 = QFileDialog::getOpenFileNames(
this,
432 tr(
"Select SoundFont"),
434 tr(
"SoundFont Files (*.sf2 *.sf3 *.dls)"));
435 if (!fileNames.isEmpty()) {
436 ui->soundFont->setText(fileNames.join(
';'));
440void FluidSettingsDialog::audioDriverChanged(
const QString &text)
443 if ((text == QSTR_PULSEAUDIO) && driverVersionLessThan_2_2_8()) {
444 ui->bufferTime->setDisabled(
false);
445 ui->bufferTime->blockSignals(
false);
446 ui->periodSize->setDisabled(
true);
447 ui->periodSize->blockSignals(
true);
448 ui->periods->setVisible(
false);
449 ui->periods->setDisabled(
true);
450 ui->periods->blockSignals(
true);
452 ui->bufferTime->setDisabled(
true);
453 ui->bufferTime->blockSignals(
true);
454 ui->periodSize->setDisabled(
false);
455 ui->periodSize->blockSignals(
false);
456 ui->periods->setVisible(
true);
457 ui->periods->setDisabled(
false);
458 ui->periods->blockSignals(
false);
463void FluidSettingsDialog::bufferTimeChanged(
int value)
465 double rate = ui->sampleRate->text().toDouble();
466 int size = qRound( value * rate / 1000.0 );
467 ui->periodSize->setValue( size );
468 ui->periods->setValue( ui->periods->minimum() );
472void FluidSettingsDialog::bufferSizeChanged()
474 QString audioDriver = ui->audioDriver->currentText();
475 double rate = ui->sampleRate->text().toDouble();
476 int size = ui->periodSize->value();
477 if ((audioDriver != QSTR_PULSEAUDIO) || !driverVersionLessThan_2_2_8()) {
478 size *= ui->periods->value();
480 int ms = qRound( 1000.0 * size / rate );
481 ui->bufferTime->setValue(ms);
485void FluidSettingsDialog::changeSoundFont(
const QString& fileName)
488 ui->soundFont->setText(fileName);
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
Declaration of the Fluidsynth configuration dialog.
QPair< QString, QVariant > MIDIConnection
MIDIConnection represents a connection identifier.
SettingsFactory class declaration.