#include <boost/shared_ptr.hpp>
#include "ardour/audio_backend.h"
+#include "ardour/dsp_load_calculator.h"
#include "ardour/types.h"
#include "portaudio_io.h"
+#include "winmmemidi_io.h"
+#include "cycle_timer.h"
namespace ARDOUR {
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;
private:
PortAudioBackend &_osx_backend;
std::string _name;
+ std::string _pretty_name;
const PortFlags _flags;
LatencyRange _capture_latency_range;
LatencyRange _playback_latency_range;
std::string name () const;
bool is_realtime () const;
+ bool requires_driver_selection() const;
+ std::string driver_name () const;
+ std::vector<std::string> enumerate_drivers () const;
+ int set_driver (const std::string&);
+
+ bool can_request_update_devices () { return true; }
+ bool update_devices ();
+
+ bool use_separate_input_and_output_devices () const;
std::vector<DeviceStatus> enumerate_devices () const;
+ std::vector<DeviceStatus> enumerate_input_devices () const;
+ std::vector<DeviceStatus> enumerate_output_devices () const;
+
std::vector<float> available_sample_rates (const std::string& device) const;
std::vector<uint32_t> available_buffer_sizes (const std::string& device) const;
uint32_t available_input_channel_count (const std::string& device) const;
bool can_change_buffer_size_when_running () const;
int set_device_name (const std::string&);
+ int set_input_device_name (const std::string&);
+ int set_output_device_name (const std::string&);
int set_sample_rate (float);
int set_buffer_size (uint32_t);
int set_interleaved (bool yn);
/* Retrieving parameters */
std::string device_name () const;
+ std::string input_device_name () const;
+ std::string output_device_name () const;
float sample_rate () const;
uint32_t buffer_size () const;
bool interleaved () const;
bool can_set_systemic_midi_latencies () const { return false; }
/* 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<std::string> enumerate_midi_options () const;
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 get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&) const;
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;
PortAudioIO *_pcmio;
+ WinMMEMidiIO *_midiio;
bool _run; /* keep going or stop, ardour thread */
bool _active; /* is running, process thread */
bool _freewheel;
bool _freewheeling;
+ bool _freewheel_ack;
+ bool _reinit_thread_callback;
bool _measure_latency;
- uint64_t _last_process_start;
+ ARDOUR::DSPLoadCalculator _dsp_calc;
+
+ bool _freewheel_thread_active;
+
+ pthread_mutex_t _freewheel_mutex;
+ pthread_cond_t _freewheel_signal;
+
+ 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<std::string> _midi_options;
- static std::vector<AudioBackend::DeviceStatus> _audio_device_status;
+ static std::vector<AudioBackend::DeviceStatus> _input_audio_device_status;
+ static std::vector<AudioBackend::DeviceStatus> _output_audio_device_status;
static std::vector<AudioBackend::DeviceStatus> _midi_device_status;
- mutable std::string _audio_device;
+ mutable std::string _input_audio_device;
+ mutable std::string _output_audio_device;
std::string _midi_driver_option;
/* audio settings */
/* 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<pthread_t> _threads;
/* port engine */
PortHandle add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
int register_system_audio_ports ();
+ int register_system_midi_ports ();
void unregister_ports (bool system_only = false);
std::vector<PamPort *> _ports;