diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h index 78e3903182..bf860e9aeb 100644 --- a/libs/ardour/ardour/audio_backend.h +++ b/libs/ardour/ardour/audio_backend.h @@ -263,6 +263,14 @@ class LIBARDOUR_API 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 */ @@ -274,6 +282,8 @@ class LIBARDOUR_API AudioBackend : public PortEngine { 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() @@ -311,7 +321,19 @@ class LIBARDOUR_API AudioBackend : public PortEngine { virtual int set_midi_option (const std::string& option) = 0; virtual std::string midi_option () const = 0; - + + /** 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 diff --git a/libs/backends/alsa/alsa_audiobackend.cc b/libs/backends/alsa/alsa_audiobackend.cc index ad50d5fe2c..1b8f6ca7d1 100644 --- a/libs/backends/alsa/alsa_audiobackend.cc +++ b/libs/backends/alsa/alsa_audiobackend.cc @@ -45,19 +45,18 @@ AlsaAudioBackend::AlsaAudioBackend (AudioEngine& e, AudioBackendInfo& info) , _run (false) , _active (false) , _freewheeling (false) + , _measure_latency (false) , _audio_device("") - , _midi_device("") + , _midi_driver_option("") , _device_reservation(0) , _samplerate (48000) , _samples_per_period (1024) , _periods_per_cycle (2) - , _dsp_load (0) , _n_inputs (0) , _n_outputs (0) , _systemic_audio_input_latency (0) , _systemic_audio_output_latency (0) - , _systemic_midi_input_latency (0) - , _systemic_midi_output_latency (0) + , _dsp_load (0) , _processed_samples (0) , _port_change_flag (false) { @@ -281,7 +280,6 @@ int AlsaAudioBackend::set_systemic_input_latency (uint32_t sl) { _systemic_audio_input_latency = sl; - _systemic_midi_input_latency = sl; return 0; } @@ -289,7 +287,24 @@ int AlsaAudioBackend::set_systemic_output_latency (uint32_t sl) { _systemic_audio_output_latency = sl; - _systemic_midi_output_latency = sl; + return 0; +} + +int +AlsaAudioBackend::set_systemic_midi_input_latency (std::string const device, uint32_t sl) +{ + struct AlsaMidiDeviceInfo * nfo = midi_device_info(device); + if (!nfo) return -1; + nfo->systemic_input_latency = sl; + return 0; +} + +int +AlsaAudioBackend::set_systemic_midi_output_latency (std::string const device, uint32_t sl) +{ + struct AlsaMidiDeviceInfo * nfo = midi_device_info(device); + if (!nfo) return -1; + nfo->systemic_output_latency = sl; return 0; } @@ -342,11 +357,47 @@ AlsaAudioBackend::systemic_output_latency () const return _systemic_audio_output_latency; } +uint32_t +AlsaAudioBackend::systemic_midi_input_latency (std::string const device) const +{ + struct AlsaMidiDeviceInfo * nfo = midi_device_info(device); + if (!nfo) return 0; + return nfo->systemic_input_latency; +} + +uint32_t +AlsaAudioBackend::systemic_midi_output_latency (std::string const device) const +{ + struct AlsaMidiDeviceInfo * nfo = midi_device_info(device); + if (!nfo) return 0; + return nfo->systemic_output_latency; +} + /* MIDI */ +struct AlsaAudioBackend::AlsaMidiDeviceInfo * +AlsaAudioBackend::midi_device_info(std::string const name) const { + for (std::map::const_iterator i = _midi_devices.begin (); i != _midi_devices.end(); ++i) { + if (i->first == name) { + return (i->second); + } + } + + std::map devices; + get_alsa_rawmidi_device_names(devices); + for (std::map::const_iterator i = devices.begin (); i != devices.end(); ++i) { + if (i->first == name) { + _midi_devices[name] = new AlsaMidiDeviceInfo(); + return _midi_devices[name]; + } + } + return 0; +} + std::vector AlsaAudioBackend::enumerate_midi_options () const { std::vector m; +#if 1 // OLD GUI m.push_back (_("-None-")); std::map devices; get_alsa_rawmidi_device_names(devices); @@ -357,20 +408,55 @@ AlsaAudioBackend::enumerate_midi_options () const if (m.size() > 2) { m.push_back (_("-All-")); } +#else + m.push_back (_("None")); + m.push_back (_("ALSA raw devices")); +#endif return m; } +std::vector +AlsaAudioBackend::enumerate_midi_devices () const +{ + std::vector s; + + std::map devices; + get_alsa_rawmidi_device_names(devices); + + for (std::map::const_iterator i = devices.begin (); i != devices.end(); ++i) { + s.push_back (DeviceStatus (i->first, true)); + } + return s; +} + int AlsaAudioBackend::set_midi_option (const std::string& opt) { - _midi_device = opt; + _midi_driver_option = opt; return 0; } std::string AlsaAudioBackend::midi_option () const { - return _midi_device; + return _midi_driver_option; +} + +int +AlsaAudioBackend::set_midi_device_enabled (std::string const device, bool enable) +{ + struct AlsaMidiDeviceInfo * nfo = midi_device_info(device); + if (!nfo) return -1; + nfo->enabled = enable; + return 0; +} + +bool +AlsaAudioBackend::midi_device_enabled (std::string const device) const +{ + struct AlsaMidiDeviceInfo * nfo = midi_device_info(device); + if (!nfo) return false; + return nfo->enabled; } /* State Control */ @@ -472,12 +558,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement) PBD::warning << _("AlsaAudioBackend: sample rate does not match.") << endmsg; } - if (for_latency_measurement) { - _systemic_audio_input_latency = 0; - _systemic_audio_output_latency = 0; - _systemic_midi_input_latency = 0; - _systemic_midi_output_latency = 0; - } + _measure_latency = for_latency_measurement; register_system_midi_ports(); @@ -849,7 +930,7 @@ AlsaAudioBackend::register_system_audio_ports() const int a_out = _n_outputs > 0 ? _n_outputs : 2; /* audio ports */ - lr.min = lr.max = _samples_per_period + _systemic_audio_input_latency; + lr.min = lr.max = _samples_per_period + _measure_latency ? 0 : _systemic_audio_input_latency; for (int i = 1; i <= a_ins; ++i) { char tmp[64]; snprintf(tmp, sizeof(tmp), "system:capture_%d", i); @@ -859,7 +940,7 @@ AlsaAudioBackend::register_system_audio_ports() _system_inputs.push_back(static_cast(p)); } - lr.min = lr.max = _samples_per_period + _systemic_audio_output_latency; + lr.min = lr.max = _samples_per_period + _measure_latency ? 0 : _systemic_audio_output_latency; for (int i = 1; i <= a_out; ++i) { char tmp[64]; snprintf(tmp, sizeof(tmp), "system:playback_%d", i); @@ -877,10 +958,11 @@ AlsaAudioBackend::register_system_midi_ports() LatencyRange lr; std::vector devices; - if (_midi_device == _("-None-")) { + // TODO new API use midi_device_info(); + if (_midi_driver_option == _("-None-")) { return 0; } - else if (_midi_device == _("-All-")) { + else if (_midi_driver_option == _("-All-")) { std::map devmap; get_alsa_rawmidi_device_names(devmap); for (std::map::const_iterator i = devmap.begin (); i != devmap.end(); ++i) { @@ -890,7 +972,7 @@ AlsaAudioBackend::register_system_midi_ports() std::map devmap; get_alsa_rawmidi_device_names(devmap); for (std::map::const_iterator i = devmap.begin (); i != devmap.end(); ++i) { - if (i->first == _midi_device) { + if (i->first == _midi_driver_option) { devices.push_back (i->second); break; } @@ -941,7 +1023,7 @@ AlsaAudioBackend::register_system_midi_ports() const int m_ins = _rmidi_in.size(); const int m_out = _rmidi_out.size(); - lr.min = lr.max = _samples_per_period + _systemic_midi_input_latency; + lr.min = lr.max = _samples_per_period; // + _systemic_midi_input_latency; for (int i = 1; i <= m_ins; ++i) { char tmp[64]; snprintf(tmp, sizeof(tmp), "system:midi_capture_%d", i); @@ -951,7 +1033,7 @@ AlsaAudioBackend::register_system_midi_ports() _system_midi_in.push_back(static_cast(p)); } - lr.min = lr.max = _samples_per_period + _systemic_midi_output_latency; + lr.min = lr.max = _samples_per_period; // + _systemic_midi_output_latency; for (int i = 1; i <= m_out; ++i) { char tmp[64]; snprintf(tmp, sizeof(tmp), "system:midi_playback_%d", i); diff --git a/libs/backends/alsa/alsa_audiobackend.h b/libs/backends/alsa/alsa_audiobackend.h index 1f6c3d3400..e0d1f114c3 100644 --- a/libs/backends/alsa/alsa_audiobackend.h +++ b/libs/backends/alsa/alsa_audiobackend.h @@ -178,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; @@ -188,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 (); } @@ -198,6 +204,10 @@ class AlsaAudioBackend : public AudioBackend { int set_midi_option (const std::string&); std::string midi_option () const; + std::vector 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); @@ -287,10 +297,10 @@ 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 &) const; std::string _audio_device; - std::string _midi_device; + std::string _midi_driver_option; /* audio device reservation */ ARDOUR::SystemExec *_device_reservation; @@ -300,10 +310,10 @@ class AlsaAudioBackend : public AudioBackend { 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; @@ -311,11 +321,25 @@ class AlsaAudioBackend : public AudioBackend { uint32_t _systemic_audio_input_latency; uint32_t _systemic_audio_output_latency; - uint32_t _systemic_midi_input_latency; - uint32_t _systemic_midi_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) + {} + }; + + mutable std::map _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 */ diff --git a/libs/backends/dummy/dummy_audiobackend.h b/libs/backends/dummy/dummy_audiobackend.h index b8069ee429..d4732f5eeb 100644 --- a/libs/backends/dummy/dummy_audiobackend.h +++ b/libs/backends/dummy/dummy_audiobackend.h @@ -171,6 +171,8 @@ class DummyAudioBackend : 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) { return 0; } + int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; } /* Retrieving parameters */ std::string device_name () const; @@ -181,6 +183,8 @@ class DummyAudioBackend : 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 { return 0; } + uint32_t systemic_midi_output_latency (std::string const) const { return 0; } /* External control app */ std::string control_app_name () const { return std::string (); } @@ -191,6 +195,19 @@ class DummyAudioBackend : public AudioBackend { int set_midi_option (const std::string&); std::string midi_option () const; + std::vector enumerate_midi_devices () const { + return std::vector (); + } + int set_midi_device_enabled (std::string const, bool) { + return 0; + } + bool midi_device_enabled (std::string const) const { + return true; + } + bool can_set_systemic_midi_latencies () const { + return false; + } + /* State Control */ protected: int _start (bool for_latency_measurement); diff --git a/libs/backends/jack/jack_audiobackend.h b/libs/backends/jack/jack_audiobackend.h index 52edd55c63..000a348161 100644 --- a/libs/backends/jack/jack_audiobackend.h +++ b/libs/backends/jack/jack_audiobackend.h @@ -73,6 +73,8 @@ class JACKAudioBackend : 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) { return 0; } + int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; } std::string device_name () const; float sample_rate () const; @@ -82,6 +84,8 @@ class JACKAudioBackend : 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 { return 0; } + uint32_t systemic_midi_output_latency (std::string const) const { return 0; } std::string driver_name() const; std::string control_app_name () const; @@ -149,6 +153,19 @@ class JACKAudioBackend : public AudioBackend { int set_midi_option (const std::string&); std::string midi_option () const; + std::vector enumerate_midi_devices () const { + return std::vector (); + } + int set_midi_device_enabled (std::string const, bool) { + return 0; + } + bool midi_device_enabled (std::string const) const { + return true; + } + bool can_set_systemic_midi_latencies () const { + return false; + } + int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index); int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size); uint32_t get_midi_event_count (void* port_buffer); diff --git a/libs/backends/wavesaudio/waves_audiobackend.h b/libs/backends/wavesaudio/waves_audiobackend.h index 115b001014..6c027824c4 100644 --- a/libs/backends/wavesaudio/waves_audiobackend.h +++ b/libs/backends/wavesaudio/waves_audiobackend.h @@ -121,6 +121,10 @@ class WavesMidiPort; virtual int set_systemic_output_latency (uint32_t); + int set_systemic_midi_input_latency (std::string const, uint32_t) { return 0; } + + int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; } + virtual std::string device_name () const; virtual float sample_rate () const; @@ -139,6 +143,10 @@ class WavesMidiPort; virtual uint32_t systemic_output_latency () const; + uint32_t systemic_midi_input_latency (std::string const) const { return 0; } + + uint32_t systemic_midi_output_latency (std::string const) const { return 0; } + virtual std::string control_app_name () const; virtual void launch_control_app (); @@ -149,6 +157,19 @@ class WavesMidiPort; virtual std::string midi_option () const; + std::vector enumerate_midi_devices () const { + return std::vector (); + } + int set_midi_device_enabled (std::string const, bool) { + return 0; + } + bool midi_device_enabled (std::string const) const { + return true; + } + bool can_set_systemic_midi_latencies () const { + return false; + } + virtual int _start (bool for_latency_measurement); virtual int stop ();