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