comparison audioio/AudioPulseAudioTarget.cpp @ 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
comparison
equal deleted inserted replaced
117:2bc8bf6d016c 118:c41e340dfe8d
51 51
52 m_api = pa_mainloop_get_api(m_loop); 52 m_api = pa_mainloop_get_api(m_loop);
53 53
54 //!!! handle signals how? 54 //!!! handle signals how?
55 55
56 m_bufferSize = 2048; 56 m_bufferSize = 20480;
57 m_sampleRate = 44100; 57 m_sampleRate = 44100;
58 if (m_source && (m_source->getSourceSampleRate() != 0)) { 58 if (m_source && (m_source->getSourceSampleRate() != 0)) {
59 m_sampleRate = m_source->getSourceSampleRate(); 59 m_sampleRate = m_source->getSourceSampleRate();
60 } 60 }
61 m_spec.rate = m_sampleRate; 61 m_spec.rate = m_sampleRate;
122 122
123 double 123 double
124 AudioPulseAudioTarget::getCurrentTime() const 124 AudioPulseAudioTarget::getCurrentTime() const
125 { 125 {
126 if (!m_stream) return 0.0; 126 if (!m_stream) return 0.0;
127 //!!! else return Pa_GetStreamTime(m_stream); 127
128 128 pa_usec_t usec = 0;
129 return 0.0;//!!! 129 pa_stream_get_time(m_stream, &usec);
130 return usec / 1000000.f;
130 } 131 }
131 132
132 void 133 void
133 AudioPulseAudioTarget::sourceModelReplaced() 134 AudioPulseAudioTarget::sourceModelReplaced()
134 { 135 {
154 std::cout << "AudioPulseAudioTarget::streamWrite(" << nframes << ")" << std::endl; 155 std::cout << "AudioPulseAudioTarget::streamWrite(" << nframes << ")" << std::endl;
155 #endif 156 #endif
156 if (m_done) return; 157 if (m_done) return;
157 158
158 QMutexLocker locker(&m_mutex); 159 QMutexLocker locker(&m_mutex);
160
161 if (m_source->getTargetPlayLatency() == 0) { //!!! need better test
162 //!!!
163 pa_usec_t latency = 0;
164 int negative = 0;
165 if (pa_stream_get_latency(m_stream, &latency, &negative)) {
166 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Failed to query latency" << std::endl;
167 }
168 std::cerr << "Latency = " << latency << " usec" << std::endl;
169 int latframes = (latency / 1000000.f) * float(m_sampleRate);
170 std::cerr << "that's " << latframes << " frames" << std::endl;
171 m_source->setTargetPlayLatency(latframes); //!!! buh
172 }
159 173
160 if (nframes > m_bufferSize) { 174 if (nframes > m_bufferSize) {
161 std::cerr << "WARNING: AudioPulseAudioTarget::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << std::endl; 175 std::cerr << "WARNING: AudioPulseAudioTarget::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << std::endl;
162 } 176 }
163 177
309 case PA_CONTEXT_AUTHORIZING: 323 case PA_CONTEXT_AUTHORIZING:
310 case PA_CONTEXT_SETTING_NAME: 324 case PA_CONTEXT_SETTING_NAME:
311 break; 325 break;
312 326
313 case PA_CONTEXT_READY: 327 case PA_CONTEXT_READY:
328 {
314 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Ready" 329 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Ready"
315 << std::endl; 330 << std::endl;
316 331
317 m_stream = pa_stream_new(m_context, "stream", &m_spec, 0); 332 m_stream = pa_stream_new(m_context, "stream", &m_spec, 0);
318 assert(m_stream); //!!! 333 assert(m_stream); //!!!
319 334
320 pa_stream_set_state_callback(m_stream, streamStateChangedStatic, this); 335 pa_stream_set_state_callback(m_stream, streamStateChangedStatic, this);
321 pa_stream_set_write_callback(m_stream, streamWriteStatic, this); 336 pa_stream_set_write_callback(m_stream, streamWriteStatic, this);
322 337
323 if (!pa_stream_connect_playback(m_stream, 0, 0, pa_stream_flags_t(0), 0, 0)) { 338 if (pa_stream_connect_playback
339 (m_stream, 0, 0,
340 pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING |
341 PA_STREAM_AUTO_TIMING_UPDATE),
342 0, 0)) { //??? return value
324 std::cerr << "AudioPulseAudioTarget: Failed to connect playback stream" << std::endl; 343 std::cerr << "AudioPulseAudioTarget: Failed to connect playback stream" << std::endl;
325 break;
326 } 344 }
345
346 pa_usec_t latency = 0;
347 int negative = 0;
348 if (pa_stream_get_latency(m_stream, &latency, &negative)) {
349 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Failed to query latency" << std::endl;
350 }
351 std::cerr << "Latency = " << latency << " usec" << std::endl;
352 int latframes = (latency / 1000000.f) * float(m_sampleRate);
353 std::cerr << "that's " << latframes << " frames" << std::endl;
327 354
328 const pa_buffer_attr *attr; 355 const pa_buffer_attr *attr;
329 if (!(attr = pa_stream_get_buffer_attr(m_stream))) { 356 if (!(attr = pa_stream_get_buffer_attr(m_stream))) {
330 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Cannot query stream buffer attributes" << std::endl; 357 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Cannot query stream buffer attributes" << std::endl;
331 m_source->setTarget(this, 4096); 358 m_source->setTarget(this, 4096);
332 m_source->setTargetSampleRate(m_sampleRate); 359 m_source->setTargetSampleRate(m_sampleRate);
333 m_source->setTargetPlayLatency(4096); 360 m_source->setTargetPlayLatency(latframes);
334 } else { 361 } else {
335 std::cerr << "AudioPulseAudioTarget::contextStateChanged: stream max length = " << attr->maxlength << std::endl; 362 std::cerr << "AudioPulseAudioTarget::contextStateChanged: stream max length = " << attr->maxlength << std::endl;
336 int latency = attr->tlength; 363 int latency = attr->tlength;
337 std::cerr << "latency = " << latency << std::endl; 364 std::cerr << "latency = " << latency << std::endl;
338 m_source->setTarget(this, attr->maxlength); 365 m_source->setTarget(this, attr->maxlength);
339 m_source->setTargetSampleRate(m_sampleRate); 366 m_source->setTargetSampleRate(m_sampleRate);
340 m_source->setTargetPlayLatency(latency); 367 m_source->setTargetPlayLatency(latframes);
341 } 368 }
342 369
343 break; 370 break;
371 }
344 372
345 case PA_CONTEXT_TERMINATED: 373 case PA_CONTEXT_TERMINATED:
346 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Terminated" << std::endl; 374 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Terminated" << std::endl;
347 //!!! do something... 375 //!!! do something...
348 break; 376 break;