1
/* Copyright (C) 2005-2008, Thorvald Natvig <thorvald@natvig.com>
1
/* Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
2
2
Copyright (C) 2007, Stefan Gehn <mETz AT gehn DOT net>
40
40
virtual AudioInput *create();
41
41
virtual const QList<audioDevice> getDeviceChoices();
42
42
virtual void setDeviceChoice(const QVariant &, Settings &);
43
virtual bool canEcho(const QString &);
43
virtual bool canEcho(const QString &) const;
46
46
class PortAudioOutputRegistrar : public AudioOutputRegistrar {
335
335
err = Pa_ReadStream(inputStream, psMic, iFrameSize);
336
336
if (err == paNoError) {
337
337
encodeAudioFrame();
338
} else if (err == paInputOverflow) {
338
} else if (err == paInputOverflowed) {
339
339
qWarning("PortAudioInput: Overflow on PortAudio input-stream, we lost incoming data!");
340
340
} else { // other error, aborg
341
341
qWarning("PortAudioInput: Could not read from PortAudio stream, error %s", Pa_GetErrorText(err));
368
368
//TODO: redo this without busy waiting if possible
369
369
void PortAudioOutput::run() {
370
370
PaStream *outputStream = 0;
371
bool hasMoreToMix = true;
372
371
PaError err = paNoError;
375
375
if (!PortAudioSystem::initStream(&outputStream, g.s.iPortAudioOutput, iFrameSize, &chans, false))
376
376
return; // PA initialization or stream opening failed, we will give up
386
386
initializeMixer(cmask);
388
388
short outBuffer[iFrameSize * iChannels];
389
memset(outBuffer, 0, sizeof(short) * iFrameSize * iChannels);
391
// Get rid of crackling noise when starting the stream.
392
if (PortAudioSystem::startStream(outputStream)) {
393
err = Pa_WriteStream(outputStream, outBuffer, iFrameSize);
394
if (err != paNoError) {
395
qWarning("PortAudioOutput: Could not write to PortAudio stream, error: %s", Pa_GetErrorText(err));
401
390
while (bRunning) {
402
bool nextHasMoreToMix = mix(outBuffer, iFrameSize);
404
if (PortAudioSystem::startStream(outputStream)) {
405
err = Pa_WriteStream(outputStream, outBuffer, iFrameSize);
406
if (err != paNoError) {
407
qWarning("PortAudioOutput: Could not write to PortAudio stream, error %s", Pa_GetErrorText(err));
394
memset(outBuffer, 0, sizeof(short) * iFrameSize * iChannels);
396
avail = mix(outBuffer, iFrameSize);
399
if (! PortAudioSystem::startStream(outputStream)) {
403
err = Pa_WriteStream(outputStream, outBuffer, iFrameSize);
404
if (err == paOutputUnderflowed) {
405
qWarning("PortAudioOutput: Output underflowed. Attempting graceful recovery.");
408
} else if (err != paNoError) {
409
qWarning("PortAudioOutput: Could not write to PortAudio stream, error %s", Pa_GetErrorText(err));
413
if (!PortAudioSystem::stopStream(outputStream))
413
if (! PortAudioSystem::stopStream(outputStream))
414
414
bRunning = false;
415
this->msleep(20); // 20ms wait to avoid hogging the cpu too much
417
hasMoreToMix = nextHasMoreToMix;
420
// ignoring return value of terminateStream, we cannot do anything about it anyway
421
421
PortAudioSystem::terminateStream(outputStream);
422
outputStream = 0; // just for gdb sessions
422
outputStream = NULL; // just for gdb sessions