Remove LocaleGuard from ARDOUR::AudioDiskstream state methods
[ardour.git] / libs / ardour / audioengine.cc
index 0eba97429bd0fbbce4046949e88b9573fd0df60c..f215eaae82feda78346c4a8404bc94376013e0e2 100644 (file)
@@ -53,6 +53,7 @@
 #include "ardour/mtdm.h"
 #include "ardour/port.h"
 #include "ardour/process_thread.h"
+#include "ardour/rc_configuration.h"
 #include "ardour/session.h"
 
 #include "pbd/i18n.h"
@@ -90,12 +91,12 @@ AudioEngine::AudioEngine ()
        , _started_for_latency (false)
        , _in_destructor (false)
        , _last_backend_error_string(AudioBackend::get_error_string((AudioBackend::ErrorCode)-1))
-    , _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)
+       , _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)
 #ifdef SILENCE_AFTER_SECONDS
        , _silence_countdown (0)
        , _silence_hit_cnt (0)
@@ -295,11 +296,11 @@ AudioEngine::process_callback (pframes_t nframes)
                PortManager::silence (nframes);
                PortManager::cycle_end (nframes);
 
-                if (_latency_flush_frames > nframes) {
-                        _latency_flush_frames -= nframes;
-                } else {
-                        _latency_flush_frames = 0;
-                }
+               if (_latency_flush_frames > nframes) {
+                       _latency_flush_frames -= nframes;
+               } else {
+                       _latency_flush_frames = 0;
+               }
 
                return_after_remove_check = true;
        }
@@ -365,9 +366,9 @@ AudioEngine::process_callback (pframes_t nframes)
        PortManager::cycle_start (nframes);
 
        /* test if we are freewheeling and there are freewheel signals connected.
-           ardour should act normally even when freewheeling unless /it/ is
-           exporting (which is what Freewheel.empty() tests for).
-       */
+        * ardour should act normally even when freewheeling unless /it/ is
+        * exporting (which is what Freewheel.empty() tests for).
+        */
 
        if (_freewheeling && !Freewheel.empty()) {
                Freewheel (nframes);
@@ -465,9 +466,9 @@ AudioEngine::launch_device_control_app()
 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 ();
+       Glib::Threads::Mutex::Lock guard (_reset_request_lock);
+       g_atomic_int_inc (&_hw_reset_request_count);
+       _hw_reset_condition.signal ();
 }
 
 int
@@ -492,28 +493,28 @@ AudioEngine::do_reset_backend()
                        Glib::Threads::RecMutex::Lock pl (_state_lock);
                        g_atomic_int_dec_and_test (&_hw_reset_request_count);
 
-            std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
-                        DeviceResetStarted(); // notify about device reset to be started
+                       std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
+                       DeviceResetStarted(); // notify about device reset to be started
 
-                        // backup the device name
-                        std::string name = _backend->device_name ();
+                       // backup the device name
+                       std::string name = _backend->device_name ();
 
-            std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
+                       std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
                        if ( ( 0 == stop () ) &&
-                 ( 0 == _backend->reset_device () ) &&
-                 ( 0 == start () ) ) {
+                                       ( 0 == _backend->reset_device () ) &&
+                                       ( 0 == start () ) ) {
 
                                std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
 
                                // inform about possible changes
                                BufferSizeChanged (_backend->buffer_size() );
-                DeviceResetFinished(); // notify about device reset finish
+                               DeviceResetFinished(); // notify about device reset finish
 
-            } else {
+                       } else {
 
-                DeviceResetFinished(); // notify about device reset finish
+                               DeviceResetFinished(); // notify about device reset finish
                                // we've got an error
-                DeviceError();
+                               DeviceError();
                        }
 
                        std::cout << "AudioEngine::RESET::Done." << std::endl;
@@ -527,81 +528,79 @@ AudioEngine::do_reset_backend()
                }
        }
 }
+
 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 ();
+       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);
+       SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
 
-    Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
+       Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
 
