add initial midi sidechain if plugin has one.
[ardour.git] / libs / ardour / ardour / audio_backend.h
index 2bbd891e989aff1991cbf08c62e1468873f8336e..9a00cf281ee11b259c619069b484bf28e420d2d8 100644 (file)
@@ -37,7 +37,7 @@
     #define ARDOURBACKEND_API LIBARDOUR_DLL_EXPORT
 #else
     #define ARDOURBACKEND_API LIBARDOUR_DLL_IMPORT
-#endif 
+#endif
 #define ARDOURBACKEND_LOCAL LIBARDOUR_DLL_LOCAL
 
 namespace ARDOUR {
@@ -46,7 +46,7 @@ struct LIBARDOUR_API AudioBackendInfo {
     const char* name;
 
     /** Using arg1 and arg2, initialize this audiobackend.
-     * 
+     *
      * Returns zero on success, non-zero otherwise.
      */
     int (*instantiate) (const std::string& arg1, const std::string& arg2);
@@ -56,7 +56,7 @@ struct LIBARDOUR_API AudioBackendInfo {
     int (*deinstantiate) (void);
 
     /** Factory method to create an AudioBackend-derived class.
-     * 
+     *
      * Returns a valid shared_ptr to the object if successfull,
      * or a "null" shared_ptr otherwise.
      */
@@ -80,18 +80,23 @@ struct LIBARDOUR_API AudioBackendInfo {
     bool (*available)();
 };
 
+/** AudioBackend is an high-level abstraction for interacting with the operating system's
+ * audio and midi I/O.
+ */
 class LIBARDOUR_API AudioBackend : public PortEngine {
   public:
 
     AudioBackend (AudioEngine& e, AudioBackendInfo& i) : PortEngine (e), _info (i), engine (e) {}
     virtual ~AudioBackend () {}
-    
+
        enum ErrorCode {
                NoError = 0,
                BackendInitializationError = -64,
                BackendDeinitializationError,
+               BackendReinitializationError,
                AudioDeviceOpenError,
                AudioDeviceCloseError,
+               AudioDeviceInvalidError,
                AudioDeviceNotAvailableError,
                AudioDeviceNotConnectedError,
                AudioDeviceReservationError,
@@ -101,17 +106,24 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
                MidiDeviceNotAvailableError,
                MidiDeviceNotConnectedError,
                MidiDeviceIOError,
+               SampleFormatNotSupportedError,
                SampleRateNotSupportedError,
                RequestedInputLatencyNotSupportedError,
                RequestedOutputLatencyNotSupportedError,
                PeriodSizeNotSupportedError,
                PeriodCountNotSupportedError,
                DeviceConfigurationNotSupportedError,
+               ChannelCountNotSupportedError,
                InputChannelCountNotSupportedError,
                OutputChannelCountNotSupportedError,
                AquireRealtimePermissionError,
                SettingAudioThreadPriorityError,
-               SettingMIDIThreadPriorityError
+               SettingMIDIThreadPriorityError,
+               ProcessThreadStartError,
+               FreewheelThreadStartError,
+               PortRegistrationError,
+               PortReconnectError,
+               OutOfMemoryError,
        };
 
        static std::string get_error_string (ErrorCode);
@@ -147,7 +159,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
      * before any device can be selected. Return false otherwise.
      *
      * Intended mainly to differentiate between meta-APIs like JACK
-     * which can still expose different backends (such as ALSA or CoreAudio 
+     * which can still expose different backends (such as ALSA or CoreAudio
      * or FFADO or netjack) and those like ASIO or CoreAudio which
      * do not.
      */
@@ -171,7 +183,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     virtual int set_driver (const std::string& /*drivername*/) { return 0; }
 
     /** used to list device names along with whether or not they are currently
-     *  available. 
+     *  available.
     */
     struct DeviceStatus {
        std::string name;
@@ -219,6 +231,53 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     virtual std::vector<DeviceStatus> enumerate_output_devices () const
     { return std::vector<DeviceStatus>(); }
 
+
+       /** An interface to set buffers/period for playback latency.
+        * useful for ALSA or JACK/ALSA on Linux.
+        *
+        * @return true if the backend supports period-size configuration
+        */
+       virtual bool can_set_period_size () const { return false; }
+
+       /** Returns a vector of supported period-sizes for the given driver */
+       virtual std::vector<uint32_t> available_period_sizes (const std::string& driver) const { return std::vector<uint32_t>(); }
+
+       /** Set the period size to be used.
+        * must be called before starting the backend.
+        */
+       virtual int set_peridod_size (uint32_t) { return -1; }
+
+       /**
+        * @return true if backend supports requesting an update to the device list
+        * and any cached properties associated with the devices.
+        */
+       virtual bool can_request_update_devices () { return false; }
+
+       /**
+        * Request an update to the list of devices returned in the enumerations.
+        * The Backend must return true from can_request_update_devices to support
+        * this interface.
+        * @return true if the devices were updated
+        */
+       virtual bool update_devices () { return false; }
+
+       /**
+        * @return true if backend supports a blocking or buffered mode, false by
+        * default unless implemented by a derived class.
+        */
+       virtual bool can_use_buffered_io () { return false; }
+
+       /**
+        * Set the backend to use a blocking or buffered I/O mode
+        */
+       virtual void set_use_buffered_io (bool) { }
+
+       /**
+        * @return Set the backend to use a blocking or buffered I/O mode, false by
+        * default unless implemented by a derived class.
+        */
+       virtual bool get_use_buffered_io () { return false; }
+
     /** Returns a collection of float identifying sample rates that are
      * potentially usable with the hardware identified by @param device.
      * Any of these values may be supplied in other calls to this backend
@@ -307,12 +366,17 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     virtual bool can_change_sample_rate_when_running () const = 0;
     /* Return true if the derived class can change the buffer size of the
      * device in use while the device is already being used. Return false
-     * otherwise. 
+     * otherwise.
      */
     virtual bool can_change_buffer_size_when_running () const = 0;
 
+               /** return true if the backend can measure and update
+                * systemic latencies without restart.
+                */
+               virtual bool can_change_systemic_latency_when_running () const { return false; }
+
     /* Set the hardware parameters.
-     * 
+     *
      * If called when the current state is stopped or paused,
      * the changes will not take effect until the state changes to running.
      *
@@ -359,7 +423,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
      * If @param yn is true, then the hardware will interleave
      * samples for successive channels; otherwise, the hardware will store
      * samples for a single channel contiguously.
-     * 
+     *
      * Setting this does not change the fact that all data streams
      * to and from Ports are mono (essentially, non-interleaved)
      */
@@ -370,12 +434,12 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     /** Set the number of output channels that should be used
      */
     virtual int set_output_channels (uint32_t) = 0;
-    /** Set the (additional) input latency that cannot be determined via 
+    /** Set the (additional) input latency that cannot be determined via
      * the implementation's underlying code (e.g. latency from
      * external D-A/D-A converters. Units are samples.
      */
     virtual int set_systemic_input_latency (uint32_t) = 0;
-    /** Set the (additional) output latency that cannot be determined via 
+    /** Set the (additional) output latency that cannot be determined via
      * the implementation's underlying code (e.g. latency from
      * external D-A/D-A converters. Units are samples.
      */
@@ -403,13 +467,14 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     virtual uint32_t     systemic_output_latency () const = 0;
     virtual uint32_t     systemic_midi_input_latency (std::string const) const = 0;
     virtual uint32_t     systemic_midi_output_latency (std::string const) const = 0;
+    virtual uint32_t     period_size () const { return 0; }
 
     /** override this if this implementation returns true from
      * requires_driver_selection()
      */
     virtual std::string  driver_name() const { return std::string(); }
 
-    /** Return the name of a control application for the 
+    /** Return the name of a control application for the
      * selected/in-use device. If no such application exists,
      * or if no device has been selected or is in-use,
      * return an empty string.
@@ -422,7 +487,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     virtual void launch_control_app () = 0;
 
     /* @return a vector of strings that describe the available
-     * MIDI options. 
+     * MIDI options.
      *
      * These can be presented to the user to decide which
      * MIDI drivers, options etc. can be used. The returned strings
@@ -454,11 +519,11 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     virtual bool can_set_systemic_midi_latencies () const = 0;
 
     /* State Control */
+
     /** Start using the device named in the most recent call
      * to set_device(), with the parameters set by various
      * the most recent calls to set_sample_rate() etc. etc.
-     * 
+     *
      * At some undetermined time after this function is successfully called,
      * the backend will start calling the ::process_callback() method of
      * the AudioEngine referenced by @param engine. These calls will
@@ -484,28 +549,28 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
      * this pattern, or possibly just this:
      *
      * http://stackoverflow.com/questions/12139786/good-pratice-default-arguments-for-pure-virtual-method
-     */ 
+     */
     int start (bool for_latency_measurement=false) {
            return _start (for_latency_measurement);
     }
 
-    /** Stop using the device currently in use. 
+    /** Stop using the device currently in use.
      *
      * If the function is successfully called, no subsequent calls to the
      * process_callback() of @param engine will be made after the function
      * returns, until parameters are reset and start() are called again.
-     * 
+     *
      * The backend is considered to be un-configured after a successful
      * return, and requires calls to set hardware parameters before it can be
      * start()-ed again. See pause() for a way to avoid this. stop() should
-     * only be used when reconfiguration is required OR when there are no 
+     * only be used when reconfiguration is required OR when there are no
      * plans to use the backend in the future with a reconfiguration.
      *
      * Return zero if successful, 1 if the device is not in use, negative values on error
      */
     virtual int stop () = 0;
 
-        /** Reset device. 
+        /** Reset device.
      *
      * Return zero if successful, negative values on error
      */
@@ -534,8 +599,8 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
      * from 0.0 to 1.0
      *
      * E.g. if the buffer size represents 5msec and current processing
-     * takes 1msec, the returned value should be 0.2. 
-     * 
+     * takes 1msec, the returned value should be 0.2.
+     *
      * Implementations can feel free to smooth the values returned over
      * time (e.g. high pass filtering, or its equivalent).
      */
@@ -544,11 +609,11 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     /* Transport Control (JACK is the only audio API that currently offers
        the concept of shared transport control)
     */
-    
-    /** Attempt to change the transport state to TransportRolling. 
+
+    /** Attempt to change the transport state to TransportRolling.
      */
     virtual void transport_start () {}
-    /** Attempt to change the transport state to TransportStopped. 
+    /** Attempt to change the transport state to TransportStopped.
      */
     virtual void transport_stop () {}
     /** return the current transport state
@@ -566,7 +631,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
      * timebase, otherwise cease to be the time master for the same.
      *
      * Return zero on success, non-zero otherwise
-     * 
+     *
      * JACK is the only currently known audio API with the concept of a shared
      * transport timebase.
      */
@@ -574,16 +639,16 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
 
     virtual int        usecs_per_cycle () const { return 1000000 * (buffer_size() / sample_rate()); }
     virtual size_t     raw_buffer_size (DataType t) = 0;
-    
+
     /* Process time */
-    
+
     /** return the time according to the sample clock in use, measured in
      * samples since an arbitrary zero time in the past. The value should
      * increase monotonically and linearly, without interruption from any
      * source (including CPU frequency scaling).
      *
      * It is extremely likely that any implementation will use a DLL, since
-     * this function can be called from any thread, at any time, and must be 
+     * this function can be called from any thread, at any time, and must be
      * able to accurately determine the correct sample time.
      *
      * Can be called from any thread.
@@ -597,7 +662,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
 
     /** Return the time since the current buffer process cycle started,
      * in samples, according to the sample clock in use.
-     * 
+     *
      * Can ONLY be called from within a process() callback tree (which
      * implies that it can only be called by a process thread)
      */
@@ -629,7 +694,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
     virtual int create_process_thread (boost::function<void()> func) = 0;
 
     /** Wait for all processing threads to exit.
-     * 
+     *
      * Return zero on success, non-zero on failure.
      */
     virtual int join_process_threads () = 0;
@@ -664,7 +729,7 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
      }
 
   protected:
-     AudioBackendInfo&  _info; 
+     AudioBackendInfo&  _info;
      AudioEngine&        engine;
 
      virtual int _start (bool for_latency_measurement) = 0;
@@ -673,4 +738,4 @@ class LIBARDOUR_API AudioBackend : public PortEngine {
 } // namespace
 
 #endif /* __libardour_audiobackend_h__ */
-    
+