changeset 1429:3e2dee09c10c levelpanwidget

Merge from branch 3.0-integration
author Chris Cannam
date Wed, 14 Dec 2016 14:28:41 +0000
parents db151fd29091 (current diff) 4c8402e902d7 (diff)
children f013210eeceb
files .hgsubstate main/MainWindow.cpp
diffstat 5 files changed, 200 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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
 
--- 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
--- 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<QString> 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<string> 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<QString> byName;
+    set<QString> byName;
     foreach (QString t, templates) {
         byName.insert(QFileInfo(t).baseName());
     }
@@ -550,6 +579,56 @@
 }
 
 void
+PreferencesDialog::rebuildDeviceCombos()
+{
+    QSettings settings;
+    settings.beginGroup("Preferences");
+
+    vector<string> 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<QString> 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<string> 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("<b>Restart required</b><p>One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.</p><p>Please exit and restart the application now if you want these changes to take effect immediately.</p>"));
         m_changesOnRestart = false;
     }
+
+    if (m_audioDeviceChanged) {
+        emit audioDeviceChanged();
+        m_audioDeviceChanged = false;
+    }
 }    
 
 void
--- 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;
 };