diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2014-09-30 20:35:31 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2014-09-30 21:00:34 -0400 |
commit | 8d59afb0486e1816f5ef30526c2dc762b9f4eda8 (patch) | |
tree | de90977cedb059b8c9c3c911f5e2ffe2493971a4 /libs/ardour/audioengine.cc | |
parent | 38e975d6b1d6e8b1cd85e7896bc00a63643d4f1d (diff) |
copy over current Waves version of their backend, along with minor changes in libs/ardour and libs/backend/jack to fit with API changes
Diffstat (limited to 'libs/ardour/audioengine.cc')
-rw-r--r-- | libs/ardour/audioengine.cc | 165 |
1 files changed, 162 insertions, 3 deletions
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index ab99ccbda3..41224a10b7 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -82,8 +82,15 @@ AudioEngine::AudioEngine () , _latency_signal_latency (0) , _stopped_for_latency (false) , _in_destructor (false) + , _hw_reset_event_thread(0) + , _hw_reset_request_count(0) + , _stop_hw_reset_processing(0) + , _hw_devicelist_update_thread(0) + , _hw_devicelist_update_count(0) + , _stop_hw_devicelist_processing(0) { g_atomic_int_set (&m_meter_exit, 0); + start_hw_event_processing(); discover_backends (); } @@ -91,6 +98,7 @@ AudioEngine::~AudioEngine () { _in_destructor = true; stop_metering_thread (); + stop_hw_event_processing(); drop_backend (); } @@ -164,6 +172,8 @@ AudioEngine::buffer_size_change (pframes_t bufsiz) last_monitor_check = 0; } + BufferSizeChanged (bufsiz); /* EMIT SIGNAL */ + return 0; } @@ -380,6 +390,139 @@ AudioEngine::process_callback (pframes_t nframes) void +AudioEngine::request_backend_reset() +{ + Glib::Threads::Mutex::Lock guard (_reset_request_lock); + g_atomic_int_inc (&_hw_reset_request_count); + _hw_reset_condition.signal (); +} + + +void +AudioEngine::do_reset_backend() +{ + SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 512); + + Glib::Threads::Mutex::Lock guard (_reset_request_lock); + + while (!_stop_hw_reset_processing) { + + if (_hw_reset_request_count && _backend) { + + _reset_request_lock.unlock(); + + Glib::Threads::RecMutex::Lock pl (_state_lock); + + g_atomic_int_dec_and_test (&_hw_reset_request_count); + + std::cout << "AudioEngine::RESET::Reset request processing" << std::endl; + + // backup the device name + std::string name = _backend->device_name (); + + std::cout << "AudioEngine::RESET::Stoping engine..." << std::endl; + stop(); + + std::cout << "AudioEngine::RESET::Reseting device..." << std::endl; + if ( 0 == _backend->reset_device () ) { + + std::cout << "AudioEngine::RESET::Starting engine..." << std::endl; + start (); + + // inform about possible changes + BufferSizeChanged (_backend->buffer_size() ); + } else { + DeviceError(); + } + + std::cout << "AudioEngine::RESET::Done." << std::endl; + + _reset_request_lock.lock(); + + } else { + + _hw_reset_condition.wait (_reset_request_lock); + + } + } +} + + +void +AudioEngine::request_device_list_update() +{ + Glib::Threads::Mutex::Lock guard (_devicelist_update_lock); + g_atomic_int_inc (&_hw_devicelist_update_count); + _hw_devicelist_update_condition.signal (); +} + + +void +AudioEngine::do_devicelist_update() +{ + SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512); + + Glib::Threads::Mutex::Lock guard (_devicelist_update_lock); + + while (!_stop_hw_devicelist_processing) { + + if (_hw_devicelist_update_count) { + + _devicelist_update_lock.unlock(); + + g_atomic_int_dec_and_test (&_hw_devicelist_update_count); + DeviceListChanged (); /* EMIT SIGNAL */ + + _devicelist_update_lock.lock(); + + } else { + _hw_devicelist_update_condition.wait (_devicelist_update_lock); + } + } +} + + +void +AudioEngine::start_hw_event_processing() +{ + if (_hw_reset_event_thread == 0) { + g_atomic_int_set(&_hw_reset_request_count, 0); + g_atomic_int_set(&_stop_hw_reset_processing, 0); + _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this)); + } + + if (_hw_devicelist_update_thread == 0) { + g_atomic_int_set(&_hw_devicelist_update_count, 0); + g_atomic_int_set(&_stop_hw_devicelist_processing, 0); + _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this)); + } +} + + +void +AudioEngine::stop_hw_event_processing() +{ + if (_hw_reset_event_thread) { + g_atomic_int_set(&_stop_hw_reset_processing, 1); + g_atomic_int_set(&_hw_reset_request_count, 0); + _hw_reset_condition.signal (); + _hw_reset_event_thread->join (); + _hw_reset_event_thread = 0; + } + + if (_hw_devicelist_update_thread) { + g_atomic_int_set(&_stop_hw_devicelist_processing, 1); + g_atomic_int_set(&_hw_devicelist_update_count, 0); + _hw_devicelist_update_condition.signal (); + _hw_devicelist_update_thread->join (); + _hw_devicelist_update_thread = 0; + } + +} + + + +void AudioEngine::stop_metering_thread () { if (m_meter_thread) { @@ -460,13 +603,22 @@ AudioEngine::remove_session () void +AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs) +{ + if (_session) { + _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs); + } +} + + +void AudioEngine::died () { /* called from a signal handler for SIGPIPE */ stop_metering_thread (); - _running = false; + _running = false; } int @@ -591,7 +743,7 @@ AudioEngine::drop_backend () { if (_backend) { _backend->stop (); - _backend->drop_device(); + _backend->drop_device (); _backend.reset (); _running = false; } @@ -661,6 +813,7 @@ AudioEngine::start (bool for_latency) if (_session->config.get_jack_time_master()) { _backend->set_time_master (true); } + } start_metering_thread (); @@ -679,6 +832,12 @@ AudioEngine::stop (bool for_latency) return 0; } + if (_session && _running) { + // it's not a halt, but should be handled the same way: + // disable record, stop transport and I/O processign but save the data. + _session->engine_halted (); + } + Glib::Threads::Mutex::Lock lm (_process_lock); if (_backend->stop ()) { @@ -1031,7 +1190,7 @@ AudioEngine::halted_callback (const char* why) return; } - stop_metering_thread (); + stop_metering_thread (); _running = false; Port::PortDrop (); /* EMIT SIGNAL */ |