# HG changeset patch # User Chris Cannam # Date 1211389917 0 # Node ID c41e340dfe8d644c70f823d17457e70186c10b73 # Parent 2bc8bf6d016c153993fa692a74703fca34233c28 * timing updates; still much to be done diff -r 2bc8bf6d016c -r c41e340dfe8d audioio/AudioPulseAudioTarget.cpp --- 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; diff -r 2bc8bf6d016c -r c41e340dfe8d audioio/AudioPulseAudioTarget.h --- 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 #include -#include +#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