# HG changeset patch # User Chris Cannam # Date 1481725721 0 # Node ID 3e2dee09c10c0baa9fd5e44f160214b708a5c470 # Parent db151fd290910a694bb8334d76485a3213e1efab# Parent 4c8402e902d73db4ebfc208db0164c9a6f4e546f Merge from branch 3.0-integration diff -r db151fd29091 -r 3e2dee09c10c .hgsubstate --- a/.hgsubstate Tue Dec 06 09:47:47 2016 +0000 +++ b/.hgsubstate Wed Dec 14 14:28:41 2016 +0000 @@ -1,13 +1,13 @@ -523a466726ea153feca116a89579b3dfdd7cf4e1 bqaudioio -f8f6b66b9875e6a9f153c1692b9f6cb241d51bf0 bqfft -6b0cbfca8fb7cf64f89b0a0026b63bc212b156af bqresample -68f8e88d6d76fc4ca074166cb80979ccbfc2b6c9 bqvec +18f41ae033e2b838a0d7982e8f4b2954a53037ed bqaudioio +ff3a7ebe6081a1740a5057ae77b796a595338806 bqfft +416b184b2bc85952cbce9241b2a0e7f09fa61e49 bqresample +dca061781357caf0500b89ccf73d8801de5d2636 bqvec 1eefc20919cd080b684b2bbbc0af7270b8facb54 checker 3768bdde6fdf866aa63fff5bde8d9fa64a8979ef dataquay 9b913ebff56264e6a10bef85a3f36a271ccab40a icons/scalable 3257ddb6fff110cc88f3ffeaeefa0f29d5eb3b6f piper-cpp 5f67a29f0fc7f1b908f7cde4866173a7af337862 sv-dependency-builds -fcac6c6b8deb3c78c4c453b4271a198775bd71d7 svapp -ea28ee929034977f941b9713e82583fc3d9b1312 svcore -6a6a63506e3f86b2b880232374c209430843417c svgui +07e111dd590227a6fc27ead995859a7770acc2e3 svapp +ccc8658914efbad80831fb518b72bdcd46571841 svcore +8665e0ffa0d8fac26fa49b7b31dd8032d9d3ea56 svgui 0eebd22a081a824067bf3d5de65326696feab653 vamp-plugin-sdk diff -r db151fd29091 -r 3e2dee09c10c bq-files.pri --- a/bq-files.pri Tue Dec 06 09:47:47 2016 +0000 +++ b/bq-files.pri Wed Dec 14 14:28:41 2016 +0000 @@ -15,18 +15,14 @@ bqaudioio/bqaudioio/ApplicationPlaybackSource.h \ bqaudioio/bqaudioio/ApplicationRecordTarget.h \ bqaudioio/bqaudioio/AudioFactory.h \ + bqaudioio/bqaudioio/ResamplerWrapper.h \ bqaudioio/bqaudioio/SystemAudioIO.h \ bqaudioio/bqaudioio/SystemPlaybackTarget.h \ bqaudioio/bqaudioio/SystemRecordSource.h \ bqaudioio/src/DynamicJACK.h \ bqaudioio/src/JACKAudioIO.h \ - bqaudioio/src/JACKPlaybackTarget.h \ - bqaudioio/src/JACKRecordSource.h \ bqaudioio/src/PortAudioIO.h \ - bqaudioio/src/PortAudioPlaybackTarget.h \ - bqaudioio/src/PortAudioRecordSource.h \ - bqaudioio/src/PulseAudioIO.h \ - bqaudioio/src/PulseAudioPlaybackTarget.h + bqaudioio/src/PulseAudioIO.h BQ_SOURCES += \ bqvec/src/Allocators.cpp \ @@ -36,13 +32,9 @@ bqresample/src/Resampler.cpp \ bqaudioio/src/AudioFactory.cpp \ bqaudioio/src/JACKAudioIO.cpp \ - bqaudioio/src/JACKPlaybackTarget.cpp \ - bqaudioio/src/JACKRecordSource.cpp \ bqaudioio/src/PortAudioIO.cpp \ - bqaudioio/src/PortAudioPlaybackTarget.cpp \ - bqaudioio/src/PortAudioRecordSource.cpp \ bqaudioio/src/PulseAudioIO.cpp \ - bqaudioio/src/PulseAudioPlaybackTarget.cpp \ + bqaudioio/src/ResamplerWrapper.cpp \ bqaudioio/src/SystemPlaybackTarget.cpp \ bqaudioio/src/SystemRecordSource.cpp diff -r db151fd29091 -r 3e2dee09c10c main/MainWindow.cpp --- a/main/MainWindow.cpp Tue Dec 06 09:47:47 2016 +0000 +++ b/main/MainWindow.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -2407,9 +2407,11 @@ QString description; +//!!!??? + sv_samplerate_t ssr = getMainModel()->getSampleRate(); sv_samplerate_t tsr = ssr; - if (m_playSource) tsr = m_playSource->getTargetSampleRate(); + if (m_playSource) tsr = m_playSource->getDeviceSampleRate(); if (ssr != tsr) { description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); @@ -2949,7 +2951,8 @@ { if (!m_recordTarget) return; - QString path = m_recordTarget->getRecordFolder(); + QString path = m_recordTarget->getRecordContainerFolder(); + if (path == "") path = m_recordTarget->getRecordFolder(); if (path == "") return; openLocalFolder(path); @@ -4605,6 +4608,9 @@ m_preferencesDialog = new PreferencesDialog(this); + connect(m_preferencesDialog, SIGNAL(audioDeviceChanged()), + this, SLOT(recreateAudioIO())); + // DeleteOnClose is safe here, because m_preferencesDialog is a // QPointer that will be zeroed when the dialog is deleted. We // use it in preference to leaving the dialog lying around because diff -r db151fd29091 -r 3e2dee09c10c main/PreferencesDialog.cpp --- a/main/PreferencesDialog.cpp Tue Dec 06 09:47:47 2016 +0000 +++ b/main/PreferencesDialog.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -42,13 +42,18 @@ #include "base/ResourceFinder.h" #include "layer/ColourMapper.h" -//#include "audioio/AudioTargetFactory.h" +#include "bqaudioio/AudioFactory.h" #include "version.h" +using namespace std; + PreferencesDialog::PreferencesDialog(QWidget *parent) : QDialog(parent), - m_audioDevice(0), + m_audioImplementation(0), + m_audioPlaybackDevice(0), + m_audioRecordDevice(0), + m_audioDeviceChanged(false), m_changesOnRestart(false) { setWindowTitle(tr("Sonic Visualiser: Application Preferences")); @@ -184,24 +189,38 @@ connect(octaveSystem, SIGNAL(currentIndexChanged(int)), this, SLOT(octaveSystemChanged(int))); - /*!!! restore - QComboBox *audioDevice = new QComboBox; - std::vector devices = - AudioTargetFactory::getInstance()->getCallbackTargetNames(); - settings.beginGroup("Preferences"); - QString targetName = settings.value("audio-target", "").toString(); + + QComboBox *audioImplementation = new QComboBox; + connect(audioImplementation, SIGNAL(currentIndexChanged(int)), + this, SLOT(audioImplementationChanged(int))); + + m_audioPlaybackDeviceCombo = new QComboBox; + connect(m_audioPlaybackDeviceCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(audioPlaybackDeviceChanged(int))); + + m_audioRecordDeviceCombo = new QComboBox; + connect(m_audioRecordDeviceCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(audioRecordDeviceChanged(int))); + + vector names = breakfastquay::AudioFactory::getImplementationNames(); + QString implementationName = settings.value("audio-target", "").toString(); + if (implementationName == "auto") implementationName = ""; + audioImplementation->addItem(tr("(auto)")); + m_audioImplementation = 0; + for (int i = 0; in_range_for(names, i); ++i) { + audioImplementation->addItem + (breakfastquay::AudioFactory::getImplementationDescription(names[i]). + c_str()); + if (implementationName.toStdString() == names[i]) { + audioImplementation->setCurrentIndex(i+1); + m_audioImplementation = i+1; + } + } settings.endGroup(); - for (int i = 0; i < (int)devices.size(); ++i) { - audioDevice->addItem(AudioTargetFactory::getInstance() - ->getCallbackTargetDescription(devices[i])); - if (targetName == devices[i]) audioDevice->setCurrentIndex(i); - } - - connect(audioDevice, SIGNAL(currentIndexChanged(int)), - this, SLOT(audioDeviceChanged(int))); - */ + rebuildDeviceCombos(); + m_audioDeviceChanged = false; // the rebuild will have changed this QCheckBox *resampleOnLoad = new QCheckBox; m_resampleOnLoad = prefs->getResampleOnLoad(); @@ -369,8 +388,14 @@ row, 0); subgrid->addWidget(gaplessMode, row++, 1, 1, 1); -//!!! subgrid->addWidget(new QLabel(tr("Playback audio device:")), row, 0); -//!!! subgrid->addWidget(audioDevice, row++, 1, 1, 2); + subgrid->addWidget(new QLabel(tr("Audio service:")), row, 0); + subgrid->addWidget(audioImplementation, row++, 1, 1, 2); + + subgrid->addWidget(new QLabel(tr("Audio playback device:")), row, 0); + subgrid->addWidget(m_audioPlaybackDeviceCombo, row++, 1, 1, 2); + + subgrid->addWidget(new QLabel(tr("Audio record device:")), row, 0); + subgrid->addWidget(m_audioRecordDeviceCombo, row++, 1, 1, 2); subgrid->setRowStretch(row, 10); @@ -498,6 +523,10 @@ subgrid->setRowStretch(row, 10); row++; + subgrid->addWidget(new QLabel(tr("(Use \"%1\" in the File menu to add to these.)") + .arg(tr("Export Session as Template..."))), + row++, 0); + settings.beginGroup("MainWindow"); m_currentTemplate = settings.value("sessiontemplate", "").toString(); settings.endGroup(); @@ -510,7 +539,7 @@ QStringList templates = ResourceFinder().getResourceFiles("templates", "svt"); - std::set byName; + set byName; foreach (QString t, templates) { byName.insert(QFileInfo(t).baseName()); } @@ -550,6 +579,56 @@ } void +PreferencesDialog::rebuildDeviceCombos() +{ + QSettings settings; + settings.beginGroup("Preferences"); + + vector names = breakfastquay::AudioFactory::getImplementationNames(); + string implementationName; + if (in_range_for(names, m_audioImplementation-1)) { + implementationName = names[m_audioImplementation-1]; + } + + QString suffix; + if (implementationName != "") { + suffix = "-" + QString(implementationName.c_str()); + } + + names = breakfastquay::AudioFactory::getPlaybackDeviceNames(implementationName); + QString playbackDeviceName = settings.value + ("audio-playback-device" + suffix, "").toString(); + m_audioPlaybackDeviceCombo->clear(); + m_audioPlaybackDeviceCombo->addItem(tr("(auto)")); + m_audioPlaybackDeviceCombo->setCurrentIndex(0); + m_audioPlaybackDevice = 0; + for (int i = 0; in_range_for(names, i); ++i) { + m_audioPlaybackDeviceCombo->addItem(names[i].c_str()); + if (playbackDeviceName.toStdString() == names[i]) { + m_audioPlaybackDeviceCombo->setCurrentIndex(i+1); + m_audioPlaybackDevice = i+1; + } + } + + names = breakfastquay::AudioFactory::getRecordDeviceNames(implementationName); + QString recordDeviceName = settings.value + ("audio-record-device" + suffix, "").toString(); + m_audioRecordDeviceCombo->clear(); + m_audioRecordDeviceCombo->addItem(tr("(auto)")); + m_audioRecordDeviceCombo->setCurrentIndex(0); + m_audioRecordDevice = 0; + for (int i = 0; in_range_for(names, i); ++i) { + m_audioRecordDeviceCombo->addItem(names[i].c_str()); + if (recordDeviceName.toStdString() == names[i]) { + m_audioRecordDeviceCombo->setCurrentIndex(i+1); + m_audioRecordDevice = i+1; + } + } + + settings.endGroup(); +} + +void PreferencesDialog::switchToTab(Tab t) { if (m_tabOrdering.contains(t)) { @@ -614,11 +693,34 @@ } void -PreferencesDialog::audioDeviceChanged(int s) +PreferencesDialog::audioImplementationChanged(int s) { - m_audioDevice = s; - m_applyButton->setEnabled(true); - m_changesOnRestart = true; + if (m_audioImplementation != s) { + m_audioImplementation = s; + rebuildDeviceCombos(); + m_applyButton->setEnabled(true); + m_audioDeviceChanged = true; + } +} + +void +PreferencesDialog::audioPlaybackDeviceChanged(int s) +{ + if (m_audioPlaybackDevice != s) { + m_audioPlaybackDevice = s; + m_applyButton->setEnabled(true); + m_audioDeviceChanged = true; + } +} + +void +PreferencesDialog::audioRecordDeviceChanged(int s) +{ + if (m_audioRecordDevice != s) { + m_audioRecordDevice = s; + m_applyButton->setEnabled(true); + m_audioDeviceChanged = true; + } } void @@ -769,14 +871,46 @@ prefs->setProperty("Octave Numbering System", m_octaveSystem); -//!!! std::vector devices = -//!!! AudioTargetFactory::getInstance()->getCallbackTargetNames(); - QSettings settings; settings.beginGroup("Preferences"); QString permishTag = QString("network-permission-%1").arg(SV_VERSION); settings.setValue(permishTag, m_networkPermission); -//!!! settings.setValue("audio-target", devices[m_audioDevice]); + + vector names = breakfastquay::AudioFactory::getImplementationNames(); + string implementationName; + if (m_audioImplementation > int(names.size())) { + m_audioImplementation = 0; + } + if (m_audioImplementation > 0) { + implementationName = names[m_audioImplementation-1]; + } + settings.setValue("audio-target", implementationName.c_str()); + + QString suffix; + if (implementationName != "") { + suffix = "-" + QString(implementationName.c_str()); + } + + names = breakfastquay::AudioFactory::getPlaybackDeviceNames(implementationName); + string deviceName; + if (m_audioPlaybackDevice > int(names.size())) { + m_audioPlaybackDevice = 0; + } + if (m_audioPlaybackDevice > 0) { + deviceName = names[m_audioPlaybackDevice-1]; + } + settings.setValue("audio-playback-device" + suffix, deviceName.c_str()); + + names = breakfastquay::AudioFactory::getRecordDeviceNames(implementationName); + deviceName = ""; + if (m_audioRecordDevice > int(names.size())) { + m_audioRecordDevice = 0; + } + if (m_audioRecordDevice > 0) { + deviceName = names[m_audioRecordDevice-1]; + } + settings.setValue("audio-record-device" + suffix, deviceName.c_str()); + settings.setValue("locale", m_currentLocale); #ifdef Q_OS_MAC settings.setValue("scaledHiDpi", m_retina); @@ -797,6 +931,11 @@ tr("Restart required

