diff options
Diffstat (limited to 'src/plugins/pulseaudio/qaudiooutput_pulse.cpp')
-rw-r--r-- | src/plugins/pulseaudio/qaudiooutput_pulse.cpp | 84 |
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 |