comparison audioio/AudioPulseAudioTarget.cpp @ 191:3bd87e04f060

* Move query for latency and other stream attributes from contextStateChanged to streamStateChanged (they did not work previously, as they were trying to query the stream too soon)
author Chris Cannam
date Tue, 15 Jun 2010 11:36:02 +0000
parents 386b02c926bf
children 2b1869fccec1
comparison
equal deleted inserted replaced
190:68a0a2625a66 191:3bd87e04f060
303 case PA_STREAM_CREATING: 303 case PA_STREAM_CREATING:
304 case PA_STREAM_TERMINATED: 304 case PA_STREAM_TERMINATED:
305 break; 305 break;
306 306
307 case PA_STREAM_READY: 307 case PA_STREAM_READY:
308 {
308 std::cerr << "AudioPulseAudioTarget::streamStateChanged: Ready" << std::endl; 309 std::cerr << "AudioPulseAudioTarget::streamStateChanged: Ready" << std::endl;
310
311 pa_usec_t latency = 0;
312 int negative = 0;
313 if (pa_stream_get_latency(m_stream, &latency, &negative)) {
314 std::cerr << "AudioPulseAudioTarget::streamStateChanged: Failed to query latency" << std::endl;
315 }
316 std::cerr << "Latency = " << latency << " usec" << std::endl;
317 int latframes = (latency / 1000000.f) * float(m_sampleRate);
318 std::cerr << "that's " << latframes << " frames" << std::endl;
319
320 const pa_buffer_attr *attr;
321 if (!(attr = pa_stream_get_buffer_attr(m_stream))) {
322 std::cerr << "AudioPulseAudioTarget::streamStateChanged: Cannot query stream buffer attributes" << std::endl;
323 m_source->setTarget(this, m_bufferSize);
324 m_source->setTargetSampleRate(m_sampleRate);
325 m_source->setTargetPlayLatency(latframes);
326 } else {
327 std::cerr << "AudioPulseAudioTarget::streamStateChanged: stream max length = " << attr->maxlength << std::endl;
328 int latency = attr->tlength;
329 std::cerr << "latency = " << latency << std::endl;
330 m_source->setTarget(this, attr->maxlength);
331 m_source->setTargetSampleRate(m_sampleRate);
332 m_source->setTargetPlayLatency(latframes);
333 }
334 }
309 break; 335 break;
310 336
311 case PA_STREAM_FAILED: 337 case PA_STREAM_FAILED:
312 default: 338 default:
313 std::cerr << "AudioPulseAudioTarget::streamStateChanged: Error: " 339 std::cerr << "AudioPulseAudioTarget::streamStateChanged: Error: "
342 case PA_CONTEXT_AUTHORIZING: 368 case PA_CONTEXT_AUTHORIZING:
343 case PA_CONTEXT_SETTING_NAME: 369 case PA_CONTEXT_SETTING_NAME:
344 break; 370 break;
345 371
346 case PA_CONTEXT_READY: 372 case PA_CONTEXT_READY:
347 {
348 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Ready" 373 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Ready"
349 << std::endl; 374 << std::endl;
350 375
351 m_stream = pa_stream_new(m_context, "stream", &m_spec, 0); 376 m_stream = pa_stream_new(m_context, "stream", &m_spec, 0);
352 assert(m_stream); //!!! 377 assert(m_stream); //!!!
353 378
354 pa_stream_set_state_callback(m_stream, streamStateChangedStatic, this); 379 pa_stream_set_state_callback(m_stream, streamStateChangedStatic, this);
355 pa_stream_set_write_callback(m_stream, streamWriteStatic, this); 380 pa_stream_set_write_callback(m_stream, streamWriteStatic, this);
356 pa_stream_set_overflow_callback(m_stream, streamOverflowStatic, this); 381 pa_stream_set_overflow_callback(m_stream, streamOverflowStatic, this);
357 pa_stream_set_underflow_callback(m_stream, streamUnderflowStatic, this); 382 pa_stream_set_underflow_callback(m_stream, streamUnderflowStatic, this);
358
359 if (pa_stream_connect_playback 383 if (pa_stream_connect_playback
360 (m_stream, 0, 0, 384 (m_stream, 0, 0,
361 pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING | 385 pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING |
362 PA_STREAM_AUTO_TIMING_UPDATE), 386 PA_STREAM_AUTO_TIMING_UPDATE),
363 0, 0)) { //??? return value 387 0, 0)) { //??? return value
364 std::cerr << "AudioPulseAudioTarget: Failed to connect playback stream" << std::endl; 388 std::cerr << "AudioPulseAudioTarget: Failed to connect playback stream" << std::endl;
365 } 389 }
366 390
367 pa_usec_t latency = 0; 391 break;
368 int negative = 0;
369 if (pa_stream_get_latency(m_stream, &latency, &negative)) {
370 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Failed to query latency" << std::endl;
371 }
372 std::cerr << "Latency = " << latency << " usec" << std::endl;
373 int latframes = (latency / 1000000.f) * float(m_sampleRate);
374 std::cerr << "that's " << latframes << " frames" << std::endl;
375
376 const pa_buffer_attr *attr;
377 if (!(attr = pa_stream_get_buffer_attr(m_stream))) {
378 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Cannot query stream buffer attributes" << std::endl;
379 m_source->setTarget(this, 4096);
380 m_source->setTargetSampleRate(m_sampleRate);
381 m_source->setTargetPlayLatency(latframes);
382 } else {
383 std::cerr << "AudioPulseAudioTarget::contextStateChanged: stream max length = " << attr->maxlength << std::endl;
384 int latency = attr->tlength;
385 std::cerr << "latency = " << latency << std::endl;
386 m_source->setTarget(this, attr->maxlength);
387 m_source->setTargetSampleRate(m_sampleRate);
388 m_source->setTargetPlayLatency(latframes);
389 }
390
391 break;
392 }
393 392
394 case PA_CONTEXT_TERMINATED: 393 case PA_CONTEXT_TERMINATED:
395 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Terminated" << std::endl; 394 std::cerr << "AudioPulseAudioTarget::contextStateChanged: Terminated" << std::endl;
396 //!!! do something... 395 //!!! do something...
397 break; 396 break;