One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.

Please exit and restart the application now if you want these changes to take effect immediately.

")); m_changesOnRestart = false; } + + if (m_audioDeviceChanged) { + emit audioDeviceChanged(); + m_audioDeviceChanged = false; + } } void diff -r db151fd29091 -r 3e2dee09c10c main/PreferencesDialog.h --- a/main/PreferencesDialog.h Tue Dec 06 09:47:47 2016 +0000 +++ b/main/PreferencesDialog.h Wed Dec 14 14:28:41 2016 +0000 @@ -25,6 +25,7 @@ class QPushButton; class QLineEdit; class QTabWidget; +class QComboBox; class PreferencesDialog : public QDialog { @@ -42,6 +43,9 @@ }; void switchToTab(Tab tab); +signals: + void audioDeviceChanged(); + public slots: void applicationClosing(bool quickly); @@ -54,7 +58,9 @@ void colour3DColourChanged(int state); void propertyLayoutChanged(int layout); void tuningFrequencyChanged(double freq); - void audioDeviceChanged(int device); + void audioImplementationChanged(int impl); + void audioPlaybackDeviceChanged(int device); + void audioRecordDeviceChanged(int device); void resampleOnLoadChanged(int state); void gaplessModeChanged(int state); void vampProcessSeparationChanged(int state); @@ -85,6 +91,10 @@ QLineEdit *m_tempDirRootEdit; + QComboBox *m_audioPlaybackDeviceCombo; + QComboBox *m_audioRecordDeviceCombo; + void rebuildDeviceCombos(); + QString m_currentTemplate; QStringList m_templates; @@ -99,7 +109,9 @@ int m_colour3DColour; int m_propertyLayout; double m_tuningFrequency; - int m_audioDevice; + int m_audioImplementation; + int m_audioPlaybackDevice; + int m_audioRecordDevice; bool m_resampleOnLoad; bool m_gapless; bool m_runPluginsInProcess; @@ -113,6 +125,7 @@ int m_viewFontSize; bool m_showSplash; + bool m_audioDeviceChanged; bool m_changesOnRestart; };