add API to get current MIDI option from an audio/MIDI backend
[ardour.git] / libs / ardour / ardour / audio_backend.h
index f598f1a93a0a2d204144d2744d8eb8aa1b8a414d..4f7a153eec290fce7241109d7bccc76ce5270ac1 100644 (file)
 #include <boost/function.hpp>
 
 #include "ardour/types.h"
+#include "ardour/audioengine.h"
+#include "ardour/port_engine.h"
+#include "ardour/visibility.h"
 
-namespace ARDOUR {
+#ifdef ARDOURBACKEND_DLL_EXPORTS // defined if we are building the ARDOUR Panners DLLs (instead of using them)
+    #define ARDOURBACKEND_API LIBARDOUR_HELPER_DLL_EXPORT
+#else
+    #define ARDOURBACKEND_API LIBARDOUR_HELPER_DLL_IMPORT
+#endif 
+#define ARDOURBACKEND_LOCAL LIBARDOUR_HELPER_DLL_LOCAL
 
-class AudioEngine;
-class PortEngine;
-class PortManager;
+namespace ARDOUR {
 
-class AudioBackend {
+class AudioBackend : public PortEngine {
   public:
 
-    AudioBackend (AudioEngine& e) : engine (e){}
+    AudioBackend (AudioEngine& e) : PortEngine (e), engine (e) {}
     virtual ~AudioBackend () {}
 
     /** Return the name of this backend.
@@ -49,17 +55,6 @@ class AudioBackend {
      */
     virtual std::string name() const = 0;
 
-    /** Return a private, type-free pointer to any data
-     * that might be useful to a concrete implementation
-     */
-    virtual void* private_handle() const = 0;
-
-    /** Return true if the underlying mechanism/API is still available
-     * for us to utilize. return false if some or all of the AudioBackend
-     * API can no longer be effectively used.
-     */
-    virtual bool connected() const = 0;
-
     /** Return true if the callback from the underlying mechanism/API
      * (CoreAudio, JACK, ASIO etc.) occurs in a thread subject to realtime
      * constraints. Return false otherwise.
@@ -228,22 +223,44 @@ class AudioBackend {
     virtual uint32_t     systemic_input_latency () const = 0;
     virtual uint32_t     systemic_output_latency () const = 0;
 
-    /** Return true if it is possible to launch a control app
-     * at this time. Return false otherwise.
-     *
-     * The audio backend may not know the device for which the
-     * control app should be opened, or there may no such
-     * application. In such cases, this method should return false.
+    /** override this if this implementation returns true from
+     * requires_driver_selection()
      */
-    virtual bool have_control_app() const = 0;
+    virtual std::string  driver_name() const { return std::string(); }
 
-    /** If the device name has been set, launch an application (if any exist)
-     * to manage the hardware settings of that device. If no such application
-     * exists, do nothing.
+    /** 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.
+     */
+    virtual std::string control_app_name() const = 0;
+    /** Launch the control app for the currently in-use or
+     * selected device. May do nothing if the control
+     * app is undefined or cannot be launched.
      */
     virtual void launch_control_app () = 0;
 
-    /* Basic state control */
+    /* @return a vector of strings that describe the available
+     * MIDI options. 
+     *
+     * These can be presented to the user to decide which
+     * MIDI drivers, options etc. can be used. The returned strings
+     * should be thought of as the key to a map of possible
+     * approaches to handling MIDI within the backend. Ensure that
+     * the strings will make sense to the user.
+     */
+    virtual std::vector<std::string> enumerate_midi_options () const = 0;
+
+    /* Request the use of the MIDI option named @param option, which
+     * should be one of the strings returned by enumerate_midi_options()
+     *
+     * @return zero if successful, non-zero otherwise
+     */
+    virtual int set_midi_option (const std::string& option) = 0;
+
+    virtual std::string midi_option () const = 0;
+    
+    /* State Control */
 
     /** Start using the device named in the most recent call
      * to set_device(), with the parameters set by various
@@ -403,7 +420,25 @@ class AudioBackend {
      * stacksize. The thread will begin executing @param func, and will exit
      * when that function returns.
      */
-    virtual int create_process_thread (boost::function<void()> func, pthread_t*, size_t stacksize) = 0;
+    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;
+
+    /** Return true if execution context is in a backend thread
+     */
+    virtual bool in_process_thread () = 0;
+
+    /** Return the minimum stack size of audio threads in bytes
+     */
+    static size_t thread_stack_size () { return 100000; }
+
+    /** Return number of processing threads
+     */
+    virtual uint32_t process_thread_count () = 0;
 
     virtual void update_latencies () = 0;
 
@@ -414,11 +449,22 @@ class AudioBackend {
 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
+     */
     int (*deinstantiate) (void);
 
-    boost::shared_ptr<AudioBackend> (*backend_factory) (AudioEngine&);
-    boost::shared_ptr<PortEngine> (*portengine_factory) (PortManager&);
+    /** 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<AudioBackend> (*factory) (AudioEngine&);
 
     /** Return true if the underlying mechanism/API has been
      * configured and does not need (re)configuration in order