X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Faudio_backend.h;h=e0e7d8e90404efc02ddbd32f28e3e7c5e5636d23;hb=582138f280b7c7d1620b31b27398459e1be84ae2;hp=cbe0bfce509d8a2891ee80794f0f1093a98ac814;hpb=e466ce40ad1ba591543020cb7c0aa15dbebef81e;p=ardour.git diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h index cbe0bfce50..e0e7d8e904 100644 --- a/libs/ardour/ardour/audio_backend.h +++ b/libs/ardour/ardour/audio_backend.h @@ -28,25 +28,68 @@ #include +#include "ardour/libardour_visibility.h" #include "ardour/types.h" #include "ardour/audioengine.h" #include "ardour/port_engine.h" -#include "ardour/visibility.h" #ifdef ARDOURBACKEND_DLL_EXPORTS // defined if we are building the ARDOUR Panners DLLs (instead of using them) - #define ARDOURBACKEND_API LIBARDOUR_HELPER_DLL_EXPORT + #define ARDOURBACKEND_API LIBARDOUR_DLL_EXPORT #else - #define ARDOURBACKEND_API LIBARDOUR_HELPER_DLL_IMPORT + #define ARDOURBACKEND_API LIBARDOUR_DLL_IMPORT #endif -#define ARDOURBACKEND_LOCAL LIBARDOUR_HELPER_DLL_LOCAL +#define ARDOURBACKEND_LOCAL LIBARDOUR_DLL_LOCAL namespace ARDOUR { -class AudioBackend : public PortEngine { +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); + + /** Release all resources associated with this audiobackend + */ + 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. + */ + boost::shared_ptr (*factory) (AudioEngine&); + + /** Return true if the underlying mechanism/API has been + * configured and does not need (re)configuration in order + * to be usable. Return false otherwise. + * + * Note that this may return true if (re)configuration, even though + * not currently required, is still possible. + */ + bool (*already_configured)(); + + /** Return true if the underlying mechanism/API can be + * used on the given system. + * + * If this function returns false, the backend is not + * listed in the engine dialog. + */ + bool (*available)(); +}; + +class LIBARDOUR_API AudioBackend : public PortEngine { public: - AudioBackend (AudioEngine& e) : PortEngine (e), engine (e) {} + AudioBackend (AudioEngine& e, AudioBackendInfo& i) : PortEngine (e), _info (i), engine (e) {} virtual ~AudioBackend () {} + + /** Return the AudioBackendInfo object from which this backend + was constructed. + */ + AudioBackendInfo& info() const { return _info; } /** Return the name of this backend. * @@ -117,6 +160,17 @@ class AudioBackend : public PortEngine { * at any time. */ virtual std::vector available_sample_rates (const std::string& device) const = 0; + + /* Returns the default sample rate that will be shown to the user when + * configuration options are first presented. If the derived class + * needs or wants to override this, it can. It also MUST override this + * if there is any chance that an SR of 44.1kHz is not in the list + * returned by available_sample_rates() + */ + virtual float default_sample_rate () const { + return 44100.0; + } + /** Returns a collection of uint32 identifying buffer sizes that are * potentially usable with the hardware identified by @param device. * Any of these values may be supplied in other calls to this backend @@ -126,6 +180,16 @@ class AudioBackend : public PortEngine { */ virtual std::vector available_buffer_sizes (const std::string& device) const = 0; + /* Returns the default buffer size that will be shown to the user when + * configuration options are first presented. If the derived class + * needs or wants to override this, it can. It also MUST override this + * if there is any chance that a buffer size of 1024 is not in the list + * returned by available_buffer_sizes() + */ + virtual uint32_t default_buffer_size (const std::string& device) const { + return 1024; + } + /** Returns the maximum number of input channels that are potentially * usable with the hardware identified by @param device. Any number from 1 * to the value returned may be supplied in other calls to this backend as @@ -167,6 +231,9 @@ class AudioBackend : public PortEngine { /** Set the name of the device to be used */ virtual int set_device_name (const std::string&) = 0; + /** Deinitialize and destroy current device + */ + virtual int drop_device() {return 0;}; /** Set the sample rate to be used */ virtual int set_sample_rate (float) = 0; @@ -179,12 +246,6 @@ class AudioBackend : public PortEngine { * doesn't directly expose the concept). */ virtual int set_buffer_size (uint32_t) = 0; - /** Set the preferred underlying hardware sample format - * - * This does not change the sample format (32 bit float) read and - * written to the device via the Port API. - */ - virtual int set_sample_format (SampleFormat) = 0; /** Set the preferred underlying hardware data layout. * If @param yn is true, then the hardware will interleave * samples for successive channels; otherwise, the hardware will store @@ -210,18 +271,27 @@ class AudioBackend : public PortEngine { * external D-A/D-A converters. Units are samples. */ virtual int set_systemic_output_latency (uint32_t) = 0; + /** Set the (additional) input latency for a specific midi device, + * or if the identifier is empty, apply to all midi devices. + */ + virtual int set_systemic_midi_input_latency (std::string const, uint32_t) = 0; + /** Set the (additional) output latency for a specific midi device, + * or if the identifier is empty, apply to all midi devices. + */ + virtual int set_systemic_midi_output_latency (std::string const, uint32_t) = 0; /* Retrieving parameters */ virtual std::string device_name () const = 0; virtual float sample_rate () const = 0; virtual uint32_t buffer_size () const = 0; - virtual SampleFormat sample_format () const = 0; virtual bool interleaved () const = 0; virtual uint32_t input_channels () const = 0; virtual uint32_t output_channels () const = 0; virtual uint32_t systemic_input_latency () const = 0; 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; /** override this if this implementation returns true from * requires_driver_selection() @@ -259,19 +329,21 @@ class AudioBackend : public PortEngine { virtual int set_midi_option (const std::string& option) = 0; virtual std::string midi_option () const = 0; - - /* State Control */ - /* non-virtual method to avoid possible overrides of default - * parameters. See Scott Meyers or other books on C++ to - * understand 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); - } + /** Detailed MIDI device list - if available */ + virtual std::vector enumerate_midi_devices () const = 0; + + /** mark a midi-devices as enabled */ + virtual int set_midi_device_enabled (std::string const, bool) = 0; + + /** query if a midi-device is enabled */ + virtual bool midi_device_enabled (std::string const) const = 0; + /** if backend supports systemic_midi_[in|ou]tput_latency() */ + 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. @@ -287,8 +359,24 @@ class AudioBackend : public PortEngine { * any existing systemic latency settings. * * Return zero if successful, negative values otherwise. - */ - virtual int _start (bool for_latency_measurement) = 0; + * + * + * + * + * Why is this non-virtual but ::_start() is virtual ? + * Virtual methods with default parameters create possible ambiguity + * because a derived class may implement the same method with a different + * type or value of default parameter. + * + * So we make this non-virtual method to avoid possible overrides of + * default parameters. See Scott Meyers or other books on C++ to understand + * 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. * @@ -306,19 +394,11 @@ class AudioBackend : public PortEngine { */ virtual int stop () = 0; - /** Temporarily cease using the device named in the most recent call to set_parameters(). + /** Reset device. * - * If the function is successfully called, no subsequent calls to the - * process_callback() of @param engine will be made after the function - * returns, until start() is called again. - * - * The backend will retain its existing parameter configuration after a successful - * return, and does NOT require any calls to set hardware parameters before it can be - * start()-ed again. - * - * Return zero if successful, 1 if the device is not in use, negative values on error + * Return zero if successful, negative values on error */ - virtual int pause () = 0; + virtual int reset_device() = 0; /** While remaining connected to the device, and without changing its * configuration, start (or stop) calling the process_callback() of @param engine @@ -348,7 +428,7 @@ class AudioBackend : public PortEngine { * Implementations can feel free to smooth the values returned over * time (e.g. high pass filtering, or its equivalent). */ - virtual float cpu_load() const = 0; + virtual float dsp_load() const = 0; /* Transport Control (JACK is the only audio API that currently offers the concept of shared transport control) @@ -397,12 +477,12 @@ class AudioBackend : public PortEngine { * * Can be called from any thread. */ - virtual pframes_t sample_time () = 0; + virtual framepos_t sample_time () = 0; /** Return the time according to the sample clock in use when the most * recent buffer process cycle began. Can be called from any thread. */ - virtual pframes_t sample_time_at_cycle_start () = 0; + virtual framepos_t sample_time_at_cycle_start () = 0; /** Return the time since the current buffer process cycle started, * in samples, according to the sample clock in use. @@ -457,38 +537,26 @@ class AudioBackend : public PortEngine { virtual void update_latencies () = 0; - protected: - AudioEngine& engine; -}; - -struct 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); - - /** Release all resources associated with this audiobackend + /** Set @param speed and @param position to the current speed and position + * indicated by some transport sync signal. Return whether the current + * transport state is pending, or finalized. + * + * Derived classes only need implement this if they provide some way to + * sync to a transport sync signal (e.g. Sony 9 Pin) that is not + * handled by Ardour itself (LTC and MTC are both handled by Ardour). + * The canonical example is JACK Transport. */ - int (*deinstantiate) (void); + virtual bool speed_and_position (double& speed, framepos_t& position) { + speed = 0.0; + position = 0; + return false; + } - /** Factory method to create an AudioBackend-derived class. - * - * Returns a valid shared_ptr to the object if successfull, - * or a "null" shared_ptr otherwise. - */ - boost::shared_ptr (*factory) (AudioEngine&); + protected: + AudioBackendInfo& _info; + AudioEngine& engine; - /** Return true if the underlying mechanism/API has been - * configured and does not need (re)configuration in order - * to be usable. Return false otherwise. - * - * Note that this may return true if (re)configuration, even though - * not currently required, is still possible. - */ - bool (*already_configured)(); + virtual int _start (bool for_latency_measurement) = 0; }; } // namespace