summaryrefslogtreecommitdiffstats
path: root/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/pulseaudio/qaudiooutput_pulse.cpp')
-rw-r--r--src/plugins/pulseaudio/qaudiooutput_pulse.cpp84
1 files changed, 32 insertions, 52 deletions
diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
index c1d46fac4..a850c9b0e 100644
--- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
+++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
@@ -34,6 +34,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdebug.h>
#include <QtCore/qmath.h>
+#include <private/qaudiohelpers_p.h>
#include "qaudiooutput_pulse.h"
#include "qaudiodeviceinfo_pulse.h"
@@ -162,7 +163,6 @@ QPulseAudioOutput::QPulseAudioOutput(const QByteArray &device)
, m_audioBuffer(0)
, m_resuming(false)
, m_volume(1.0)
- , m_customVolumeRequired(false)
{
connect(m_tickTimer, SIGNAL(timeout()), SLOT(userFeed()));
}
@@ -312,27 +312,6 @@ bool QPulseAudioOutput::open()
pa_stream_set_overflow_callback(m_stream, outputStreamOverflowCallback, this);
pa_stream_set_latency_update_callback(m_stream, outputStreamLatencyCallback, this);
- pa_volume_t paVolume;
-
- /* streams without a custom volume set are expected to already have a
- * sensible volume set by Pulse, so we don't set it explicitly.
- *
- * explicit setting also breaks volume handling on sailfish, where each
- * stream's volume is set separately inside pulseaudio, with the
- * exception of streams that already have a volume set (i.e. if we set
- * it here, we'd ignore system volume).
- */
- if (m_customVolumeRequired) {
- if (qFuzzyCompare(m_volume, 0.0)) {
- paVolume = PA_VOLUME_MUTED;
- m_volume = 0.0;
- } else {
- paVolume = qFloor(m_volume * PA_VOLUME_NORM + 0.5);
- }
-
- pa_cvolume_set(&m_chVolume, m_spec.channels, paVolume);
- }
-
if (m_bufferSize <= 0 && m_category == LOW_LATENCY_CATEGORY_NAME) {
m_bufferSize = bytesPerSecond * LowLatencyBufferSizeMs / qint64(1000);
}
@@ -344,7 +323,7 @@ bool QPulseAudioOutput::open()
requestedBuffer.prebuf = (uint32_t)-1;
requestedBuffer.tlength = m_bufferSize;
- if (pa_stream_connect_playback(m_stream, m_device.data(), (m_bufferSize > 0) ? &requestedBuffer : NULL, (pa_stream_flags_t)0, m_customVolumeRequired ? &m_chVolume : NULL, NULL) < 0) {
+ if (pa_stream_connect_playback(m_stream, m_device.data(), (m_bufferSize > 0) ? &requestedBuffer : NULL, (pa_stream_flags_t)0, NULL, NULL) < 0) {
qWarning() << "pa_stream_connect_playback() failed!";
pa_stream_unref(m_stream);
m_stream = 0;
@@ -491,8 +470,33 @@ qint64 QPulseAudioOutput::write(const char *data, qint64 len)
QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
pulseEngine->lock();
+
len = qMin(len, static_cast<qint64>(pa_stream_writable_size(m_stream)));
- pa_stream_write(m_stream, data, len, 0, 0, PA_SEEK_RELATIVE);
+
+ if (m_volume < 1.0f) {
+ // Don't use PulseAudio volume, as it might affect all other streams of the same category
+ // or even affect the system volume if flat volumes are enabled
+ void *dest = NULL;
+ size_t nbytes = len;
+ if (pa_stream_begin_write(m_stream, &dest, &nbytes) < 0) {
+ qWarning("QAudioOutput(pulseaudio): pa_stream_begin_write, error = %s",
+ pa_strerror(pa_context_errno(pulseEngine->context())));
+ setError(QAudio::IOError);
+ return 0;
+ }
+
+ len = int(nbytes);
+ QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, dest, len);
+ data = reinterpret_cast<char *>(dest);
+ }
+
+ if (pa_stream_write(m_stream, data, len, NULL, 0, PA_SEEK_RELATIVE) < 0) {
+ qWarning("QAudioOutput(pulseaudio): pa_stream_write, error = %s",
+ pa_strerror(pa_context_errno(pulseEngine->context())));
+ setError(QAudio::IOError);
+ return 0;
+ }
+
pulseEngine->unlock();
m_totalTimeValue += len;
@@ -664,34 +668,10 @@ qint64 PulseOutputPrivate::writeData(const char *data, qint64 len)
void QPulseAudioOutput::setVolume(qreal vol)
{
- if (vol >= 0.0 && vol <= 1.0) {
- if (!qFuzzyCompare(m_volume, vol)) {
- m_customVolumeRequired = true;
- m_volume = vol;
- if (m_opened) {
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pulseEngine->lock();
- pa_volume_t paVolume;
- if (qFuzzyCompare(vol, 0.0)) {
- pa_cvolume_mute(&m_chVolume, m_spec.channels);
- m_volume = 0.0;
- } else {
- paVolume = qFloor(m_volume * PA_VOLUME_NORM + 0.5);
- pa_cvolume_set(&m_chVolume, m_spec.channels, paVolume);
- }
- pa_operation *op = pa_context_set_sink_input_volume(pulseEngine->context(),
- pa_stream_get_index(m_stream),
- &m_chVolume,
- NULL,
- NULL);
- if (op == NULL)
- qWarning()<<"QAudioOutput: Failed to set volume";
- else
- pa_operation_unref(op);
- pulseEngine->unlock();
- }
- }
- }
+ if (qFuzzyCompare(m_volume, vol))
+ return;
+
+ m_volume = qBound(qreal(0), vol, qreal(1));
}
qreal QPulseAudioOutput::volume() const