changeset 552:8c11ca1ebc39 bqresample

Some fixes to sample rate management
author Chris Cannam
date Fri, 09 Dec 2016 13:46:34 +0000
parents b9d8c7a690d6
children 2a1e9e017484
files audio/AudioCallbackPlaySource.cpp audio/AudioCallbackPlaySource.h framework/MainWindowBase.cpp
diffstat 3 files changed, 45 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/audio/AudioCallbackPlaySource.cpp	Wed Dec 07 13:57:45 2016 +0000
+++ b/audio/AudioCallbackPlaySource.cpp	Fri Dec 09 13:46:34 2016 +0000
@@ -230,13 +230,15 @@
 	if (willPlay) clearRingBuffers(true);
     }
 
-    if (buffersChanged || srChanged) {
-
-        // There are more channels than there were before, or the
-        // source sample rate has changed
-
-        //!!!
-
+    if (srChanged) {
+        SVCERR << "AudioCallbackPlaySource: Source rate changed" << endl;
+        if (m_resamplerWrapper) {
+            SVCERR << "AudioCallbackPlaySource: Source sample rate changed to "
+                << m_sourceSampleRate << ", updating resampler wrapper" << endl;
+            m_resamplerWrapper->changeApplicationSampleRate
+                (int(round(m_sourceSampleRate)));
+            m_resamplerWrapper->reset();
+        }
     }
 
     rebuildRangeLists();
@@ -540,7 +542,7 @@
 }
 
 void
-AudioCallbackPlaySource::preferenceChanged(PropertyContainer::PropertyName n)
+AudioCallbackPlaySource::preferenceChanged(PropertyContainer::PropertyName )
 {
 }
 
@@ -578,6 +580,10 @@
 AudioCallbackPlaySource::setResamplerWrapper(breakfastquay::ResamplerWrapper *w)
 {
     m_resamplerWrapper = w;
+    if (m_resamplerWrapper && m_sourceSampleRate != 0) {
+        m_resamplerWrapper->changeApplicationSampleRate
+            (int(round(m_sourceSampleRate)));
+    }
 }
 
 void
@@ -944,7 +950,7 @@
 }
 
 void
-AudioCallbackPlaySource::setSystemPlaybackChannelCount(int c)
+AudioCallbackPlaySource::setSystemPlaybackChannelCount(int)
 {
 }
 
@@ -1336,8 +1342,6 @@
 
     int channels = getTargetChannelCount();
 
-    sv_frame_t orig = space;
-
     static float **bufferPtrs = 0;
     static int bufferPtrCount = 0;
 
--- a/audio/AudioCallbackPlaySource.h	Wed Dec 07 13:57:45 2016 +0000
+++ b/audio/AudioCallbackPlaySource.h	Fri Dec 09 13:46:34 2016 +0000
@@ -203,30 +203,45 @@
      * to the play target.  This may be more than the source channel
      * count: for example, a mono source will provide 2 channels
      * after pan.
+     *
      * This may safely be called from a realtime thread.  Returns 0 if
      * there is no source yet available.
+     *
+     * override from AudioPlaySource
      */
-    int getTargetChannelCount() const;
+    virtual int getTargetChannelCount() const override;
 
     /**
      * ApplicationPlaybackSource equivalent of the above.
+     *
+     * override from breakfastquay::ApplicationPlaybackSource
      */
-    virtual int getApplicationChannelCount() const {
+    virtual int getApplicationChannelCount() const override {
         return getTargetChannelCount();
     }
     
     /**
-     * Get the actual sample rate of the source material.  This may
-     * safely be called from a realtime thread.  Returns 0 if there is
-     * no source yet available.
+     * Get the actual sample rate of the source material (the main
+     * model).  This may safely be called from a realtime thread.
+     * Returns 0 if there is no source yet available.
+     *
+     * When this changes, the AudioCallbackPlaySource notifies its
+     * ResamplerWrapper of the new sample rate so that it can resample
+     * correctly on the way to the device (which is opened at a fixed
+     * rate, see getApplicationSampleRate).
      */
-    virtual sv_samplerate_t getSourceSampleRate() const;
+    virtual sv_samplerate_t getSourceSampleRate() const override;
 
     /**
-     * ApplicationPlaybackSource equivalent of the above.
+     * ApplicationPlaybackSource interface method: get the sample rate
+     * at which the application wants the device to be opened. We
+     * always allow the device to open at its default rate, and then
+     * we resample if the audio is at a different rate. This avoids
+     * having to close and re-open the device to obtain consistent
+     * behaviour for consecutive sessions with different source rates.
      */
-    virtual int getApplicationSampleRate() const {
-        return int(round(getSourceSampleRate()));
+    virtual int getApplicationSampleRate() const override {
+        return 0;
     }
 
     /**
--- a/framework/MainWindowBase.cpp	Wed Dec 07 13:57:45 2016 +0000
+++ b/framework/MainWindowBase.cpp	Fri Dec 09 13:46:34 2016 +0000
@@ -1402,7 +1402,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);
@@ -2161,7 +2163,9 @@
     if (getMainModel()) {
         rate = getMainModel()->getSampleRate();
     } else if (Preferences::getInstance()->getResampleOnLoad()) {
-        rate = m_playSource->getSourceSampleRate();
+        if (getMainModel()) {
+            rate = getMainModel()->getSampleRate();
+        }
     }
 
     RDFImporter importer