@@ 21,7 21,7 @@ using std::endl;
namespace Turbot {
PulseAudioIO::PulseAudioIO(ApplicationRecordTarget *target,
- ApplicationPlaybackSource *source) :
+ ApplicationPlaybackSource *source) :
SystemAudioIO(target, source),
m_mutex(QMutex::Recursive), //!!!???
m_loop(0),
@@ 32,6 32,7 @@ PulseAudioIO::PulseAudioIO(ApplicationRe
m_loopThread(0),
m_bufferSize(0),
m_sampleRate(0),
+ m_paChannels(2),
m_done(false),
m_captureReady(false),
m_playbackReady(false)
@@ 56,7 57,7 @@ PulseAudioIO::PulseAudioIO(ApplicationRe
m_sampleRate = m_source->getApplicationSampleRate();
}
m_spec.rate = m_sampleRate;
- m_spec.channels = 2;
+ m_spec.channels = m_paChannels;
m_spec.format = PA_SAMPLE_FLOAT32NE;
m_context = pa_context_new(m_api, "turbot");
@@ 206,14 207,14 @@ PulseAudioIO::streamWrite(int requested)
tmpbuf[i] = new float[tmpbufsz];
}
- output = new float[tmpbufsz * tmpbufch];
+ output = new float[tmpbufsz * m_paChannels];
}
m_source->getSourceSamples(nframes, tmpbuf);
float peakLeft = 0.0, peakRight = 0.0;
- for (int ch = 0; ch < 2; ++ch) {
+ for (int ch = 0; ch < m_paChannels; ++ch) {
float peak = 0.0;
@@ 221,22 222,22 @@ PulseAudioIO::streamWrite(int requested)
// PulseAudio samples are interleaved
for (int i = 0; i < nframes; ++i) {
- output[i * 2 + ch] = tmpbuf[ch][i] * m_outputGain;
- float sample = fabsf(output[i * 2 + ch]);
+ output[i * m_paChannels + ch] = tmpbuf[ch][i] * m_outputGain;
+ float sample = fabsf(output[i * m_paChannels + ch]);
if (sample > peak) peak = sample;
}
} else if (ch == 1 && sourceChannels == 1) {
for (int i = 0; i < nframes; ++i) {
- output[i * 2 + ch] = tmpbuf[0][i] * m_outputGain;
- float sample = fabsf(output[i * 2 + ch]);
+ output[i * m_paChannels + ch] = tmpbuf[0][i] * m_outputGain;
+ float sample = fabsf(output[i * m_paChannels + ch]);
if (sample > peak) peak = sample;
}
} else {
for (int i = 0; i < nframes; ++i) {
- output[i * 2 + ch] = 0;
+ output[i * m_paChannels + ch] = 0;
}
}
@@ 381,7 382,7 @@ PulseAudioIO::streamStateChanged(pa_stre
cerr << "PulseAudioIO::streamStateChanged" << endl;
#endif
- assert(stream == m_in || stream == m_out);
+ assert(stream == m_out);
QMutexLocker locker(&m_mutex);
@@ 3,9 3,8 @@
#ifdef HAVE_LIBPULSE
-#include "PulseAudioIO.h"
+#include "PulseAudioPlaybackTarget.h"
#include "ApplicationPlaybackSource.h"
-#include "ApplicationRecordTarget.h"
#include "VectorOps.h"
@@ 16,33 15,31 @@ using std::cerr;
using std::cout;
using std::endl;
-//#define DEBUG_AUDIO_PULSE_AUDIO_IO 1
+//#define DEBUG_PULSE_AUDIO_PLAYBACK_TARGET 1
namespace Turbot {
-PulseAudioIO::PulseAudioIO(ApplicationRecordTarget *target,
- ApplicationPlaybackSource *source) :
- SystemAudioIO(target, source),
+PulseAudioPlaybackTarget::PulseAudioPlaybackTarget(ApplicationPlaybackSource *source) :
+ SystemPlaybackTarget(source),
m_mutex(QMutex::Recursive), //!!!???
m_loop(0),
m_api(0),
m_context(0),
- m_in(0),
m_out(0),
m_loopThread(0),
m_bufferSize(0),
m_sampleRate(0),
+ m_paChannels(2),
m_done(false),
- m_captureReady(false),
m_playbackReady(false)
{
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
- cerr << "PulseAudioIO: Initialising for PulseAudio" << endl;
+#ifdef DEBUG_PULSE_AUDIO_PLAYBACK_TARGET
+ cerr << "PulseAudioPlaybackTarget: Initialising for PulseAudio" << endl;
#endif
m_loop = pa_mainloop_new();
if (!m_loop) {
- cerr << "ERROR: PulseAudioIO: Failed to create main loop" << endl;
+ cerr << "ERROR: PulseAudioPlaybackTarget: Failed to create main loop" << endl;
return;
}
@@ 56,12 53,12 @@ PulseAudioIO::PulseAudioIO(ApplicationRe
m_sampleRate = m_source->getApplicationSampleRate();
}
m_spec.rate = m_sampleRate;
- m_spec.channels = 2;
+ m_spec.channels = m_paChannels;
m_spec.format = PA_SAMPLE_FLOAT32NE;
m_context = pa_context_new(m_api, "turbot");
if (!m_context) {
- cerr << "ERROR: PulseAudioIO: Failed to create context object" << endl;
+ cerr << "ERROR: PulseAudioPlaybackTarget: Failed to create context object" << endl;
return;
}
@@ 72,14 69,14 @@ PulseAudioIO::PulseAudioIO(ApplicationRe
m_loopThread = new MainLoopThread(m_loop);
m_loopThread->start();
-#ifdef DEBUG_PULSE_AUDIO_IO
- cerr << "PulseAudioIO: initialised OK" << endl;
+#ifdef DEBUG_PULSE_AUDIO_PLAYBACK_TARGET
+ cerr << "PulseAudioPlaybackTarget: initialised OK" << endl;
#endif
}
-PulseAudioIO::~PulseAudioIO()
+PulseAudioPlaybackTarget::~PulseAudioPlaybackTarget()
{
- cerr << "PulseAudioIO::~PulseAudioIO()" << endl;
+ cerr << "PulseAudioPlaybackTarget::~PulseAudioPlaybackTarget()" << endl;
//!!! if (m_source) {
// m_source->setTarget(0, m_bufferSize);
@@ 89,7 86,6 @@ PulseAudioIO::~PulseAudioIO()
QMutexLocker locker(&m_mutex);
- if (m_in) pa_stream_unref(m_in);
if (m_out) pa_stream_unref(m_out);
if (m_context) pa_context_unref(m_context);
@@ 99,35 95,17 @@ PulseAudioIO::~PulseAudioIO()
pa_mainloop_free(m_loop);
}
- cerr << "PulseAudioIO::~PulseAudioIO() done" << endl;
+ cerr << "PulseAudioPlaybackTarget::~PulseAudioPlaybackTarget() done" << endl;
}
bool
-PulseAudioIO::isSourceOK() const
-{
- return (m_context != 0);
-}
-
-bool
-PulseAudioIO::isTargetOK() const
+PulseAudioPlaybackTarget::isTargetOK() const
{
return (m_context != 0);
}
-bool
-PulseAudioIO::isSourceReady() const
-{
- return m_captureReady;
-}
-
-bool
-PulseAudioIO::isTargetReady() const
-{
- return m_playbackReady;
-}
-
double
-PulseAudioIO::getCurrentTime() const
+PulseAudioPlaybackTarget::getCurrentTime() const
{
if (!m_out) return 0.0;
@@ 137,11 115,11 @@ PulseAudioIO::getCurrentTime() const
}
void
-PulseAudioIO::streamWriteStatic(pa_stream *stream,
- size_t length,
- void *data)
+PulseAudioPlaybackTarget::streamWriteStatic(pa_stream *stream,
+ size_t length,
+ void *data)
{
- PulseAudioIO *target = (PulseAudioIO *)data;
+ PulseAudioPlaybackTarget *target = (PulseAudioPlaybackTarget *)data;
assert(stream == target->m_out);
@@ 149,13 127,16 @@ PulseAudioIO::streamWriteStatic(pa_strea
}
void
-PulseAudioIO::streamWrite(int requested)
+PulseAudioPlaybackTarget::streamWrite(int requested)
{
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
- cout << "PulseAudioIO::streamWrite(" << requested << ")" << endl;
+#ifdef DEBUG_PULSE_AUDIO_PLAYBACK_TARGET
+ cout << "PulseAudioPlaybackTarget::streamWrite(" << requested << ")" << endl;
#endif
if (m_done) return;
+ // requested is a byte count for an interleaved buffer, so number
+ // of frames = requested / (channels * sizeof(float))
+
QMutexLocker locker(&m_mutex);
pa_usec_t latency = 0;
@@ 172,17 153,28 @@ PulseAudioIO::streamWrite(int requested)
int sourceChannels = m_source->getApplicationChannelCount();
if (sourceChannels == 0) {
+ //!!! but this is incredibly cpu-intensive and poor for
+ //!!! battery life, because it happens all the time when not
+ //!!! playing. should pause and resume the stream somehow
+ int samples = requested / sizeof(float);
+ output = new float[samples];
+ for (int i = 0; i < samples; ++i) {
+ output[i] = 0.f;
+ }
+ pa_stream_write(m_out, output, samples * sizeof(float),
+ 0, 0, PA_SEEK_RELATIVE);
+ m_source->setOutputLevels(0.f, 0.f);
return;
}
int nframes = requested / (sourceChannels * sizeof(float)); //!!! this should be dividing by how many channels PA thinks it has!
if (nframes > m_bufferSize) {
- cerr << "WARNING: PulseAudioIO::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << endl;
+ cerr << "WARNING: PulseAudioPlaybackTarget::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << endl;
}
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
- cout << "PulseAudioIO::streamWrite: nframes = " << nframes << endl;
+#ifdef DEBUG_PULSE_AUDIO_PLAYBACK_TARGET
+ cerr << "PulseAudioPlaybackTarget::streamWrite: nframes = " << nframes << endl;
#endif
if (!tmpbuf || tmpbufch != sourceChannels || int(tmpbufsz) < nframes) {
@@ 206,14 198,14 @@ PulseAudioIO::streamWrite(int requested)
tmpbuf[i] = new float[tmpbufsz];
}
- output = new float[tmpbufsz * tmpbufch];
+ output = new float[tmpbufsz * m_paChannels];
}
m_source->getSourceSamples(nframes, tmpbuf);
float peakLeft = 0.0, peakRight = 0.0;
- for (int ch = 0; ch < 2; ++ch) {
+ for (int ch = 0; ch < m_paChannels; ++ch) {
float peak = 0.0;
@@ 221,22 213,22 @@ PulseAudioIO::streamWrite(int requested)
// PulseAudio samples are interleaved
for (int i = 0; i < nframes; ++i) {
- output[i * 2 + ch] = tmpbuf[ch][i] * m_outputGain;
- float sample = fabsf(output[i * 2 + ch]);
+ output[i * m_paChannels + ch] = tmpbuf[ch][i] * m_outputGain;
+ float sample = fabsf(output[i * m_paChannels + ch]);
if (sample > peak) peak = sample;
}
} else if (ch == 1 && sourceChannels == 1) {
for (int i = 0; i < nframes; ++i) {
- output[i * 2 + ch] = tmpbuf[0][i] * m_outputGain;
- float sample = fabsf(output[i * 2 + ch]);
+ output[i * m_paChannels + ch] = tmpbuf[0][i] * m_outputGain;
+ float sample = fabsf(output[i * m_paChannels + ch]);
if (sample > peak) peak = sample;
}
} else {
for (int i = 0; i < nframes; ++i) {
- output[i * 2 + ch] = 0;
+ output[i * m_paChannels + ch] = 0;
}
}
@@ 244,7 236,7 @@ PulseAudioIO::streamWrite(int requested)
if (ch > 0 || sourceChannels == 1) peakRight = peak;
}
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
+#ifdef DEBUG_PULSE_AUDIO_PLAYBACK_TARGET
cerr << "calling pa_stream_write with "
<< nframes * tmpbufch * sizeof(float) << " bytes" << endl;
#endif
@@ 252,136 244,32 @@ PulseAudioIO::streamWrite(int requested)
pa_stream_write(m_out, output, nframes * tmpbufch * sizeof(float),
0, 0, PA_SEEK_RELATIVE);
+// cerr << "peaks: " << peakLeft << ", " << peakRight << endl;
+
m_source->setOutputLevels(peakLeft, peakRight);
return;
}
void
-PulseAudioIO::streamReadStatic(pa_stream *stream,
- size_t length,
- void *data)
-{
- PulseAudioIO *target = (PulseAudioIO *)data;
-
- assert(stream == target->m_in);
-
- target->streamRead(length);
-}
-
-void
-PulseAudioIO::streamRead(int available)
-{
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
- cerr << "PulseAudioIO::streamRead(" << available << ")" << endl;
-#endif
-
- QMutexLocker locker(&m_mutex);
-
- pa_usec_t latency = 0;
- int negative = 0;
- if (!pa_stream_get_latency(m_in, &latency, &negative)) {
- int latframes = (latency / 1000000.f) * float(m_sampleRate);
- if (latframes > 0) m_target->setSystemRecordLatency(latframes);
- }
-
- int sz = pa_stream_readable_size(m_in);
-
- static const void *input = 0;
- static float **tmpbuf = 0;
- static int tmpbufch = 0;
- static int tmpbufsz = 0;
-
- int targetChannels = m_target->getApplicationChannelCount();
-
- //!!! need to handle mismatches between our and PA's expectations!
-
- if (targetChannels < 2) targetChannels = 2;
-
- int nframes = available / (targetChannels * sizeof(float)); //!!! this should be dividing by how many channels PA thinks it has!
-
- if (nframes > m_bufferSize) {
- cerr << "WARNING: PulseAudioIO::streamRead: nframes " << nframes << " > m_bufferSize " << m_bufferSize << endl;
- }
-
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
- cout << "PulseAudioIO::streamRead: nframes = " << nframes << endl;
-#endif
-
- if (!tmpbuf || tmpbufch != targetChannels || int(tmpbufsz) < nframes) {
-
- if (tmpbuf) {
- for (int i = 0; i < tmpbufch; ++i) {
- delete[] tmpbuf[i];
- }
- delete[] tmpbuf;
- }
-
- tmpbufch = targetChannels;
- tmpbufsz = nframes;
- tmpbuf = new float *[tmpbufch];
-
- for (int i = 0; i < tmpbufch; ++i) {
- tmpbuf[i] = new float[tmpbufsz];
- }
- }
-
- float peakLeft = 0.0, peakRight = 0.0;
-
- size_t actual = available;
-
- pa_stream_peek(m_in, &input, &actual);
-
- int actualFrames = actual / (targetChannels * sizeof(float)); //!!! this should be dividing by how many channels PA thinks it has!
-
- if (actualFrames < nframes) {
- cerr << "WARNING: streamRead: read " << actualFrames << " frames, expected " << nframes << endl;
- }
-
- const float *finput = (const float *)input;
-
- for (int ch = 0; ch < targetChannels; ++ch) {
-
- float peak = 0.0;
-
- // PulseAudio samples are interleaved
- for (int i = 0; i < nframes; ++i) {
- tmpbuf[ch][i] = finput[i * 2 + ch];
- float sample = fabsf(finput[i * 2 + ch]);
- if (sample > peak) peak = sample;
- }
-
- if (ch == 0) peakLeft = peak;
- if (ch > 0 || targetChannels == 1) peakRight = peak;
- }
-
- m_target->putSamples(nframes, tmpbuf);
- m_target->setInputLevels(peakLeft, peakRight);
-
- pa_stream_drop(m_in);
-
- return;
-}
-
-void
-PulseAudioIO::streamStateChangedStatic(pa_stream *stream,
+PulseAudioPlaybackTarget::streamStateChangedStatic(pa_stream *stream,
void *data)
{
- PulseAudioIO *target = (PulseAudioIO *)data;
+ PulseAudioPlaybackTarget *target = (PulseAudioPlaybackTarget *)data;
- assert(stream == target->m_in || stream == target->m_out);
+ assert(stream == target->m_out);
target->streamStateChanged(stream);
}
void
-PulseAudioIO::streamStateChanged(pa_stream *stream)
+PulseAudioPlaybackTarget::streamStateChanged(pa_stream *stream)
{
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
- cerr << "PulseAudioIO::streamStateChanged" << endl;
+#ifdef DEBUG_PULSE_AUDIO_PLAYBACK_TARGET
+ cerr << "PulseAudioPlaybackTarget::streamStateChanged" << endl;
#endif
- assert(stream == m_in || stream == m_out);
+ assert(stream == m_out);
QMutexLocker locker(&m_mutex);
@@ 393,18 281,12 @@ PulseAudioIO::streamStateChanged(pa_stre
case PA_STREAM_READY:
{
- if (stream == m_in) {
- cerr << "PulseAudioIO::streamStateChanged: Capture ready" << endl;
- m_captureReady = true;
- } else {
- cerr << "PulseAudioIO::streamStateChanged: Playback ready" << endl;
- m_playbackReady = true;
- }
+ m_playbackReady = true;
pa_usec_t latency = 0;
int negative = 0;
if (pa_stream_get_latency(m_out, &latency, &negative)) {
- cerr << "PulseAudioIO::contextStateChanged: Failed to query latency" << endl;
+ cerr << "PulseAudioPlaybackTarget::contextStateChanged: Failed to query latency" << endl;
}
cerr << "Latency = " << latency << " usec" << endl;
int latframes = (latency / 1000000.f) * float(m_sampleRate);
@@ 412,12 294,12 @@ PulseAudioIO::streamStateChanged(pa_stre
const pa_buffer_attr *attr;
if (!(attr = pa_stream_get_buffer_attr(m_out))) {
- cerr << "PulseAudioIO::streamStateChanged: Cannot query stream buffer attributes" << endl;
+ cerr << "PulseAudioPlaybackTarget::streamStateChanged: Cannot query stream buffer attributes" << endl;
m_source->setSystemPlaybackBlockSize(4096);
m_source->setSystemPlaybackSampleRate(m_sampleRate);
m_source->setSystemPlaybackLatency(latframes);
} else {
- cerr << "PulseAudioIO::streamStateChanged: stream max length = " << attr->maxlength << endl;
+ cerr << "PulseAudioPlaybackTarget::streamStateChanged: stream max length = " << attr->maxlength << endl;
int latency = attr->tlength;
cerr << "latency = " << latency << endl;
m_source->setSystemPlaybackBlockSize(attr->maxlength);
@@ 425,15 307,12 @@ PulseAudioIO::streamStateChanged(pa_stre
m_source->setSystemPlaybackLatency(latframes);
}
- cerr << "PulseAudioIO: setting system record sample rate to " << m_sampleRate << endl;
- m_target->setSystemRecordSampleRate(m_sampleRate);
-
break;
}
case PA_STREAM_FAILED:
default:
- cerr << "PulseAudioIO::streamStateChanged: Error: "
+ cerr << "PulseAudioPlaybackTarget::streamStateChanged: Error: "
<< pa_strerror(pa_context_errno(m_context)) << endl;
//!!! do something...
break;
@@ 441,10 320,10 @@ PulseAudioIO::streamStateChanged(pa_stre
}
void
-PulseAudioIO::contextStateChangedStatic(pa_context *context,
+PulseAudioPlaybackTarget::contextStateChangedStatic(pa_context *context,
void *data)
{
- PulseAudioIO *target = (PulseAudioIO *)data;
+ PulseAudioPlaybackTarget *target = (PulseAudioPlaybackTarget *)data;
assert(context == target->m_context);
@@ 452,10 331,10 @@ PulseAudioIO::contextStateChangedStatic(
}
void
-PulseAudioIO::contextStateChanged()
+PulseAudioPlaybackTarget::contextStateChanged()
{
-#ifdef DEBUG_AUDIO_PULSE_AUDIO_IO
- cerr << "PulseAudioIO::contextStateChanged" << endl;
+#ifdef DEBUG_PULSE_AUDIO_PLAYBACK_TARGET
+ cerr << "PulseAudioPlaybackTarget::contextStateChanged" << endl;
#endif
QMutexLocker locker(&m_mutex);
@@ 468,24 347,9 @@ PulseAudioIO::contextStateChanged()
case PA_CONTEXT_READY:
{
- cerr << "PulseAudioIO::contextStateChanged: Ready"
+ cerr << "PulseAudioPlaybackTarget::contextStateChanged: Ready"
<< endl;
- m_in = pa_stream_new(m_context, "Turbot capture", &m_spec, 0);
- assert(m_in); //!!!
-
- pa_stream_set_state_callback(m_in, streamStateChangedStatic, this);
- pa_stream_set_read_callback(m_in, streamReadStatic, this);
- pa_stream_set_overflow_callback(m_in, streamOverflowStatic, this);
- pa_stream_set_underflow_callback(m_in, streamUnderflowStatic, this);
-
- if (pa_stream_connect_record
- (m_in, 0, 0,
- pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING |
- PA_STREAM_AUTO_TIMING_UPDATE))) { //??? return value
- cerr << "PulseAudioIO: Failed to connect record stream" << endl;
- }
-
m_out = pa_stream_new(m_context, "Turbot playback", &m_spec, 0);
assert(m_out); //!!!
@@ 499,20 363,20 @@ PulseAudioIO::contextStateChanged()
pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING |
PA_STREAM_AUTO_TIMING_UPDATE),
0, 0)) { //??? return value
- cerr << "PulseAudioIO: Failed to connect playback stream" << endl;
+ cerr << "PulseAudioPlaybackTarget: Failed to connect playback stream" << endl;
}
break;
}
case PA_CONTEXT_TERMINATED:
- cerr << "PulseAudioIO::contextStateChanged: Terminated" << endl;
+ cerr << "PulseAudioPlaybackTarget::contextStateChanged: Terminated" << endl;
//!!! do something...
break;
case PA_CONTEXT_FAILED:
default:
- cerr << "PulseAudioIO::contextStateChanged: Error: "
+ cerr << "PulseAudioPlaybackTarget::contextStateChanged: Error: "
<< pa_strerror(pa_context_errno(m_context)) << endl;
//!!! do something...
break;
@@ 520,15 384,15 @@ PulseAudioIO::contextStateChanged()
}
void
-PulseAudioIO::streamOverflowStatic(pa_stream *, void *)
+PulseAudioPlaybackTarget::streamOverflowStatic(pa_stream *, void *)
{
- cerr << "PulseAudioIO::streamOverflowStatic: Overflow!" << endl;
+ cerr << "PulseAudioPlaybackTarget::streamOverflowStatic: Overflow!" << endl;
}
void
-PulseAudioIO::streamUnderflowStatic(pa_stream *, void *)
+PulseAudioPlaybackTarget::streamUnderflowStatic(pa_stream *, void *)
{
- cerr << "PulseAudioIO::streamUnderflowStatic: Underflow!" << endl;
+ cerr << "PulseAudioPlaybackTarget::streamUnderflowStatic: Underflow!" << endl;
}
@@ 1,14 1,14 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
/* Copyright Chris Cannam - All Rights Reserved */
-#ifndef _AUDIO_PULSE_AUDIO_IO_H_
-#define _AUDIO_PULSE_AUDIO_IO_H_
+#ifndef _AUDIO_PULSE_AUDIO_PLAYBACK_TARGET_H_
+#define _AUDIO_PULSE_AUDIO_PLAYBACK_TARGET_H_
#ifdef HAVE_LIBPULSE
#include <pulse/pulseaudio.h>
-#include "SystemAudioIO.h"
+#include "SystemPlaybackTarget.h"
#include "system/Thread.h"
@@ 16,31 16,24 @@
namespace Turbot {
-class ApplicationRecordTarget;
class ApplicationPlaybackSource;
-class PulseAudioIO : public SystemAudioIO
+class PulseAudioPlaybackTarget : public SystemPlaybackTarget
{
public:
- PulseAudioIO(ApplicationRecordTarget *recordTarget,
- ApplicationPlaybackSource *playSource);
- virtual ~PulseAudioIO();
+ PulseAudioPlaybackTarget(ApplicationPlaybackSource *playSource);
+ virtual ~PulseAudioPlaybackTarget();
- virtual bool isSourceOK() const;
- virtual bool isSourceReady() const;
virtual bool isTargetOK() const;
- virtual bool isTargetReady() const;
virtual double getCurrentTime() const;
protected:
void streamWrite(int);
- void streamRead(int);
void streamStateChanged(pa_stream *);
void contextStateChanged();
static void streamWriteStatic(pa_stream *, size_t, void *);
- static void streamReadStatic(pa_stream *, size_t, void *);
static void streamStateChangedStatic(pa_stream *, void *);
static void streamOverflowStatic(pa_stream *, void *);
static void streamUnderflowStatic(pa_stream *, void *);
@@ 64,7 57,6 @@ protected:
pa_mainloop *m_loop;
pa_mainloop_api *m_api;
pa_context *m_context;
- pa_stream *m_in;
pa_stream *m_out;
pa_sample_spec m_spec;
@@ 72,9 64,9 @@ protected:
int m_bufferSize;
int m_sampleRate;
+ int m_paChannels;
bool m_done;
- bool m_captureReady;
bool m_playbackReady;
};