-    while (!_stop_hw_devicelist_processing) {
+       while (!_stop_hw_devicelist_processing) {
 
-        if (_hw_devicelist_update_count) {
+               if (_hw_devicelist_update_count) {
 
-            _devicelist_update_lock.unlock();
+                       _devicelist_update_lock.unlock();
 
-            Glib::Threads::RecMutex::Lock pl (_state_lock);
+                       Glib::Threads::RecMutex::Lock pl (_state_lock);
 
-            g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
-            DeviceListChanged (); /* EMIT SIGNAL */
+                       g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
+                       DeviceListChanged (); /* EMIT SIGNAL */
 
-            _devicelist_update_lock.lock();
+                       _devicelist_update_lock.lock();
 
-        } else {
-            _hw_devicelist_update_condition.wait (_devicelist_update_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_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));
-    }
+       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;
-    }
+       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::set_session (Session *s)
 {
@@ -775,12 +774,14 @@ AudioEngine::backend_discover (const string& path)
        return info;
 }
 
+#ifdef NDEBUG
 static bool running_from_source_tree ()
 {
        // dup ARDOUR_UI_UTILS::running_from_source_tree ()
        gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
        return x && (string (x).find ("gtk2_ardour") != string::npos);
 }
+#endif
 
 vector<const AudioBackendInfo*>
 AudioEngine::available_backends() const
@@ -789,7 +790,7 @@ AudioEngine::available_backends() const
 
        for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
 #ifdef NDEBUG
-               if (i->first == "None (Dummy)" && !running_from_source_tree ()) {
+               if (i->first == "None (Dummy)" && !running_from_source_tree () && Config->get_hide_dummy_backend ()) {
                        continue;
                }
 #endif
@@ -876,8 +877,7 @@ AudioEngine::start (bool for_latency)
        int error_code = _backend->start (for_latency);
 
        if (error_code != 0) {
-               _last_backend_error_string =
-                   AudioBackend::get_error_string((AudioBackend::ErrorCode)error_code);
+               _last_backend_error_string = AudioBackend::get_error_string((AudioBackend::ErrorCode) error_code);
                return -1;
        }
 
@@ -892,6 +892,10 @@ AudioEngine::start (bool for_latency)
 
        }
 
+       /* XXX MIDI ports may not actually be available here yet .. */
+
+       PortManager::fill_midi_port_info ();
+
        if (!for_latency) {
                Running(); /* EMIT SIGNAL */
        }
@@ -916,11 +920,14 @@ AudioEngine::stop (bool for_latency)
 
        if (for_latency && _backend->can_change_systemic_latency_when_running()) {
                stop_engine = false;
+               if (_running) {
+                       _backend->start (false); // keep running, reload latencies
+               }
        } else {
                if (_backend->stop ()) {
-                       if (pl.locked ()) { 
-                            pl.release ();
-                        }
+                       if (pl.locked ()) {
+                               pl.release ();
+                       }
                        return -1;
                }
        }
@@ -937,20 +944,24 @@ AudioEngine::stop (bool for_latency)
                _session->engine_halted ();
        }
 
-       if (stop_engine) {
+       if (stop_engine && _running) {
                _running = false;
+               if (!for_latency) {
+                       _started_for_latency = false;
+               } else if (!_started_for_latency) {
+                       _stopped_for_latency = true;
+               }
        }
        _processed_frames = 0;
        _measuring_latency = MeasureNone;
        _latency_output_port = 0;
        _latency_input_port = 0;
-       _started_for_latency = false;
 
        if (stop_engine) {
                Port::PortDrop ();
        }
 
-       if (!for_latency && stop_engine) {
+       if (stop_engine) {
                Stopped (); /* EMIT SIGNAL */
        }
 
@@ -1227,7 +1238,7 @@ AudioEngine::set_systemic_output_latency (uint32_t ol)
 bool
 AudioEngine::thread_initialised_for_audio_processing ()
 {
-    return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
+       return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
 }
 
 /* END OF BACKEND PROXY API */
@@ -1273,9 +1284,9 @@ AudioEngine::freewheel_callback (bool onoff)
 void
 AudioEngine::latency_callback (bool for_playback)
 {
-        if (_session) {
-                _session->update_latency (for_playback);
-        }
+       if (_session) {
+               _session->update_latency (for_playback);
+       }
 }
 
 void
@@ -1325,17 +1336,21 @@ AudioEngine::prepare_for_latency_measurement ()
                return -1;
        }
 
+       if (running() && _started_for_latency) {
+               return 0;
+       }
+
        if (_backend->can_change_systemic_latency_when_running()) {
-               if (start()) {
+               if (_running) {
+                       _backend->start (true); // zero latency reporting of running backend
+               } else if (start (true)) {
                        return -1;
                }
-               _backend->set_systemic_input_latency (0);
-               _backend->set_systemic_output_latency (0);
+               _started_for_latency = true;
                return 0;
        }
 
        if (running()) {
-               _stopped_for_latency = true;
                stop (true);
        }
 
@@ -1343,7 +1358,6 @@ AudioEngine::prepare_for_latency_measurement ()
                return -1;
        }
        _started_for_latency = true;
-
        return 0;
 }
 
@@ -1458,6 +1472,18 @@ AudioEngine::stop_latency_detection ()
                _latency_input_port = 0;
        }
 
+       if (_running && _backend->can_change_systemic_latency_when_running()) {
+               if (_started_for_latency) {
+                       _running = false; // force reload: reset latencies and emit Running()
+                       start ();
+               }
+       }
+
+       if (_running && !_started_for_latency) {
+               assert (!_stopped_for_latency);
+               return;
+       }
+
        if (!_backend->can_change_systemic_latency_when_running()) {
                stop (true);
        }
@@ -1496,4 +1522,3 @@ AudioEngine::add_pending_port_deletion (Port* p)
                delete p;
        }
 }
-