Mercurial > hg > svapp
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; |