8a6973890932 — Chris Cannam 3 years ago
Docs
2 files changed, 97 insertions(+), 20 deletions(-)

M bqaudioio/AudioFactory.h
M bqaudioio/ResamplerWrapper.h
M bqaudioio/AudioFactory.h +64 -13
@@ 51,26 51,77 @@ public:
     static std::vector<std::string> getRecordDeviceNames(std::string implName);
     static std::vector<std::string> getPlaybackDeviceNames(std::string implName);
 
+    /**
+     * Preferences for implementation (i.e. audio driver layer) and
+     * audio device.
+     *
+     * Wherever a non-empty string is provided, then it will be used
+     * by the factory; if the factory can't open the requested driver,
+     * or select a requested device, creation will fail.
+     *
+     * Wherever an empty string is provided, the driver will make an
+     * automatic selection and may potentially try more than one
+     * implementation or device if its first choice can't be used.
+     */
     struct Preference {
-        // In all cases an empty string indicates "choose
-        // automatically". This may not be the same as any individual
-        // preference, because it implies potentially trying more than
-        // one implementation if the first doesn't work
         std::string implementation;
         std::string recordDevice;
         std::string playbackDevice;
         Preference() { }
     };
-    
-    static SystemRecordSource *createCallbackRecordSource(ApplicationRecordTarget *,
-                                                          Preference);
+
+    /**
+     * Open the audio driver for duplex (i.e recording + playback) I/O
+     * using the given driver and device preferences. Provide the
+     * given record target and play source objects to the audio I/O
+     * and return the new audio I/O.
+     *
+     * Caller owns the returned object and must delete it when
+     * done. Note that the record target and playback source must
+     * outlive the returned IO object.
+     *
+     * Return a null pointer if the requested device could not be
+     * opened, or, in the case where no preference was stated, if no
+     * device could be opened.
+     */
+    static SystemAudioIO *
+    createCallbackIO(ApplicationRecordTarget *,
+                     ApplicationPlaybackSource *,
+                     Preference);
+
+    /**
+     * Open the audio driver in record-only mode using the given
+     * driver and device preferences. Provide the given record target
+     * to the audio source and return the new audio source.
+     *
+     * Caller owns the returned object and must delete it when
+     * done. Note that the record target must outlive the returned
+     * source object.
+     *
+     * Return a null pointer if the requested device could not be
+     * opened, or, in the case where no preference was stated, if no
+     * device could be opened.
+     */
+    static SystemRecordSource *
+    createCallbackRecordSource(ApplicationRecordTarget *,
+                               Preference);
     
-    static SystemPlaybackTarget *createCallbackPlayTarget(ApplicationPlaybackSource *,
-                                                          Preference);
-    
-    static SystemAudioIO *createCallbackIO(ApplicationRecordTarget *,
-                                           ApplicationPlaybackSource *,
-                                           Preference);
+    /**
+     * Open the audio driver in playback-only mode using the given
+     * driver and device preferences. Provide the given playback
+     * source to the audio source and return the new audio target.
+     *
+     * Caller owns the returned object and must delete it when
+     * done. Note that the playback source must outlive the returned
+     * target object.
+     *
+     * Return a null pointer if the requested device could not be
+     * opened, or, in the case where no preference was stated, if no
+     * device could be opened.
+     */
+    static SystemPlaybackTarget *
+    createCallbackPlayTarget(ApplicationPlaybackSource *,
+                             Preference);
 
 private:
     AudioFactory(const AudioFactory &)=delete;

          
M bqaudioio/ResamplerWrapper.h +33 -7
@@ 39,6 39,24 @@ namespace breakfastquay {
 
 class Resampler;
 
+/**
+ * Utility class for applications that want automatic sample rate
+ * conversion on playback (resampling on record is not provided).
+ *
+ * An ApplicationPlaybackSource may request a specific sample rate
+ * through its getApplicationSampleRate callback. This will be used as
+ * the default rate when opening the audio driver. However, not all
+ * drivers can be opened at arbitrary rates (e.g. a JACK driver always
+ * inherits the JACK graph sample rate), so it's possible that a
+ * driver may be opened at a different rate from that requested by the
+ * source.
+ *
+ * An application can accommodate this by wrapping its
+ * ApplicationPlaybackSource in a ResamplerWrapper when passing it to
+ * the AudioFactory. The ResamplerWrapper will automatically resample
+ * output if the driver happened to be opened at a different rate from
+ * that requested by the source.
+ */
 class ResamplerWrapper : public ApplicationPlaybackSource
 {
 public:

          
@@ 49,16 67,17 @@ public:
      * target's expected sample rate automatically.
      */
     ResamplerWrapper(ApplicationPlaybackSource *source);
+
     ~ResamplerWrapper();
 
     /**
-     * Call this (e.g. from the wrapped ApplicationPlaybackSource) to
-     * indicate a change in the sample rate that we should be
-     * resampling from.
+     * Call this function (e.g. from the wrapped
+     * ApplicationPlaybackSource) to indicate a change in the sample
+     * rate that we should be resampling from.
      *
      * (The wrapped ApplicationPlaybackSource should not change the
      * value it returns from getApplicationSampleRate(), as the API
-     * requires that this be fixed.)
+     * requires that that be fixed.)
      */
     void changeApplicationSampleRate(int newRate);
 

          
@@ 67,8 86,10 @@ public:
      */
     void reset();
     
+    // These functions are passed through to the wrapped
+    // ApplicationPlaybackSource
+    
     virtual std::string getClientName() const;
-    
     virtual int getApplicationSampleRate() const;
     virtual int getApplicationChannelCount() const;
 

          
@@ 77,11 98,16 @@ public:
     virtual void setSystemPlaybackChannelCount(int);
     virtual void setSystemPlaybackLatency(int);
 
-    virtual int getSourceSamples(float *const *samples, int nchannels, int nframes);
-
     virtual void setOutputLevels(float peakLeft, float peakRight);
     virtual void audioProcessingOverload();
 
+    /** 
+     * Request some samples from the wrapped
+     * ApplicationPlaybackSource, resample them if necessary, and
+     * return them to the target
+     */
+    virtual int getSourceSamples(float *const *samples, int nchannels, int nframes);
+
 private:
     ApplicationPlaybackSource *m_source;