28 #include <glibmm/timer.h>
29 #include <glibmm/pattern.h>
30 #include <glibmm/module.h>
38 #include "midi++/port.h"
39 #include "midi++/mmc.h"
67 #define SILENCE_AFTER_SECONDS 600
71 : session_remove_pending (false)
72 , session_removal_countdown (-1)
74 , _freewheeling (false)
75 , monitor_check_interval (INT32_MAX)
76 , last_monitor_check (0)
77 , _processed_frames (0)
82 , _measuring_latency (MeasureNone)
83 , _latency_input_port (0)
84 , _latency_output_port (0)
85 , _latency_flush_frames (0)
86 , _latency_signal_latency (0)
87 , _stopped_for_latency (false)
88 , _started_for_latency (false)
89 , _in_destructor (false)
90 , _hw_reset_event_thread(0)
91 , _hw_reset_request_count(0)
92 , _stop_hw_reset_processing(0)
93 , _hw_devicelist_update_thread(0)
94 , _hw_devicelist_update_count(0)
95 , _stop_hw_devicelist_processing(0)
96 #ifdef SILENCE_AFTER_SECONDS
97 , _silence_countdown (0)
98 , _silence_hit_cnt (0)
112 i->second->deinstantiate();
139 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
140 i->second->cycle_split ();
158 #ifdef SILENCE_AFTER_SECONDS
159 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
182 __attribute__((annotate(
"realtime")))
217 bool return_after_remove_check =
false;
240 return_after_remove_check =
true;
262 return_after_remove_check =
true;
280 return_after_remove_check =
true;
319 if (return_after_remove_check) {
370 #ifdef SILENCE_AFTER_SECONDS
372 bool was_silent = (_silence_countdown == 0);
374 if (_silence_countdown >= nframes) {
375 _silence_countdown -= nframes;
377 _silence_countdown = 0;
380 if (!was_silent && _silence_countdown == 0) {
420 #ifdef SILENCE_AFTER_SECONDS
425 _silence_countdown = max (60 * sr,
426 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (
double) _silence_hit_cnt)));
471 std::cout <<
"AudioEngine::RESET::Reset request processing. Requests left: " <<
_hw_reset_request_count << std::endl;
477 std::cout <<
"AudioEngine::RESET::Stoping engine..." << std::endl;
480 std::cout <<
"AudioEngine::RESET::Reseting device..." << std::endl;
481 if ( 0 ==
_backend->reset_device () ) {
483 std::cout <<
"AudioEngine::RESET::Starting engine..." << std::endl;
492 std::cout <<
"AudioEngine::RESET::Done." << std::endl;
663 vector<std::string> backend_modules;
667 Glib::PatternSpec so_extension_pattern(
"*backend.so");
668 Glib::PatternSpec dylib_extension_pattern(
"*backend.dylib");
670 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
671 #if defined(DEBUG) || defined(_DEBUG)
672 Glib::PatternSpec dll_extension_pattern(
"*backendD.dll");
674 Glib::PatternSpec dll_extension_pattern(
"*backendRDC.dll");
677 Glib::PatternSpec dll_extension_pattern(
"*backend.dll");
681 so_extension_pattern);
684 dylib_extension_pattern);
687 dll_extension_pattern);
691 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
710 #ifdef PLATFORM_WINDOWS
713 SetErrorMode(SEM_FAILCRITICALERRORS);
715 Glib::Module module (path);
716 #ifdef PLATFORM_WINDOWS
725 Glib::Module::get_last_error()) <<
endmsg;
729 if (!module.get_symbol (
"descriptor", func)) {
741 module.make_resident ();
746 vector<const AudioBackendInfo*>
749 vector<const AudioBackendInfo*> r;
752 r.push_back (i->second);
791 BackendMap::iterator b =
_backends.find (name);
800 if (b->second->instantiate (arg1, arg2)) {
804 _backend = b->second->factory (*
this);
806 }
catch (exception& e) {
830 if (
_backend->start (for_latency)) {
896 return _backend->freewheel (start_stop);
934 return _backend->transport_start ();
952 return _backend->transport_state ();
961 return _backend->transport_locate (pos);
970 return _backend->transport_frame ();
997 return _backend->usecs_per_cycle ();
1006 return _backend->raw_buffer_size (t);
1024 return _backend->sample_time_at_cycle_start ();
1033 return _backend->samples_since_cycle_start ();
1042 return _backend->get_sync_offset (offset);
1051 return _backend->create_process_thread (func);
1060 return _backend->join_process_threads ();
1069 return _backend->in_process_thread ();
1078 return _backend->process_thread_count ();
1087 return _backend->set_device_name (name);
1097 return _backend->set_sample_rate (sr);
1106 return _backend->set_buffer_size (bufsiz);
1115 return _backend->set_interleaved (yn);
1124 return _backend->set_input_channels (ic);
1133 return _backend->set_output_channels (oc);
1142 return _backend->set_systemic_input_latency (il);
1151 return _backend->set_systemic_output_latency (ol);
1230 if (
_backend->info().already_configured())
1296 const string portname (
"latency_in");
1324 const string portname (
"latency_in");
static void increment_global_port_buffer_offset(pframes_t n)
framecnt_t _latency_signal_latency
gain_t session_removal_gain
int join_process_threads()
void silence_outputs(pframes_t nframes)
SerializedRCUManager< Ports > ports
pframes_t samples_since_cycle_start()
std::string to_string(T t, std::ios_base &(*f)(std::ios_base &))
Glib::Threads::Mutex _devicelist_update_lock
void update_latency(bool playback)
int stop(bool for_latency_measurement=false)
Glib::Threads::Cond session_removed
void reconnect_existing_routes(bool withLock, bool reconnect_master=true, bool reconnect_inputs=true, bool reconnect_outputs=true)
PBD::Signal1< int, pframes_t > Freewheel
void set_session(Session *)
uint32_t process_thread_count()
PBD::Signal0< void > Xrun
int start_latency_detection(bool)
bool _started_for_latency
framepos_t transport_frame()
int backend_sync_callback(TransportState, framepos_t)
pframes_t samples_per_cycle() const
int set_buffer_size(uint32_t)
void cycle_end(pframes_t nframes)
static void create_per_thread_pool(const std::string &n, uint32_t nitems)
void reconnect_session_routes(bool reconnect_inputs=true, bool reconnect_outputs=true)
Glib::Threads::Thread * _hw_reset_event_thread
Glib::Threads::RecMutex _state_lock
int process(size_t len, float *inp, float *out)
std::string _latency_output_name
bool _stopped_for_latency
gint _stop_hw_devicelist_processing
void request_backend_reset()
framecnt_t last_monitor_check
time of the last monitor check in frames
framecnt_t _processed_frames
the number of frames processed since start() was called
int start(bool for_latency_measurement=false)
int set_sample_rate(float)
LIBPBD_API void notify_gui_about_thread_creation(std::string, pthread_t, std::string, int requests=256)
LIBPBD_API Transmitter error
AudioBackendInfo * backend_discover(const std::string &)
int usecs_per_cycle() const
PBD::Signal0< void > DeviceListChanged
virtual void * get_buffer(PortHandle, pframes_t)=0
float get_dsp_load() const
std::ostream & endmsg(std::ostream &ostr)
static AudioEngine * _instance
SessionConfiguration config
#define PT_TIMING_CHECK(x)
virtual int connect(const std::string &src, const std::string &dst)=0
framecnt_t monitor_check_interval
number of frames between each check for changes in monitor input
static AudioEngine * instance()
PortEngine & port_engine()
gint _hw_devicelist_update_count
frameoffset_t session_removal_countdown
void stop_hw_event_processing()
void set_latency_input_port(const std::string &)
static PBD::Signal0< void > PortDrop
void reset_silence_countdown()
std::string current_backend_name() const
ProcessThread * _main_thread
framecnt_t sample_rate() const
void request_device_list_update()
framecnt_t _latency_flush_frames
int process(pframes_t nframes, PortEngine &pe, void *midi_in, void *midi_out)
int sync_callback(TransportState state, framepos_t position)
int freewheel(bool start_stop)
Glib::Threads::Cond _hw_reset_condition
void find_files_matching_pattern(vector< string > &result, const Searchpath &paths, const Glib::PatternSpec &pattern)
void set_block_size(pframes_t nframes)
TransportState transport_state()
Glib::Threads::Thread * _hw_devicelist_update_thread
static PBD::Signal1< void, pframes_t > CycleStart
static AudioEngine * create()
gint _stop_hw_reset_processing
Glib::Threads::Mutex _process_lock
void fade_out(gain_t, gain_t, pframes_t)
int set_device_name(const std::string &)
virtual void unregister_port(PortHandle)=0
PortEngine::PortHandle _latency_input_port
PBD::Signal1< void, framecnt_t > SampleRateChanged
LIBARDOUR_API PBD::Searchpath backend_search_path()
int set_input_channels(uint32_t)
void process(pframes_t nframes)
gint _hw_reset_request_count
void start_hw_event_processing()
framepos_t sample_time_at_cycle_start()
int set_output_channels(uint32_t)
boost::shared_ptr< AudioBackend > set_backend(const std::string &, const std::string &arg1, const std::string &arg2)
void set_latency_output_port(const std::string &)
#define DEBUG_TRACE(bits, str)
virtual PortHandle get_port_by_name(const std::string &) const =0
PBD::Signal0< void > BecameSilent
LIBPBD_API void pthread_set_name(const char *name)
Glib::Threads::Mutex _reset_request_lock
boost::shared_ptr< AudioBackend > _backend
int process_callback(pframes_t nframes)
PBD::Signal0< void > Running
LIBPBD_API Transmitter info
PBD::Signal0< void > DeviceResetStarted
size_t raw_buffer_size(DataType t)
void launch_device_control_app()
void silence(pframes_t nframes)
int set_interleaved(bool yn)
static void set_process_thread(pthread_t)
virtual PortHandle register_port(const std::string &shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags)=0
virtual LatencyRange get_latency_range(PortHandle port, bool for_playback)=0
PortEngine::PortHandle _latency_output_port
bool setup_required() const
std::vector< const AudioBackendInfo * > available_backends() const
int backend_reset_requested()
Glib::Threads::Cond _hw_devicelist_update_condition
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
int buffer_size_change(pframes_t nframes)
int prepare_for_latency_measurement()
void transport_locate(framepos_t pos)
PBD::Signal0< void > DeviceError
PBD::Signal1< void, pframes_t > BufferSizeChanged
bool get_sync_offset(pframes_t &offset) const
std::string _latency_input_name
void halted_callback(const char *reason)
int set_systemic_output_latency(uint32_t)
PBD::Signal1< void, const char * > Halted
static const framepos_t max_framepos
void split_cycle(pframes_t offset)
virtual void set_session(ARDOUR::Session *)
PBD::Signal0< void > Stopped
LIBARDOUR_API uint64_t AudioEngine
bool session_remove_pending
boost::shared_ptr< T > reader() const
void set_frame_rate(framecnt_t nframes)
void freewheel_callback(bool)
LatencyMeasurement _measuring_latency
int create_process_thread(boost::function< void()> func)
void cycle_start(pframes_t nframes)
std::string make_port_name_non_relative(const std::string &name) const
void stop_latency_detection()
int sample_rate_change(pframes_t nframes)
boost::shared_ptr< AudioBackend > set_default_backend()
int set_systemic_input_latency(uint32_t)
ARDOUR::Session * _session
static void thread_init_callback(void *)
std::string string_compose(const std::string &fmt, const T1 &o1)
void do_devicelist_update()
void latency_callback(bool for_playback)
gain_t session_removal_gain_step