Merged with trunk revision 600
[ardour.git] / libs / ardour / audioengine.cc
index e3c9549663558f0bfcab6b7819229e6a6971e9ec..c4f90efd4945955e65f30bef09bf279b45a20e1d 100644 (file)
@@ -21,6 +21,8 @@
 #include <unistd.h>
 #include <cerrno>
 #include <vector>
+
+#include <glibmm/timer.h>
 #include <pbd/pthread_utils.h>
 
 #include <ardour/audioengine.h>
@@ -44,7 +46,6 @@ jack_nframes_t Port::long_over_length = 10;
 
 AudioEngine::AudioEngine (string client_name) 
 {
-       pthread_cond_init (&session_removed, 0);
        session = 0;
        session_remove_pending = false;
        _running = false;
@@ -59,7 +60,12 @@ AudioEngine::AudioEngine (string client_name)
        _buffer_size = 0;
        _freewheeling = false;
        _freewheel_thread_registered = false;
+    
+    m_meter_thread = 0;
+    m_meter_exit = false;
 
+    start_metering_thread();
+    
        if (connect_to_jack (client_name)) {
                throw NoBackendAvailable ();
        }
@@ -71,6 +77,10 @@ AudioEngine::~AudioEngine ()
        if (_running) {
                jack_client_close (_jack);
        }
+
+    if(m_meter_thread) {
+        g_atomic_int_inc(&m_meter_exit);
+    }
 }
 
 void
@@ -80,7 +90,7 @@ _thread_init_callback (void *arg)
           knows about it.
        */
 
-       PBD::ThreadCreated (pthread_self(), X_("Audioengine"));
+       PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("Audioengine"), 4096);
 
 #ifdef VST_SUPPORT
        if (Config->get_use_vst()) {
@@ -216,65 +226,13 @@ AudioEngine::_freewheel_callback (int onoff, void *arg)
        static_cast<AudioEngine*>(arg)->_freewheeling = onoff;
 }
 
-void 
-AudioEngine::meter (Port *port, jack_nframes_t nframes)
-{
-       double peak;
-       uint32_t overlen;
-       jack_default_audio_sample_t *buf;
-       
-       buf = port->get_buffer (nframes);
-       peak = port->_peak;
-       overlen = port->overlen;
-       
-       {
-               for (jack_nframes_t n = 0; n < nframes; ++n) {
-                       
-                       /* 1) peak metering */
-                       
-                       peak = f_max (peak, buf[n]);
-                       
-                       /* 2) clip/over metering */
-                       
-                       if (buf[n] >= 1.0) {
-                               overlen++;
-                       } else if (overlen) {
-                               if (overlen > Port::short_over_length) {
-                                       port->_short_overs++;
-                               }
-                               if (overlen > Port::long_over_length) {
-                                       port->_long_overs++;
-                               }
-                               overlen = 0;
-                       }
-               }
-       }
-       
-        /* post-loop check on the final status of overlen */
-       
-       if (overlen > Port::short_over_length) {
-               port->_short_overs++;
-       }
-       if (overlen > Port::long_over_length) {
-               port->_short_overs++;
-       }
-
-       if (peak > 0.0) {
-               port->_peak_db= 20 * fast_log10 (peak);
-       } else {
-               port->_peak_db = minus_infinity();
-       }
-       
-       port->_peak = peak;
-       port->overlen = overlen;
-}
-
 int
 AudioEngine::process_callback (jack_nframes_t nframes)
 {
-       TentativeLockMonitor tm (_process_lock, __LINE__, __FILE__);
+       // CycleTimer ct ("AudioEngine::process");
+       Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
        jack_nframes_t next_processed_frames;
-
+       
        /* handle wrap around of total frames counter */
 
        if (max_frames - _processed_frames < nframes) {
@@ -291,7 +249,7 @@ AudioEngine::process_callback (jack_nframes_t nframes)
        if (session_remove_pending) {
                session = 0;
                session_remove_pending = false;
-               pthread_cond_signal (&session_removed);
+               session_removed.signal();
                _processed_frames = next_processed_frames;
                return 0;
        }
@@ -304,14 +262,6 @@ AudioEngine::process_callback (jack_nframes_t nframes)
                return 0;
        }
 
-       /* do input peak metering */
-
-       for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
-               if ((*i)->metering) {
-                       meter ((*i), nframes);
-               }
-       }
-       
        session->process (nframes);
 
        if (!_running) {
@@ -322,7 +272,7 @@ AudioEngine::process_callback (jack_nframes_t nframes)
                _processed_frames = next_processed_frames;
                return 0;
        }
-               
+
        if (last_monitor_check + monitor_check_interval < next_processed_frames) {
                for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
                        
@@ -360,7 +310,7 @@ AudioEngine::jack_sample_rate_callback (jack_nframes_t nframes)
 
        monitor_check_interval = nframes / 10;
        last_monitor_check = 0;
-
+       
        if (session) {
                session->set_frame_rate (nframes);
        }
@@ -394,6 +344,24 @@ AudioEngine::jack_bufsize_callback (jack_nframes_t nframes)
        return 0;
 }
 
+void
+AudioEngine::start_metering_thread ()
+{
+    if(m_meter_thread == 0) {
+        m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread), false);
+    }
+}
+
+void
+AudioEngine::meter_thread ()
+{
+       while (g_atomic_int_get(&m_meter_exit) != true) {
+        Glib::usleep (10000); /* 1/100th sec interval */
+        IO::update_meters ();
+       }
+       return;
+}
+
 void 
 AudioEngine::set_session (Session *s)
 {
@@ -405,13 +373,13 @@ AudioEngine::set_session (Session *s)
 void 
 AudioEngine::remove_session ()
 {
-       LockMonitor lm (_process_lock, __LINE__, __FILE__);
+       Glib::Mutex::Lock lm (_process_lock);
 
        if (_running) {
 
                if (session) {
                        session_remove_pending = true;
-                       pthread_cond_wait (&session_removed, _process_lock.mutex());
+                       session_removed.wait(_process_lock);
                } 
 
        } else {
@@ -448,7 +416,7 @@ AudioEngine::register_audio_input_port (const string& portname)
 
        } else {
 
-               pthread_mutex_unlock (_process_lock.mutex());
+               _process_lock.unlock();
                throw PortRegistrationFailure();
        }
 
@@ -476,7 +444,7 @@ AudioEngine::register_audio_output_port (const string& portname)
 
        } else {
 
-               pthread_mutex_unlock (_process_lock.mutex());
+               _process_lock.unlock();
                throw PortRegistrationFailure ();
        }
 
@@ -633,7 +601,7 @@ AudioEngine::frames_per_cycle ()
 Port *
 AudioEngine::get_port_by_name (const string& portname, bool keep)
 {
-       LockMonitor lm (_process_lock, __LINE__, __FILE__);
+       Glib::Mutex::Lock lm (_process_lock);
 
        if (!_running) {
                if (!_has_run) {
@@ -966,7 +934,7 @@ AudioEngine::reconnect_to_jack ()
        if (_jack) {
                disconnect_from_jack ();
                /* XXX give jackd a chance */
-               usleep (250000);
+        Glib::usleep (250000);
        }
 
        if (connect_to_jack (jack_client_name)) {