Mercurial > hg > svapp
comparison audioio/AudioPulseAudioTarget.cpp @ 120:2aa263b384f8
* Fix to PulseAudio output -- it works rather better now it's being fed
the right number of samples and not 8 times as many
author | Chris Cannam |
---|---|
date | Fri, 23 May 2008 15:36:20 +0000 |
parents | 1ba557a20ca3 |
children | 4c9c04645685 |
comparison
equal
deleted
inserted
replaced
119:1ba557a20ca3 | 120:2aa263b384f8 |
---|---|
22 | 22 |
23 #include <iostream> | 23 #include <iostream> |
24 #include <cassert> | 24 #include <cassert> |
25 #include <cmath> | 25 #include <cmath> |
26 | 26 |
27 #define DEBUG_AUDIO_PULSE_AUDIO_TARGET 1 | 27 //#define DEBUG_AUDIO_PULSE_AUDIO_TARGET 1 |
28 | 28 |
29 AudioPulseAudioTarget::AudioPulseAudioTarget(AudioCallbackPlaySource *source) : | 29 AudioPulseAudioTarget::AudioPulseAudioTarget(AudioCallbackPlaySource *source) : |
30 AudioCallbackPlayTarget(source), | 30 AudioCallbackPlayTarget(source), |
31 m_mutex(QMutex::Recursive), | 31 m_mutex(QMutex::Recursive), |
32 m_loop(0), | 32 m_loop(0), |
147 | 147 |
148 target->streamWrite(length); | 148 target->streamWrite(length); |
149 } | 149 } |
150 | 150 |
151 void | 151 void |
152 AudioPulseAudioTarget::streamWrite(size_t nframes) | 152 AudioPulseAudioTarget::streamWrite(size_t requested) |
153 { | 153 { |
154 #ifdef DEBUG_AUDIO_PULSE_AUDIO_TARGET | 154 #ifdef DEBUG_AUDIO_PULSE_AUDIO_TARGET |
155 std::cout << "AudioPulseAudioTarget::streamWrite(" << nframes << ")" << std::endl; | 155 std::cout << "AudioPulseAudioTarget::streamWrite(" << requested << ")" << std::endl; |
156 #endif | 156 #endif |
157 if (m_done) return; | 157 if (m_done) return; |
158 | 158 |
159 QMutexLocker locker(&m_mutex); | 159 QMutexLocker locker(&m_mutex); |
160 | 160 |
169 int latframes = (latency / 1000000.f) * float(m_sampleRate); | 169 int latframes = (latency / 1000000.f) * float(m_sampleRate); |
170 std::cerr << "that's " << latframes << " frames" << std::endl; | 170 std::cerr << "that's " << latframes << " frames" << std::endl; |
171 m_source->setTargetPlayLatency(latframes); //!!! buh | 171 m_source->setTargetPlayLatency(latframes); //!!! buh |
172 } | 172 } |
173 | 173 |
174 if (nframes > m_bufferSize) { | |
175 std::cerr << "WARNING: AudioPulseAudioTarget::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << std::endl; | |
176 } | |
177 | |
178 static float *output = 0; | 174 static float *output = 0; |
179 static float **tmpbuf = 0; | 175 static float **tmpbuf = 0; |
180 static size_t tmpbufch = 0; | 176 static size_t tmpbufch = 0; |
181 static size_t tmpbufsz = 0; | 177 static size_t tmpbufsz = 0; |
182 | 178 |
183 size_t sourceChannels = m_source->getSourceChannelCount(); | 179 size_t sourceChannels = m_source->getSourceChannelCount(); |
184 | 180 |
185 // Because we offer pan, we always want at least 2 channels | 181 // Because we offer pan, we always want at least 2 channels |
186 if (sourceChannels < 2) sourceChannels = 2; | 182 if (sourceChannels < 2) sourceChannels = 2; |
183 | |
184 size_t nframes = requested / (sourceChannels * sizeof(float)); | |
185 | |
186 if (nframes > m_bufferSize) { | |
187 std::cerr << "WARNING: AudioPulseAudioTarget::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << std::endl; | |
188 } | |
189 | |
190 #ifdef DEBUG_AUDIO_PULSE_AUDIO_TARGET | |
191 std::cout << "AudioPulseAudioTarget::streamWrite: nframes = " << nframes << std::endl; | |
192 #endif | |
187 | 193 |
188 if (!tmpbuf || tmpbufch != sourceChannels || int(tmpbufsz) < nframes) { | 194 if (!tmpbuf || tmpbufch != sourceChannels || int(tmpbufsz) < nframes) { |
189 | 195 |
190 if (tmpbuf) { | 196 if (tmpbuf) { |
191 for (size_t i = 0; i < tmpbufch; ++i) { | 197 for (size_t i = 0; i < tmpbufch; ++i) { |
209 output = new float[tmpbufsz * tmpbufch]; | 215 output = new float[tmpbufsz * tmpbufch]; |
210 } | 216 } |
211 | 217 |
212 size_t received = m_source->getSourceSamples(nframes, tmpbuf); | 218 size_t received = m_source->getSourceSamples(nframes, tmpbuf); |
213 | 219 |
220 #ifdef DEBUG_AUDIO_PULSE_AUDIO_TARGET | |
214 std::cerr << "requested " << nframes << ", received " << received << std::endl; | 221 std::cerr << "requested " << nframes << ", received " << received << std::endl; |
222 | |
215 if (received < nframes) { | 223 if (received < nframes) { |
216 std::cerr << "*** WARNING: Wrong number of frames received" << std::endl; | 224 std::cerr << "*** WARNING: Wrong number of frames received" << std::endl; |
217 } | 225 } |
226 #endif | |
218 | 227 |
219 float peakLeft = 0.0, peakRight = 0.0; | 228 float peakLeft = 0.0, peakRight = 0.0; |
220 | 229 |
221 for (size_t ch = 0; ch < 2; ++ch) { | 230 for (size_t ch = 0; ch < 2; ++ch) { |
222 | 231 |
255 | 264 |
256 if (ch == 0) peakLeft = peak; | 265 if (ch == 0) peakLeft = peak; |
257 if (ch > 0 || sourceChannels == 1) peakRight = peak; | 266 if (ch > 0 || sourceChannels == 1) peakRight = peak; |
258 } | 267 } |
259 | 268 |
269 #ifdef DEBUG_AUDIO_PULSE_AUDIO_TARGET | |
270 std::cerr << "calling pa_stream_write with " | |
271 << nframes * tmpbufch * sizeof(float) << " bytes" << std::endl; | |
272 #endif | |
273 | |
260 pa_stream_write(m_stream, output, nframes * tmpbufch * sizeof(float), | 274 pa_stream_write(m_stream, output, nframes * tmpbufch * sizeof(float), |
261 0, 0, PA_SEEK_RELATIVE); | 275 0, 0, PA_SEEK_RELATIVE); |
262 | 276 |
263 m_source->setOutputLevels(peakLeft, peakRight); | 277 m_source->setOutputLevels(peakLeft, peakRight); |
264 | 278 |
337 m_stream = pa_stream_new(m_context, "stream", &m_spec, 0); | 351 m_stream = pa_stream_new(m_context, "stream", &m_spec, 0); |
338 assert(m_stream); //!!! | 352 assert(m_stream); //!!! |
339 | 353 |
340 pa_stream_set_state_callback(m_stream, streamStateChangedStatic, this); | 354 pa_stream_set_state_callback(m_stream, streamStateChangedStatic, this); |
341 pa_stream_set_write_callback(m_stream, streamWriteStatic, this); | 355 pa_stream_set_write_callback(m_stream, streamWriteStatic, this); |
356 pa_stream_set_overflow_callback(m_stream, streamOverflowStatic, this); | |
357 pa_stream_set_underflow_callback(m_stream, streamUnderflowStatic, this); | |
342 | 358 |
343 if (pa_stream_connect_playback | 359 if (pa_stream_connect_playback |
344 (m_stream, 0, 0, | 360 (m_stream, 0, 0, |
345 pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING | | 361 pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING | |
346 PA_STREAM_AUTO_TIMING_UPDATE), | 362 PA_STREAM_AUTO_TIMING_UPDATE), |
387 //!!! do something... | 403 //!!! do something... |
388 break; | 404 break; |
389 } | 405 } |
390 } | 406 } |
391 | 407 |
408 void | |
409 AudioPulseAudioTarget::streamOverflowStatic(pa_stream *, void *) | |
410 { | |
411 std::cerr << "AudioPulseAudioTarget::streamOverflowStatic: Overflow!" << std::endl; | |
412 } | |
413 | |
414 void | |
415 AudioPulseAudioTarget::streamUnderflowStatic(pa_stream *, void *) | |
416 { | |
417 std::cerr << "AudioPulseAudioTarget::streamUnderflowStatic: Underflow!" << std::endl; | |
418 } | |
419 | |
392 #endif /* HAVE_PULSEAUDIO */ | 420 #endif /* HAVE_PULSEAUDIO */ |
393 | 421 |