diff framework/MainWindowBase.cpp @ 564:07e111dd5902 levelpanwidget

Merge from branch 3.0-integration
author Chris Cannam
date Wed, 14 Dec 2016 14:28:41 +0000
parents 7b115a6505b8
children 1cc23cee4ebf 58354f2934ec
line wrap: on
line diff
--- a/framework/MainWindowBase.cpp	Mon Dec 05 17:03:09 2016 +0000
+++ b/framework/MainWindowBase.cpp	Wed Dec 14 14:28:41 2016 +0000
@@ -76,6 +76,7 @@
 #include <bqaudioio/SystemPlaybackTarget.h>
 #include <bqaudioio/SystemAudioIO.h>
 #include <bqaudioio/AudioFactory.h>
+#include <bqaudioio/ResamplerWrapper.h>
 
 #include <QApplication>
 #include <QMessageBox>
@@ -141,6 +142,7 @@
     m_soundOptions(options),
     m_playSource(0),
     m_recordTarget(0),
+    m_resamplerWrapper(0),
     m_playTarget(0),
     m_audioIO(0),
     m_oscQueue(0),
@@ -240,6 +242,8 @@
 
     connect(m_playSource, SIGNAL(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool)),
 	    this,           SLOT(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool)));
+    connect(m_playSource, SIGNAL(channelCountIncreased()),
+            this,           SLOT(recreateAudioIO()));
     connect(m_playSource, SIGNAL(audioOverloadPluginDisabled()),
             this,           SLOT(audioOverloadPluginDisabled()));
     connect(m_playSource, SIGNAL(audioTimeStretchMultiChannelDisabled()),
@@ -293,14 +297,8 @@
     // depends on whether we handle recording or not) before we delete
     // the ApplicationPlaybackSource and ApplicationRecordTarget that
     // they refer to.
-    
-    // First prevent this trying to call target.
-    if (m_playSource) m_playSource->setSystemPlaybackTarget(0);
-
-    // Then delete the breakfastquay::System object.
-    // Only one of these two exists!
-    delete m_audioIO;
-    delete m_playTarget;
+
+    deleteAudioIO();
 
     // Then delete the Application objects.
     delete m_playSource;
@@ -1399,7 +1397,9 @@
     if (Preferences::getInstance()->getFixedSampleRate() != 0) {
         rate = Preferences::getInstance()->getFixedSampleRate();
     } else if (Preferences::getInstance()->getResampleOnLoad()) {
-        rate = m_playSource->getSourceSampleRate();
+        if (getMainModel()) {
+            rate = getMainModel()->getSampleRate();
+        }
     }
 
     ReadOnlyWaveFileModel *newModel = new ReadOnlyWaveFileModel(source, rate);
@@ -2158,7 +2158,9 @@
     if (getMainModel()) {
         rate = getMainModel()->getSampleRate();
     } else if (Preferences::getInstance()->getResampleOnLoad()) {
-        rate = m_playSource->getSourceSampleRate();
+        if (getMainModel()) {
+            rate = getMainModel()->getSampleRate();
+        }
     }
 
     RDFImporter importer
@@ -2300,27 +2302,49 @@
 
     if (!(m_soundOptions & WithAudioOutput)) return;
 
-    //!!! how to handle preferences
-/*    
     QSettings settings;
     settings.beginGroup("Preferences");
-    QString targetName = settings.value("audio-target", "").toString();
+    QString implementation = settings.value
+        ("audio-target", "").toString();
+    QString suffix;
+    if (implementation != "") suffix = "-" + implementation;
+    QString recordDevice = settings.value
+        ("audio-record-device" + suffix, "").toString();
+    QString playbackDevice = settings.value
+        ("audio-playback-device" + suffix, "").toString();
     settings.endGroup();
-    AudioTargetFactory *factory = AudioTargetFactory::getInstance();
-
-    factory->setDefaultCallbackTarget(targetName);
-*/
-
+
+    if (implementation == "auto") {
+        implementation = "";
+    }
+    
+    breakfastquay::AudioFactory::Preference preference;
+    preference.implementation = implementation.toStdString();
+    preference.recordDevice = recordDevice.toStdString();
+    preference.playbackDevice = playbackDevice.toStdString();
+
+    SVCERR << "createAudioIO: Preferred implementation = \""
+            << preference.implementation << "\"" << endl;
+    SVCERR << "createAudioIO: Preferred playback device = \""
+            << preference.playbackDevice << "\"" << endl;
+    SVCERR << "createAudioIO: Preferred record device = \""
+            << preference.recordDevice << "\"" << endl;
+
+    if (!m_resamplerWrapper) {
+        m_resamplerWrapper = new breakfastquay::ResamplerWrapper(m_playSource);
+        m_playSource->setResamplerWrapper(m_resamplerWrapper);
+    }
+    
     if (m_soundOptions & WithAudioInput) {
         m_audioIO = breakfastquay::AudioFactory::
-            createCallbackIO(m_recordTarget, m_playSource);
+            createCallbackIO(m_recordTarget, m_resamplerWrapper, preference);
         if (m_audioIO) {
             m_audioIO->suspend(); // start in suspended state
             m_playSource->setSystemPlaybackTarget(m_audioIO);
         }
     } else {
         m_playTarget = breakfastquay::AudioFactory::
-            createCallbackPlayTarget(m_playSource);
+            createCallbackPlayTarget(m_resamplerWrapper, preference);
         if (m_playTarget) {
             m_playTarget->suspend(); // start in suspended state
             m_playSource->setSystemPlaybackTarget(m_playTarget);
@@ -2329,25 +2353,54 @@
 
     if (!m_playTarget && !m_audioIO) {
         emit hideSplash();
-
-//        if (factory->isAutoCallbackTarget(targetName)) {
+        if (implementation == "") {
             QMessageBox::warning
 	    (this, tr("Couldn't open audio device"),
 	     tr("<b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p>"),
 	     QMessageBox::Ok);
-/*
         } else {
             QMessageBox::warning
                 (this, tr("Couldn't open audio device"),
                  tr("<b>No audio available</b><p>Failed to open your preferred audio device (\"%1\").<p>Audio playback will not be available during this session.</p>")
-                 .arg(factory->getCallbackTargetDescription(targetName)),
+                 .arg(breakfastquay::AudioFactory::
+                      getImplementationDescription(implementation.toStdString())
+                      .c_str()),
                  QMessageBox::Ok);
         }
-*/
-            return;
     }
 }
 
+void
+MainWindowBase::deleteAudioIO()
+{
+    // First prevent this trying to call target.
+    if (m_playSource) {
+        m_playSource->setSystemPlaybackTarget(0);
+        m_playSource->setResamplerWrapper(0);
+    }
+
+    // Then delete the breakfastquay::System object.
+    // Only one of these two exists!
+    delete m_audioIO;
+    delete m_playTarget;
+
+    // And the breakfastquay resampler wrapper. We need to
+    // delete/recreate this if the channel count changes, which is one
+    // of the use cases for recreateAudioIO() calling this
+    delete m_resamplerWrapper;
+
+    m_audioIO = 0;
+    m_playTarget = 0;
+    m_resamplerWrapper = 0;
+}
+
+void
+MainWindowBase::recreateAudioIO()
+{
+    deleteAudioIO();
+    createAudioIO();
+}
+
 WaveFileModel *
 MainWindowBase::getMainModel()
 {
@@ -2826,6 +2879,8 @@
         }
     }
 
+    if (m_viewManager) m_viewManager->setGlobalCentreFrame(0);
+    
     m_audioIO->resume();
 
     WritableWaveFileModel *model = m_recordTarget->startRecording();