X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fbackends%2Fportaudio%2Fportaudio_backend.h;h=692e4c0e6131a4e53b9b30d79cbe09c8f4ec246e;hb=335debfa2fed045dc80c43fb2ef62d89262fc8f8;hp=22dd38690416523d067c08162744d9daf2c119dc;hpb=fe50d068761a2e2cbd7b95678d807adbde32eb65;p=ardour.git diff --git a/libs/backends/portaudio/portaudio_backend.h b/libs/backends/portaudio/portaudio_backend.h index 22dd386904..692e4c0e61 100644 --- a/libs/backends/portaudio/portaudio_backend.h +++ b/libs/backends/portaudio/portaudio_backend.h @@ -30,6 +30,7 @@ #include #include "ardour/audio_backend.h" +#include "ardour/dsp_load_calculator.h" #include "ardour/types.h" #include "portaudio_io.h" @@ -65,9 +66,11 @@ class PamPort { // PortAudio / PortMidi Backend Port virtual ~PamPort (); const std::string& name () const { return _name; } + const std::string& pretty_name () const { return _pretty_name; } PortFlags flags () const { return _flags; } int set_name (const std::string &name) { _name = name; return 0; } + int set_pretty_name (const std::string& name) { _pretty_name = name; return 0;} virtual DataType type () const = 0; @@ -107,6 +110,7 @@ class PamPort { // PortAudio / PortMidi Backend Port private: PortAudioBackend &_osx_backend; std::string _name; + std::string _pretty_name; const PortFlags _flags; LatencyRange _capture_latency_range; LatencyRange _playback_latency_range; @@ -167,7 +171,15 @@ class PortAudioBackend : public AudioBackend { std::vector enumerate_drivers () const; int set_driver (const std::string&); + bool can_request_update_devices () { return true; } + bool update_devices (); + + bool can_use_buffered_io () { return true; } + void set_use_buffered_io (bool); + bool get_use_buffered_io () { return _use_blocking_api; } + bool use_separate_input_and_output_devices () const; + bool match_input_output_devices_or_none () const { return true; } std::vector enumerate_devices () const; std::vector enumerate_input_devices () const; std::vector enumerate_output_devices () const; @@ -190,8 +202,8 @@ class PortAudioBackend : 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; } + int set_systemic_midi_input_latency (std::string const, uint32_t); + int set_systemic_midi_output_latency (std::string const, uint32_t); int reset_device () { return 0; }; @@ -206,29 +218,23 @@ class PortAudioBackend : 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; } + 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 false; } + bool can_set_systemic_midi_latencies () const { return true; } /* External control app */ - std::string control_app_name () const { return std::string (); } - void launch_control_app () {} + std::string control_app_name () const; + void launch_control_app (); /* MIDI */ std::vector enumerate_midi_options () const; 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; - } + std::vector enumerate_midi_devices () const; + int set_midi_device_enabled (std::string const, bool); + bool midi_device_enabled (std::string const) const; protected: /* State Control */ @@ -261,6 +267,8 @@ class PortAudioBackend : public AudioBackend { int set_port_name (PortHandle, const std::string&); std::string get_port_name (PortHandle) const; PortHandle get_port_by_name (const std::string&) const; + int get_port_property (PortHandle, const std::string& key, std::string& value, std::string& type) const; + int set_port_property (PortHandle, const std::string& key, const std::string& value, const std::string& type); int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector&) const; @@ -310,7 +318,42 @@ class PortAudioBackend : public AudioBackend { void* get_buffer (PortHandle, pframes_t); - void* main_process_thread (); + void* blocking_process_thread (); + + void* freewheel_process_thread (); + + private: // Methods + bool start_blocking_process_thread (); + bool stop_blocking_process_thread (); + bool blocking_process_freewheel (); + bool blocking_process_main (const float* interleaved_input_data, + float* interleaved_output_data); + + void process_port_connection_changes (); + void process_incoming_midi (); + void process_outgoing_midi (); + + bool engine_halted (); + bool running (); + + static int portaudio_callback(const void* input, + void* output, + unsigned long frameCount, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void* userData); + + bool process_callback(const float* input, + float* output, + uint32_t frame_count, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags); + + bool start_freewheel_process_thread (); + bool stop_freewheel_process_thread (); + + static bool set_mmcss_pro_audio (HANDLE* task_handle); + static bool reset_mmcss (HANDLE task_handle); private: std::string _instance_name; @@ -319,16 +362,26 @@ class PortAudioBackend : public AudioBackend { bool _run; /* keep going or stop, ardour thread */ bool _active; /* is running, process thread */ + bool _use_blocking_api; bool _freewheel; bool _freewheeling; + bool _freewheel_ack; + bool _reinit_thread_callback; bool _measure_latency; - uint64_t m_cycle_count; - uint64_t m_total_deviation_us; - uint64_t m_max_deviation_us; + ARDOUR::DSPLoadCalculator _dsp_calc; + + bool _freewheel_thread_active; + + pthread_mutex_t _freewheel_mutex; + pthread_cond_t _freewheel_signal; - CycleTimer m_cycle_timer; - uint64_t m_last_cycle_start; + uint64_t _cycle_count; + uint64_t _total_deviation_us; + uint64_t _max_deviation_us; + + CycleTimer _cycle_timer; + uint64_t _last_cycle_start; static std::vector _midi_options; static std::vector _input_audio_device_status; @@ -350,14 +403,24 @@ class PortAudioBackend : public AudioBackend { uint32_t _systemic_audio_input_latency; uint32_t _systemic_audio_output_latency; + MidiDeviceInfo* midi_device_info(const std::string&) const; + /* portaudio specific */ int name_to_id(std::string) const; /* processing */ float _dsp_load; framecnt_t _processed_samples; + + /* blocking thread */ + pthread_t _main_blocking_thread; + + /* main thread in callback mode(or fw thread when running) */ pthread_t _main_thread; + /* freewheel thread in callback mode */ + pthread_t _pthread_freewheel; + /* process threads */ static void* portaudio_process_thread (void *); std::vector _threads;