add AudioEngine API to configure individual MIDI devices
[ardour.git] / libs / backends / alsa / alsa_audiobackend.h
index 6ad58161f32598d87729dc4e030c5f4c9a6cb7f6..e0d1f114c314410d5aabf52788a6f2052f4873b5 100644 (file)
@@ -30,8 +30,9 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include "ardour/types.h"
 #include "ardour/audio_backend.h"
+#include "ardour/system_exec.h"
+#include "ardour/types.h"
 
 #include "zita-alsa-pcmi.h"
 #include "alsa_rawmidi.h"
@@ -140,10 +141,13 @@ class AlsaMidiPort : public AlsaPort {
                DataType type () const { return DataType::MIDI; };
 
                void* get_buffer (pframes_t nframes);
-               const AlsaMidiBuffer const_buffer () const { return _buffer; }
+               const AlsaMidiBuffer const_buffer () const { return _buffer[_bufperiod]; }
+
+               void next_period() { get_buffer(0); _bufperiod = (_bufperiod + 1) % 2; }
 
        private:
-               AlsaMidiBuffer _buffer;
+               AlsaMidiBuffer _buffer[2];
+               int _bufperiod;
 }; // class AlsaMidiPort
 
 class AlsaAudioBackend : public AudioBackend {
@@ -174,6 +178,8 @@ class AlsaAudioBackend : public AudioBackend {
                int set_output_channels (uint32_t);
                int set_systemic_input_latency (uint32_t);
                int set_systemic_output_latency (uint32_t);
+               int set_systemic_midi_input_latency (std::string const, uint32_t);
+               int set_systemic_midi_output_latency (std::string const, uint32_t);
 
                /* Retrieving parameters */
                std::string  device_name () const;
@@ -184,6 +190,10 @@ class AlsaAudioBackend : public AudioBackend {
                uint32_t     output_channels () const;
                uint32_t     systemic_input_latency () const;
                uint32_t     systemic_output_latency () const;
+               uint32_t     systemic_midi_input_latency (std::string const) const;
+               uint32_t     systemic_midi_output_latency (std::string const) const;
+
+               bool can_set_systemic_midi_latencies () const { return true; }
 
                /* External control app */
                std::string control_app_name () const { return std::string (); }
@@ -194,6 +204,10 @@ class AlsaAudioBackend : public AudioBackend {
                int set_midi_option (const std::string&);
                std::string midi_option () const;
 
+               std::vector<DeviceStatus> enumerate_midi_devices () const;
+               int set_midi_device_enabled (std::string const, bool);
+               bool midi_device_enabled (std::string const) const;
+
                /* State Control */
        protected:
                int _start (bool for_latency_measurement);
@@ -283,25 +297,49 @@ class AlsaAudioBackend : public AudioBackend {
                bool  _run; /* keep going or stop, ardour thread */
                bool  _active; /* is running, process thread */
                bool  _freewheeling;
+               bool  _measure_latency;
 
-               void enumerate_midi_devices (std::vector<std::string> &) const;
                std::string _audio_device;
-               std::string _midi_device;
+               std::string _midi_driver_option;
+
+               /* audio device reservation */
+               ARDOUR::SystemExec *_device_reservation;
+               PBD::ScopedConnectionList _reservation_connection;
+               void reservation_stdout (std::string, size_t);
+               bool acquire_device(const char* device_name);
+               void release_device();
+               bool _reservation_succeeded;
 
+               /* audio settings */
                float  _samplerate;
                size_t _samples_per_period;
                size_t _periods_per_cycle;
-               float  _dsp_load;
                static size_t _max_buffer_size;
 
                uint32_t _n_inputs;
                uint32_t _n_outputs;
 
-               uint32_t _systemic_input_latency;
-               uint32_t _systemic_output_latency;
+               uint32_t _systemic_audio_input_latency;
+               uint32_t _systemic_audio_output_latency;
+
+               /* midi settings */
+               struct AlsaMidiDeviceInfo {
+                       bool     enabled;
+                       uint32_t systemic_input_latency;
+                       uint32_t systemic_output_latency;
+                       AlsaMidiDeviceInfo()
+                               : enabled (true)
+                               , systemic_input_latency (0)
+                               , systemic_output_latency (0)
+                       {}
+               };
 
-               uint64_t _processed_samples;
+               mutable std::map<std::string, struct AlsaMidiDeviceInfo *> _midi_devices;
+               struct AlsaMidiDeviceInfo * midi_device_info(std::string const) const;
 
+               /* processing */
+               float  _dsp_load;
+               uint64_t _processed_samples;
                pthread_t _main_thread;
 
                /* process threads */
@@ -343,6 +381,7 @@ class AlsaAudioBackend : public AudioBackend {
 
                std::vector<PortConnectData *> _port_connection_queue;
                pthread_mutex_t _port_callback_mutex;
+               bool _port_change_flag;
 
                void port_connect_callback (const std::string& a, const std::string& b, bool conn) {
                        pthread_mutex_lock (&_port_callback_mutex);
@@ -350,6 +389,12 @@ class AlsaAudioBackend : public AudioBackend {
                        pthread_mutex_unlock (&_port_callback_mutex);
                }
 
+               void port_connect_add_remove_callback () {
+                       pthread_mutex_lock (&_port_callback_mutex);
+                       _port_change_flag = true;
+                       pthread_mutex_unlock (&_port_callback_mutex);
+               }
+
                bool valid_port (PortHandle port) const {
                        return std::find (_ports.begin (), _ports.end (), (AlsaPort*)port) != _ports.end ();
                }