changeset 118:c41e340dfe8d

* timing updates; still much to be done
author Chris Cannam
date Wed, 21 May 2008 17:11:57 +0000
parents 2bc8bf6d016c
children 1ba557a20ca3
files audioio/AudioPulseAudioTarget.cpp audioio/AudioPulseAudioTarget.h
diffstat 2 files changed, 39 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/audioio/AudioPulseAudioTarget.cpp	Wed May 21 16:54:24 2008 +0000
+++ b/audioio/AudioPulseAudioTarget.cpp	Wed May 21 17:11:57 2008 +0000
@@ -53,7 +53,7 @@
 
     //!!! handle signals how?
 
-    m_bufferSize = 2048;
+    m_bufferSize = 20480;
     m_sampleRate = 44100;
     if (m_source && (m_source->getSourceSampleRate() != 0)) {
 	m_sampleRate = m_source->getSourceSampleRate();
@@ -124,9 +124,10 @@
 AudioPulseAudioTarget::getCurrentTime() const
 {
     if (!m_stream) return 0.0;
-//!!!    else return Pa_GetStreamTime(m_stream);
-
-    return 0.0;//!!!
+    
+    pa_usec_t usec = 0;
+    pa_stream_get_time(m_stream, &usec);
+    return usec / 1000000.f;
 }
 
 void
@@ -157,6 +158,19 @@
 
     QMutexLocker locker(&m_mutex);
 
+    if (m_source->getTargetPlayLatency() == 0) { //!!! need better test
+            //!!!
+            pa_usec_t latency = 0;
+            int negative = 0;
+            if (pa_stream_get_latency(m_stream, &latency, &negative)) {
+                std::cerr << "AudioPulseAudioTarget::contextStateChanged: Failed to query latency" << std::endl;
+            }
+            std::cerr << "Latency = " << latency << " usec" << std::endl;
+            int latframes = (latency / 1000000.f) * float(m_sampleRate);
+            std::cerr << "that's " << latframes << " frames" << std::endl;
+            m_source->setTargetPlayLatency(latframes); //!!! buh
+    }
+
     if (nframes > m_bufferSize) {
         std::cerr << "WARNING: AudioPulseAudioTarget::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << std::endl;
     }
@@ -311,6 +325,7 @@
             break;
 
         case PA_CONTEXT_READY:
+        {
             std::cerr << "AudioPulseAudioTarget::contextStateChanged: Ready"
                       << std::endl;
 
@@ -320,27 +335,40 @@
             pa_stream_set_state_callback(m_stream, streamStateChangedStatic, this);
             pa_stream_set_write_callback(m_stream, streamWriteStatic, this);
 
-            if (!pa_stream_connect_playback(m_stream, 0, 0, pa_stream_flags_t(0), 0, 0)) {
+            if (pa_stream_connect_playback
+                (m_stream, 0, 0,
+                 pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING |
+                                   PA_STREAM_AUTO_TIMING_UPDATE),
+                 0, 0)) { //??? return value
                 std::cerr << "AudioPulseAudioTarget: Failed to connect playback stream" << std::endl;
-                break;
             }
 
+            pa_usec_t latency = 0;
+            int negative = 0;
+            if (pa_stream_get_latency(m_stream, &latency, &negative)) {
+                std::cerr << "AudioPulseAudioTarget::contextStateChanged: Failed to query latency" << std::endl;
+            }
+            std::cerr << "Latency = " << latency << " usec" << std::endl;
+            int latframes = (latency / 1000000.f) * float(m_sampleRate);
+            std::cerr << "that's " << latframes << " frames" << std::endl;
+
             const pa_buffer_attr *attr;
             if (!(attr = pa_stream_get_buffer_attr(m_stream))) {
                 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Cannot query stream buffer attributes" << std::endl;
                 m_source->setTarget(this, 4096);
                 m_source->setTargetSampleRate(m_sampleRate);
-                m_source->setTargetPlayLatency(4096);
+                m_source->setTargetPlayLatency(latframes);
             } else {
                 std::cerr << "AudioPulseAudioTarget::contextStateChanged: stream max length = " << attr->maxlength << std::endl;
                 int latency = attr->tlength;
                 std::cerr << "latency = " << latency << std::endl;
                 m_source->setTarget(this, attr->maxlength);
                 m_source->setTargetSampleRate(m_sampleRate);
-                m_source->setTargetPlayLatency(latency);
+                m_source->setTargetPlayLatency(latframes);
             }
 
             break;
+        }
 
         case PA_CONTEXT_TERMINATED:
             std::cerr << "AudioPulseAudioTarget::contextStateChanged: Terminated" << std::endl;
--- a/audioio/AudioPulseAudioTarget.h	Wed May 21 16:54:24 2008 +0000
+++ b/audioio/AudioPulseAudioTarget.h	Wed May 21 17:11:57 2008 +0000
@@ -22,7 +22,7 @@
 
 #include <QObject>
 #include <QMutex>
-#include <QThread>
+#include "base/Thread.h"
 
 #include "AudioCallbackPlayTarget.h"
 
@@ -56,10 +56,10 @@
 
     QMutex m_mutex;
 
-    class MainLoopThread : public QThread
+    class MainLoopThread : public Thread
     {
     public:
-        MainLoopThread(pa_mainloop *loop) : m_loop(loop) { }
+        MainLoopThread(pa_mainloop *loop) : Thread(RTThread), m_loop(loop) { }
         virtual void run() {
             int rv = 0;
             pa_mainloop_run(m_loop, &rv); //!!! check return value from this, and rv