diff audio/AudioCallbackPlaySource.h @ 564:07e111dd5902 levelpanwidget

Merge from branch 3.0-integration
author Chris Cannam
date Wed, 14 Dec 2016 14:28:41 +0000
parents fc70aa31d8c5
children 6f54789f3127
line wrap: on
line diff
--- a/audio/AudioCallbackPlaySource.h	Mon Dec 05 17:03:09 2016 +0000
+++ b/audio/AudioCallbackPlaySource.h	Wed Dec 14 14:28:41 2016 +0000
@@ -39,6 +39,10 @@
     class RubberBandStretcher;
 }
 
+namespace breakfastquay {
+    class ResamplerWrapper;
+}
+
 class Model;
 class ViewManagerBase;
 class AudioGenerator;
@@ -86,23 +90,23 @@
      * from the given frame.  If playback is already under way, reseek
      * to the given frame and continue.
      */
-    virtual void play(sv_frame_t startFrame);
+    virtual void play(sv_frame_t startFrame) override;
 
     /**
      * Stop playback and ensure that no more data is returned.
      */
-    virtual void stop();
+    virtual void stop() override;
 
     /**
      * Return whether playback is currently supposed to be happening.
      */
-    virtual bool isPlaying() const { return m_playing; }
+    virtual bool isPlaying() const override { return m_playing; }
 
     /**
      * Return the frame number that is currently expected to be coming
      * out of the speakers.  (i.e. compensating for playback latency.)
      */
-    virtual sv_frame_t getCurrentPlayingFrame();
+    virtual sv_frame_t getCurrentPlayingFrame() override;
     
     /** 
      * Return the last frame that would come out of the speakers if we
@@ -121,10 +125,15 @@
     virtual void setSystemPlaybackTarget(breakfastquay::SystemPlaybackTarget *);
 
     /**
+     * Set the resampler wrapper, if one is in use.
+     */
+    virtual void setResamplerWrapper(breakfastquay::ResamplerWrapper *);
+    
+    /**
      * Set the block size of the target audio device.  This should be
      * called by the target class.
      */
-    virtual void setSystemPlaybackBlockSize(int blockSize);
+    virtual void setSystemPlaybackBlockSize(int blockSize) override;
 
     /**
      * Get the block size of the target audio device.  This may be an
@@ -132,16 +141,16 @@
      * size; the source should behave itself even if this value turns
      * out to be inaccurate.
      */
-    int getTargetBlockSize() const;
+    virtual int getTargetBlockSize() const override;
 
     /**
      * Set the playback latency of the target audio device, in frames
-     * at the target sample rate.  This is the difference between the
+     * at the device sample rate.  This is the difference between the
      * frame currently "leaving the speakers" and the last frame (or
      * highest last frame across all channels) requested via
      * getSamples().  The default is zero.
      */
-    void setSystemPlaybackLatency(int);
+    virtual void setSystemPlaybackLatency(int) override;
 
     /**
      * Get the playback latency of the target audio device.
@@ -155,25 +164,34 @@
      * source sample rate, this class will resample automatically to
      * fit.
      */
-    void setSystemPlaybackSampleRate(int);
+    virtual void setSystemPlaybackSampleRate(int) override;
 
     /**
      * Return the sample rate set by the target audio device (or the
      * source sample rate if the target hasn't set one).
      */
-    virtual sv_samplerate_t getTargetSampleRate() const;
+    virtual sv_samplerate_t getDeviceSampleRate() const override;
 
     /**
+     * Indicate how many channels the target audio device was opened
+     * with. Note that the target device does channel mixing in the
+     * case where our requested channel count does not match its, so
+     * long as we provide the number of channels we specified when the
+     * target was started in getApplicationChannelCount().
+     */
+    virtual void setSystemPlaybackChannelCount(int) override;
+    
+    /**
      * Set the current output levels for metering (for call from the
      * target)
      */
-    void setOutputLevels(float left, float right);
+    virtual void setOutputLevels(float left, float right) override;
 
     /**
      * Return the current (or thereabouts) output levels in the range
      * 0.0 -> 1.0, for metering purposes.
      */
-    virtual bool getOutputLevels(float &left, float &right);
+    virtual bool getOutputLevels(float &left, float &right) override;
 
     /**
      * Get the number of channels of audio that in the source models.
@@ -187,30 +205,52 @@
      * 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;
 
     /**
+     * Get the number of channels of audio the device is
+     * expecting. Equal to whatever getTargetChannelCount() was
+     * returning at the time the device was initialised.
+     */
+    int getDeviceChannelCount() const;
+    
+    /**
      * 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;
     }
 
     /**
@@ -218,7 +258,7 @@
      * audio data, in all channels.  This may safely be called from a
      * realtime thread.
      */
-    virtual int getSourceSamples(int count, float **buffer);
+    virtual int getSourceSamples(float *const *buffer, int nchannels, int count) override;
 
     /**
      * Set the time stretcher factor (i.e. playback speed).
@@ -226,12 +266,6 @@
     void setTimeStretch(double factor);
 
     /**
-     * Set the resampler quality, 0 - 2 where 0 is fastest and 2 is
-     * highest quality.
-     */
-    void setResampleQuality(int q);
-
-    /**
      * Set a single real-time plugin as a processing effect for
      * auditioning during playback.
      *
@@ -246,7 +280,7 @@
      * Pass a null pointer to remove the current auditioning plugin,
      * if any.
      */
-    void setAuditioningEffect(Auditionable *plugin);
+    virtual void setAuditioningEffect(Auditionable *plugin) override;
 
     /**
      * Specify that only the given set of models should be played.
@@ -259,24 +293,26 @@
      */
     void clearSoloModelSet();
 
-    std::string getClientName() const { return m_clientName; }
+    virtual std::string getClientName() const override {
+        return m_clientName;
+    }
 
 signals:
-    void modelReplaced();
-
     void playStatusChanged(bool isPlaying);
 
     void sampleRateMismatch(sv_samplerate_t requested,
                             sv_samplerate_t available,
                             bool willResample);
 
+    void channelCountIncreased();
+
     void audioOverloadPluginDisabled();
     void audioTimeStretchMultiChannelDisabled();
 
     void activity(QString);
 
 public slots:
-    void audioProcessingOverload();
+    void audioProcessingOverload() override;
 
 protected slots:
     void selectionChanged();
@@ -310,7 +346,8 @@
     int                               m_sourceChannelCount;
     sv_frame_t                        m_blockSize;
     sv_samplerate_t                   m_sourceSampleRate;
-    sv_samplerate_t                   m_targetSampleRate;
+    sv_samplerate_t                   m_deviceSampleRate;
+    int                               m_deviceChannelCount;
     sv_frame_t                        m_playLatency;
     breakfastquay::SystemPlaybackTarget *m_target;
     double                            m_lastRetrievalTimestamp;
@@ -370,7 +407,7 @@
     sv_frame_t mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers);
 
     // Called from getSourceSamples.
-    void applyAuditioningEffect(sv_frame_t count, float **buffers);
+    void applyAuditioningEffect(sv_frame_t count, float *const *buffers);
 
     // Ranges of current selections, if play selection is active
     std::vector<RealTime> m_rangeStarts;
@@ -395,9 +432,7 @@
     QMutex m_mutex;
     QWaitCondition m_condition;
     FillThread *m_fillThread;
-    SRC_STATE *m_converter;
-    int m_resampleQuality;
-    void initialiseConverter();
+    breakfastquay::ResamplerWrapper *m_resamplerWrapper; // I don't own this
 };
 
 #endif