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