diff options
Diffstat (limited to 'src/plugins/pulseaudio')
-rw-r--r-- | src/plugins/pulseaudio/pulseaudio.json | 3 | ||||
-rw-r--r-- | src/plugins/pulseaudio/pulseaudio.pro | 25 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qaudiodeviceinfo_pulse.cpp | 103 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h | 90 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qaudioinput_pulse.cpp | 682 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qaudioinput_pulse.h | 161 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qaudiooutput_pulse.cpp | 739 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qaudiooutput_pulse.h | 166 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qpulseaudioengine.cpp | 482 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qpulseaudioengine.h | 129 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qpulseaudioplugin.cpp | 85 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qpulseaudioplugin.h | 73 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qpulsehelpers.cpp | 211 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qpulsehelpers.h | 71 |
14 files changed, 0 insertions, 3020 deletions
diff --git a/src/plugins/pulseaudio/pulseaudio.json b/src/plugins/pulseaudio/pulseaudio.json deleted file mode 100644 index a31d52107..000000000 --- a/src/plugins/pulseaudio/pulseaudio.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": ["default"] -} diff --git a/src/plugins/pulseaudio/pulseaudio.pro b/src/plugins/pulseaudio/pulseaudio.pro deleted file mode 100644 index c6339e9e8..000000000 --- a/src/plugins/pulseaudio/pulseaudio.pro +++ /dev/null @@ -1,25 +0,0 @@ -TARGET = qtmedia_pulse -QT += multimedia-private - -QMAKE_USE += pulseaudio - -HEADERS += qpulseaudioplugin.h \ - qaudiodeviceinfo_pulse.h \ - qaudiooutput_pulse.h \ - qaudioinput_pulse.h \ - qpulseaudioengine.h \ - qpulsehelpers.h - -SOURCES += qpulseaudioplugin.cpp \ - qaudiodeviceinfo_pulse.cpp \ - qaudiooutput_pulse.cpp \ - qaudioinput_pulse.cpp \ - qpulseaudioengine.cpp \ - qpulsehelpers.cpp - -OTHER_FILES += \ - pulseaudio.json - -PLUGIN_TYPE = audio -PLUGIN_CLASS_NAME = QPulseAudioPlugin -load(qt_plugin) diff --git a/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.cpp b/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.cpp deleted file mode 100644 index c9cdfb3c5..000000000 --- a/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qaudiodeviceinfo_pulse.h" -#include "qpulseaudioengine.h" -#include "qpulsehelpers.h" - -QT_BEGIN_NAMESPACE - -QPulseAudioDeviceInfo::QPulseAudioDeviceInfo(const QByteArray &device, QAudio::Mode mode) - : m_device(device) - , m_mode(mode) -{ -} - -bool QPulseAudioDeviceInfo::isFormatSupported(const QAudioFormat &format) const -{ - pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(format); - if (!pa_sample_spec_valid(&spec)) - return false; - - return true; -} - -QAudioFormat QPulseAudioDeviceInfo::preferredFormat() const -{ - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - QAudioFormat format = pulseEngine->m_preferredFormats.value(m_device); - return format; -} - -QString QPulseAudioDeviceInfo::deviceName() const -{ - return m_device; -} - -QStringList QPulseAudioDeviceInfo::supportedCodecs() -{ - return QStringList() << "audio/pcm"; -} - -QList<int> QPulseAudioDeviceInfo::supportedSampleRates() -{ - return QList<int>() << 8000 << 11025 << 22050 << 44100 << 48000; -} - -QList<int> QPulseAudioDeviceInfo::supportedChannelCounts() -{ - return QList<int>() << 1 << 2 << 4 << 6 << 8; -} - -QList<int> QPulseAudioDeviceInfo::supportedSampleSizes() -{ - return QList<int>() << 8 << 16 << 24 << 32; -} - -QList<QAudioFormat::Endian> QPulseAudioDeviceInfo::supportedByteOrders() -{ - return QList<QAudioFormat::Endian>() << QAudioFormat::BigEndian << QAudioFormat::LittleEndian; -} - -QList<QAudioFormat::SampleType> QPulseAudioDeviceInfo::supportedSampleTypes() -{ - return QList<QAudioFormat::SampleType>() << QAudioFormat::SignedInt << QAudioFormat::UnSignedInt << QAudioFormat::Float; -} - -QT_END_NAMESPACE diff --git a/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h b/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h deleted file mode 100644 index 1cec772c0..000000000 --- a/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QAUDIODEVICEINFOPULSE_H -#define QAUDIODEVICEINFOPULSE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qbytearray.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qlist.h> - -#include "qaudio.h" -#include "qaudiodeviceinfo.h" -#include "qaudiosystem.h" - -QT_BEGIN_NAMESPACE - -class QPulseAudioDeviceInfo : public QAbstractAudioDeviceInfo -{ - Q_OBJECT - -public: - QPulseAudioDeviceInfo(const QByteArray &device, QAudio::Mode mode); - ~QPulseAudioDeviceInfo() {} - - QAudioFormat preferredFormat() const override; - bool isFormatSupported(const QAudioFormat &format) const override; - QString deviceName() const override; - QStringList supportedCodecs() override; - QList<int> supportedSampleRates() override; - QList<int> supportedChannelCounts() override; - QList<int> supportedSampleSizes() override; - QList<QAudioFormat::Endian> supportedByteOrders() override; - QList<QAudioFormat::SampleType> supportedSampleTypes() override; - -private: - QByteArray m_device; - QAudio::Mode m_mode; -}; - -QT_END_NAMESPACE - -#endif - diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/src/plugins/pulseaudio/qaudioinput_pulse.cpp deleted file mode 100644 index 3e7b4d79a..000000000 --- a/src/plugins/pulseaudio/qaudioinput_pulse.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdebug.h> -#include <QtCore/qmath.h> -#include <private/qaudiohelpers_p.h> - -#include "qaudioinput_pulse.h" -#include "qaudiodeviceinfo_pulse.h" -#include "qpulseaudioengine.h" -#include "qpulsehelpers.h" -#include <sys/types.h> -#include <unistd.h> - -QT_BEGIN_NAMESPACE - -const int PeriodTimeMs = 50; - -static void inputStreamReadCallback(pa_stream *stream, size_t length, void *userdata) -{ - Q_UNUSED(userdata); - Q_UNUSED(length); - Q_UNUSED(stream); - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); -} - -static void inputStreamStateCallback(pa_stream *stream, void *userdata) -{ - Q_UNUSED(userdata); - pa_stream_state_t state = pa_stream_get_state(stream); -#ifdef DEBUG_PULSE - qDebug() << "Stream state: " << QPulseAudioInternal::stateToQString(state); -#endif - switch (state) { - case PA_STREAM_CREATING: - break; - case PA_STREAM_READY: { -#ifdef DEBUG_PULSE - QPulseAudioInput *audioInput = static_cast<QPulseAudioInput*>(userdata); - const pa_buffer_attr *buffer_attr = pa_stream_get_buffer_attr(stream); - qDebug() << "*** maxlength: " << buffer_attr->maxlength; - qDebug() << "*** prebuf: " << buffer_attr->prebuf; - qDebug() << "*** fragsize: " << buffer_attr->fragsize; - qDebug() << "*** minreq: " << buffer_attr->minreq; - qDebug() << "*** tlength: " << buffer_attr->tlength; - - pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(audioInput->format()); - qDebug() << "*** bytes_to_usec: " << pa_bytes_to_usec(buffer_attr->fragsize, &spec); -#endif - } - break; - case PA_STREAM_TERMINATED: - break; - case PA_STREAM_FAILED: - default: - qWarning() << QString("Stream error: %1").arg(pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); - break; - } -} - -static void inputStreamUnderflowCallback(pa_stream *stream, void *userdata) -{ - Q_UNUSED(userdata); - Q_UNUSED(stream); - qWarning() << "Got a buffer underflow!"; -} - -static void inputStreamOverflowCallback(pa_stream *stream, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(userdata); - qWarning() << "Got a buffer overflow!"; -} - -static void inputStreamSuccessCallback(pa_stream *stream, int success, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(userdata); - Q_UNUSED(success); - - //if (!success) - //TODO: Is cork success? i->operation_success = success; - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); -} - -QPulseAudioInput::QPulseAudioInput(const QByteArray &device) - : m_totalTimeValue(0) - , m_audioSource(0) - , m_errorState(QAudio::NoError) - , m_deviceState(QAudio::StoppedState) - , m_volume(qreal(1.0f)) - , m_pullMode(true) - , m_opened(false) - , m_bytesAvailable(0) - , m_bufferSize(0) - , m_periodSize(0) - , m_intervalTime(1000) - , m_periodTime(PeriodTimeMs) - , m_stream(0) - , m_device(device) -{ - m_timer = new QTimer(this); - connect(m_timer, SIGNAL(timeout()), SLOT(userFeed())); -} - -QPulseAudioInput::~QPulseAudioInput() -{ - close(); - disconnect(m_timer, SIGNAL(timeout())); - QCoreApplication::processEvents(); - delete m_timer; -} - -void QPulseAudioInput::setError(QAudio::Error error) -{ - if (m_errorState == error) - return; - - m_errorState = error; - emit errorChanged(error); -} - -QAudio::Error QPulseAudioInput::error() const -{ - return m_errorState; -} - -void QPulseAudioInput::setState(QAudio::State state) -{ - if (m_deviceState == state) - return; - - m_deviceState = state; - emit stateChanged(state); -} - -QAudio::State QPulseAudioInput::state() const -{ - return m_deviceState; -} - -void QPulseAudioInput::setFormat(const QAudioFormat &format) -{ - if (m_deviceState == QAudio::StoppedState) - m_format = format; -} - -QAudioFormat QPulseAudioInput::format() const -{ - return m_format; -} - -void QPulseAudioInput::start(QIODevice *device) -{ - setState(QAudio::StoppedState); - setError(QAudio::NoError); - - if (!m_pullMode && m_audioSource) { - delete m_audioSource; - m_audioSource = 0; - } - - close(); - - if (!open()) - return; - - m_pullMode = true; - m_audioSource = device; - - setState(QAudio::ActiveState); -} - -QIODevice *QPulseAudioInput::start() -{ - setState(QAudio::StoppedState); - setError(QAudio::NoError); - - if (!m_pullMode && m_audioSource) { - delete m_audioSource; - m_audioSource = 0; - } - - close(); - - if (!open()) - return nullptr; - - m_pullMode = false; - m_audioSource = new PulseInputPrivate(this); - m_audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered); - - setState(QAudio::IdleState); - - return m_audioSource; -} - -void QPulseAudioInput::stop() -{ - if (m_deviceState == QAudio::StoppedState) - return; - - close(); - - setError(QAudio::NoError); - setState(QAudio::StoppedState); -} - -bool QPulseAudioInput::open() -{ - if (m_opened) - return true; - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - - if (!pulseEngine->context() || pa_context_get_state(pulseEngine->context()) != PA_CONTEXT_READY) { - setError(QAudio::FatalError); - setState(QAudio::StoppedState); - return false; - } - - pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format); - - if (!pa_sample_spec_valid(&spec)) { - setError(QAudio::OpenError); - setState(QAudio::StoppedState); - return false; - } - - m_spec = spec; - -#ifdef DEBUG_PULSE -// QTime now(QTime::currentTime()); -// qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; -#endif - - if (m_streamName.isNull()) - m_streamName = QString(QLatin1String("QtmPulseStream-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8(); - -#ifdef DEBUG_PULSE - qDebug() << "Format: " << QPulseAudioInternal::sampleFormatToQString(spec.format); - qDebug() << "Rate: " << spec.rate; - qDebug() << "Channels: " << spec.channels; - qDebug() << "Frame size: " << pa_frame_size(&spec); -#endif - - pulseEngine->lock(); - pa_channel_map channel_map; - - pa_channel_map_init_extend(&channel_map, spec.channels, PA_CHANNEL_MAP_DEFAULT); - - if (!pa_channel_map_compatible(&channel_map, &spec)) - qWarning() << "Channel map doesn't match sample specification!"; - - m_stream = pa_stream_new(pulseEngine->context(), m_streamName.constData(), &spec, &channel_map); - - pa_stream_set_state_callback(m_stream, inputStreamStateCallback, this); - pa_stream_set_read_callback(m_stream, inputStreamReadCallback, this); - - pa_stream_set_underflow_callback(m_stream, inputStreamUnderflowCallback, this); - pa_stream_set_overflow_callback(m_stream, inputStreamOverflowCallback, this); - - m_periodSize = pa_usec_to_bytes(PeriodTimeMs*1000, &spec); - - int flags = 0; - pa_buffer_attr buffer_attr; - buffer_attr.maxlength = (uint32_t) -1; - buffer_attr.prebuf = (uint32_t) -1; - buffer_attr.tlength = (uint32_t) -1; - buffer_attr.minreq = (uint32_t) -1; - flags |= PA_STREAM_ADJUST_LATENCY; - - if (m_bufferSize > 0) - buffer_attr.fragsize = (uint32_t) m_bufferSize; - else - buffer_attr.fragsize = (uint32_t) m_periodSize; - - if (pa_stream_connect_record(m_stream, m_device.data(), &buffer_attr, (pa_stream_flags_t)flags) < 0) { - qWarning() << "pa_stream_connect_record() failed!"; - pa_stream_unref(m_stream); - m_stream = 0; - pulseEngine->unlock(); - setError(QAudio::OpenError); - setState(QAudio::StoppedState); - return false; - } - - while (pa_stream_get_state(m_stream) != PA_STREAM_READY) - pa_threaded_mainloop_wait(pulseEngine->mainloop()); - - const pa_buffer_attr *actualBufferAttr = pa_stream_get_buffer_attr(m_stream); - m_periodSize = actualBufferAttr->fragsize; - m_periodTime = pa_bytes_to_usec(m_periodSize, &spec) / 1000; - if (actualBufferAttr->tlength != (uint32_t)-1) - m_bufferSize = actualBufferAttr->tlength; - - pulseEngine->unlock(); - - connect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioInput::onPulseContextFailed); - - m_opened = true; - m_timer->start(m_periodTime); - - m_clockStamp.restart(); - m_timeStamp.restart(); - m_elapsedTimeOffset = 0; - m_totalTimeValue = 0; - - return true; -} - -void QPulseAudioInput::close() -{ - if (!m_opened) - return; - - m_timer->stop(); - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - - if (m_stream) { - pulseEngine->lock(); - - pa_stream_set_state_callback(m_stream, 0, 0); - pa_stream_set_read_callback(m_stream, 0, 0); - pa_stream_set_underflow_callback(m_stream, 0, 0); - pa_stream_set_overflow_callback(m_stream, 0, 0); - - pa_stream_disconnect(m_stream); - pa_stream_unref(m_stream); - m_stream = 0; - - pulseEngine->unlock(); - } - - disconnect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioInput::onPulseContextFailed); - - if (!m_pullMode && m_audioSource) { - delete m_audioSource; - m_audioSource = 0; - } - m_opened = false; -} - -int QPulseAudioInput::checkBytesReady() -{ - if (m_deviceState != QAudio::ActiveState && m_deviceState != QAudio::IdleState) { - m_bytesAvailable = 0; - } else { - m_bytesAvailable = pa_stream_readable_size(m_stream); - } - - return m_bytesAvailable; -} - -int QPulseAudioInput::bytesReady() const -{ - return qMax(m_bytesAvailable, 0); -} - -qint64 QPulseAudioInput::read(char *data, qint64 len) -{ - m_bytesAvailable = checkBytesReady(); - - setError(QAudio::NoError); - setState(QAudio::ActiveState); - - int readBytes = 0; - - if (!m_pullMode && !m_tempBuffer.isEmpty()) { - readBytes = qMin(static_cast<int>(len), m_tempBuffer.size()); - memcpy(data, m_tempBuffer.constData(), readBytes); - m_totalTimeValue += readBytes; - - if (readBytes < m_tempBuffer.size()) { - m_tempBuffer.remove(0, readBytes); - return readBytes; - } - - m_tempBuffer.clear(); - } - - while (pa_stream_readable_size(m_stream) > 0) { - size_t readLength = 0; - -#ifdef DEBUG_PULSE - qDebug() << "QPulseAudioInput::read -- " << pa_stream_readable_size(m_stream) << " bytes available from pulse audio"; -#endif - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pulseEngine->lock(); - - const void *audioBuffer; - - // Second and third parameters (audioBuffer and length) to pa_stream_peek are output parameters, - // the audioBuffer pointer is set to point to the actual pulse audio data, - // and the length is set to the length of this data. - if (pa_stream_peek(m_stream, &audioBuffer, &readLength) < 0) { - qWarning() << QString("pa_stream_peek() failed: %1").arg(pa_strerror(pa_context_errno(pa_stream_get_context(m_stream)))); - pulseEngine->unlock(); - return 0; - } - - qint64 actualLength = 0; - if (m_pullMode) { - QByteArray adjusted(readLength, Qt::Uninitialized); - applyVolume(audioBuffer, adjusted.data(), readLength); - actualLength = m_audioSource->write(adjusted); - - if (actualLength < qint64(readLength)) { - pulseEngine->unlock(); - - setError(QAudio::UnderrunError); - setState(QAudio::IdleState); - - return actualLength; - } - } else { - actualLength = qMin(static_cast<int>(len - readBytes), static_cast<int>(readLength)); - applyVolume(audioBuffer, data + readBytes, actualLength); - } - -#ifdef DEBUG_PULSE - qDebug() << "QPulseAudioInput::read -- wrote " << actualLength << " to client"; -#endif - - if (actualLength < qint64(readLength)) { -#ifdef DEBUG_PULSE - qDebug() << "QPulseAudioInput::read -- appending " << readLength - actualLength << " bytes of data to temp buffer"; -#endif - int diff = readLength - actualLength; - int oldSize = m_tempBuffer.size(); - m_tempBuffer.resize(m_tempBuffer.size() + diff); - applyVolume(static_cast<const char *>(audioBuffer) + actualLength, m_tempBuffer.data() + oldSize, diff); - QMetaObject::invokeMethod(this, "userFeed", Qt::QueuedConnection); - } - - m_totalTimeValue += actualLength; - readBytes += actualLength; - - pa_stream_drop(m_stream); - pulseEngine->unlock(); - - if (!m_pullMode && readBytes >= len) - break; - - if (m_intervalTime && (m_timeStamp.elapsed() + m_elapsedTimeOffset) > m_intervalTime) { - emit notify(); - m_elapsedTimeOffset = m_timeStamp.elapsed() + m_elapsedTimeOffset - m_intervalTime; - m_timeStamp.restart(); - } - } - -#ifdef DEBUG_PULSE - qDebug() << "QPulseAudioInput::read -- returning after reading " << readBytes << " bytes"; -#endif - - return readBytes; -} - -void QPulseAudioInput::applyVolume(const void *src, void *dest, int len) -{ - if (m_volume < 1.f) - QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len); - else - memcpy(dest, src, len); -} - -void QPulseAudioInput::resume() -{ - if (m_deviceState == QAudio::SuspendedState || m_deviceState == QAudio::IdleState) { - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_operation *operation; - - pulseEngine->lock(); - - operation = pa_stream_cork(m_stream, 0, inputStreamSuccessCallback, 0); - pulseEngine->wait(operation); - pa_operation_unref(operation); - - pulseEngine->unlock(); - - m_timer->start(m_periodTime); - - setState(QAudio::ActiveState); - setError(QAudio::NoError); - } -} - -void QPulseAudioInput::setVolume(qreal vol) -{ - if (qFuzzyCompare(m_volume, vol)) - return; - - m_volume = qBound(qreal(0), vol, qreal(1)); -} - -qreal QPulseAudioInput::volume() const -{ - return m_volume; -} - -void QPulseAudioInput::setBufferSize(int value) -{ - m_bufferSize = value; -} - -int QPulseAudioInput::bufferSize() const -{ - return m_bufferSize; -} - -int QPulseAudioInput::periodSize() const -{ - return m_periodSize; -} - -void QPulseAudioInput::setNotifyInterval(int ms) -{ - m_intervalTime = qMax(0, ms); -} - -int QPulseAudioInput::notifyInterval() const -{ - return m_intervalTime; -} - -qint64 QPulseAudioInput::processedUSecs() const -{ - pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format); - qint64 result = pa_bytes_to_usec(m_totalTimeValue, &spec); - - return result; -} - -void QPulseAudioInput::suspend() -{ - if (m_deviceState == QAudio::ActiveState) { - setError(QAudio::NoError); - setState(QAudio::SuspendedState); - - m_timer->stop(); - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_operation *operation; - - pulseEngine->lock(); - - operation = pa_stream_cork(m_stream, 1, inputStreamSuccessCallback, 0); - pulseEngine->wait(operation); - pa_operation_unref(operation); - - pulseEngine->unlock(); - } -} - -void QPulseAudioInput::userFeed() -{ - if (m_deviceState == QAudio::StoppedState || m_deviceState == QAudio::SuspendedState) - return; -#ifdef DEBUG_PULSE -// QTime now(QTime::currentTime()); -// qDebug()<< now.second() << "s " << now.msec() << "ms :userFeed() IN"; -#endif - deviceReady(); -} - -bool QPulseAudioInput::deviceReady() -{ - if (m_pullMode) { - // reads some audio data and writes it to QIODevice - read(0,0); - } else { - // emits readyRead() so user will call read() on QIODevice to get some audio data - if (m_audioSource != 0) { - PulseInputPrivate *a = qobject_cast<PulseInputPrivate*>(m_audioSource); - a->trigger(); - } - } - m_bytesAvailable = checkBytesReady(); - - if (m_deviceState != QAudio::ActiveState) - return true; - - if (m_intervalTime && (m_timeStamp.elapsed() + m_elapsedTimeOffset) > m_intervalTime) { - emit notify(); - m_elapsedTimeOffset = m_timeStamp.elapsed() + m_elapsedTimeOffset - m_intervalTime; - m_timeStamp.restart(); - } - - return true; -} - -qint64 QPulseAudioInput::elapsedUSecs() const -{ - if (m_deviceState == QAudio::StoppedState) - return 0; - - return m_clockStamp.elapsed() * qint64(1000); -} - -void QPulseAudioInput::reset() -{ - stop(); - m_bytesAvailable = 0; -} - -void QPulseAudioInput::onPulseContextFailed() -{ - close(); - - setError(QAudio::FatalError); - setState(QAudio::StoppedState); -} - -PulseInputPrivate::PulseInputPrivate(QPulseAudioInput *audio) -{ - m_audioDevice = qobject_cast<QPulseAudioInput*>(audio); -} - -qint64 PulseInputPrivate::readData(char *data, qint64 len) -{ - return m_audioDevice->read(data, len); -} - -qint64 PulseInputPrivate::writeData(const char *data, qint64 len) -{ - Q_UNUSED(data); - Q_UNUSED(len); - return 0; -} - -void PulseInputPrivate::trigger() -{ - emit readyRead(); -} - -QT_END_NAMESPACE - -#include "moc_qaudioinput_pulse.cpp" diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.h b/src/plugins/pulseaudio/qaudioinput_pulse.h deleted file mode 100644 index dce212a25..000000000 --- a/src/plugins/pulseaudio/qaudioinput_pulse.h +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QAUDIOINPUTPULSE_H -#define QAUDIOINPUTPULSE_H - -#include <QtCore/qfile.h> -#include <QtCore/qtimer.h> -#include <QtCore/qstring.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qelapsedtimer.h> -#include <QtCore/qiodevice.h> - -#include "qaudio.h" -#include "qaudiodeviceinfo.h" -#include "qaudiosystem.h" - -#include <pulse/pulseaudio.h> - -QT_BEGIN_NAMESPACE - -class PulseInputPrivate; - -class QPulseAudioInput : public QAbstractAudioInput -{ - Q_OBJECT - -public: - QPulseAudioInput(const QByteArray &device); - ~QPulseAudioInput(); - - qint64 read(char *data, qint64 len); - - void start(QIODevice *device) override; - QIODevice *start() override; - void stop() override; - void reset() override; - void suspend() override; - void resume() override; - int bytesReady() const override; - int periodSize() const override; - void setBufferSize(int value) override; - int bufferSize() const override; - void setNotifyInterval(int milliSeconds) override; - int notifyInterval() const override; - qint64 processedUSecs() const override; - qint64 elapsedUSecs() const override; - QAudio::Error error() const override; - QAudio::State state() const override; - void setFormat(const QAudioFormat &format) override; - QAudioFormat format() const override; - - void setVolume(qreal volume) override; - qreal volume() const override; - - qint64 m_totalTimeValue; - QIODevice *m_audioSource; - QAudioFormat m_format; - QAudio::Error m_errorState; - QAudio::State m_deviceState; - qreal m_volume; - -private slots: - void userFeed(); - bool deviceReady(); - void onPulseContextFailed(); - -private: - void setState(QAudio::State state); - void setError(QAudio::Error error); - - void applyVolume(const void *src, void *dest, int len); - - int checkBytesReady(); - bool open(); - void close(); - - bool m_pullMode; - bool m_opened; - int m_bytesAvailable; - int m_bufferSize; - int m_periodSize; - int m_intervalTime; - unsigned int m_periodTime; - QTimer *m_timer; - qint64 m_elapsedTimeOffset; - pa_stream *m_stream; - QElapsedTimer m_timeStamp; - QElapsedTimer m_clockStamp; - QByteArray m_streamName; - QByteArray m_device; - QByteArray m_tempBuffer; - pa_sample_spec m_spec; -}; - -class PulseInputPrivate : public QIODevice -{ - Q_OBJECT -public: - PulseInputPrivate(QPulseAudioInput *audio); - ~PulseInputPrivate() {}; - - qint64 readData(char *data, qint64 len) override; - qint64 writeData(const char *data, qint64 len) override; - - void trigger(); - -private: - QPulseAudioInput *m_audioDevice; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp deleted file mode 100644 index 708c3e0e3..000000000 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp +++ /dev/null @@ -1,739 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#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" -#include "qpulseaudioengine.h" -#include "qpulsehelpers.h" -#include <sys/types.h> -#include <unistd.h> - -QT_BEGIN_NAMESPACE - -const int PeriodTimeMs = 20; -const int LowLatencyPeriodTimeMs = 10; -const int LowLatencyBufferSizeMs = 40; - -#define LOW_LATENCY_CATEGORY_NAME "game" - -static void outputStreamWriteCallback(pa_stream *stream, size_t length, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(length); - Q_UNUSED(userdata); - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); -} - -static void outputStreamStateCallback(pa_stream *stream, void *userdata) -{ - Q_UNUSED(userdata); - pa_stream_state_t state = pa_stream_get_state(stream); -#ifdef DEBUG_PULSE - qDebug() << "Stream state: " << QPulseAudioInternal::stateToQString(state); -#endif - switch (state) { - case PA_STREAM_CREATING: - case PA_STREAM_READY: - case PA_STREAM_TERMINATED: - break; - - case PA_STREAM_FAILED: - default: - qWarning() << QString("Stream error: %1").arg(pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); - break; - } -} - -static void outputStreamUnderflowCallback(pa_stream *stream, void *userdata) -{ - Q_UNUSED(stream); - ((QPulseAudioOutput*)userdata)->streamUnderflowCallback(); -} - -static void outputStreamOverflowCallback(pa_stream *stream, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(userdata); - qWarning() << "Got a buffer overflow!"; -} - -static void outputStreamLatencyCallback(pa_stream *stream, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(userdata); - -#ifdef DEBUG_PULSE - const pa_timing_info *info = pa_stream_get_timing_info(stream); - - qDebug() << "Write index corrupt: " << info->write_index_corrupt; - qDebug() << "Write index: " << info->write_index; - qDebug() << "Read index corrupt: " << info->read_index_corrupt; - qDebug() << "Read index: " << info->read_index; - qDebug() << "Sink usec: " << info->sink_usec; - qDebug() << "Configured sink usec: " << info->configured_sink_usec; -#endif -} - -static void outputStreamSuccessCallback(pa_stream *stream, int success, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(success); - Q_UNUSED(userdata); - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); -} - -static void outputStreamDrainComplete(pa_stream *stream, int success, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(success); - Q_UNUSED(userdata); - -#ifdef DEBUG_PULSE - qDebug() << "Draining completed successfully: " << (bool)success; -#endif -} - -static void streamAdjustPrebufferCallback(pa_stream *stream, int success, void *userdata) -{ - Q_UNUSED(stream); - Q_UNUSED(success); - Q_UNUSED(userdata); - -#ifdef DEBUG_PULSE - qDebug() << "Adjust prebuffer completed successfully: " << (bool)success; -#endif -} - - -QPulseAudioOutput::QPulseAudioOutput(const QByteArray &device) - : m_device(device) - , m_errorState(QAudio::NoError) - , m_deviceState(QAudio::StoppedState) - , m_pullMode(true) - , m_opened(false) - , m_audioSource(0) - , m_periodTime(0) - , m_stream(0) - , m_notifyInterval(1000) - , m_periodSize(0) - , m_bufferSize(0) - , m_maxBufferSize(0) - , m_totalTimeValue(0) - , m_tickTimer(new QTimer(this)) - , m_audioBuffer(0) - , m_resuming(false) - , m_volume(1.0) -{ - connect(m_tickTimer, SIGNAL(timeout()), SLOT(userFeed())); -} - -QPulseAudioOutput::~QPulseAudioOutput() -{ - close(); - disconnect(m_tickTimer, SIGNAL(timeout())); - QCoreApplication::processEvents(); -} - -void QPulseAudioOutput::setError(QAudio::Error error) -{ - if (m_errorState == error) - return; - - m_errorState = error; - emit errorChanged(error); -} - -QAudio::Error QPulseAudioOutput::error() const -{ - return m_errorState; -} - -void QPulseAudioOutput::setState(QAudio::State state) -{ - if (m_deviceState == state) - return; - - m_deviceState = state; - emit stateChanged(state); -} - -QAudio::State QPulseAudioOutput::state() const -{ - return m_deviceState; -} - -void QPulseAudioOutput::streamUnderflowCallback() -{ - if (m_deviceState != QAudio::IdleState && !m_resuming) { - setError(QAudio::UnderrunError); - setState(QAudio::IdleState); - } -} - -void QPulseAudioOutput::start(QIODevice *device) -{ - setState(QAudio::StoppedState); - setError(QAudio::NoError); - - // Handle change of mode - if (m_audioSource && !m_pullMode) { - delete m_audioSource; - } - m_audioSource = 0; - - close(); - - m_pullMode = true; - m_audioSource = device; - - if (!open()) { - m_audioSource = 0; - return; - } - - setState(QAudio::ActiveState); -} - -QIODevice *QPulseAudioOutput::start() -{ - setState(QAudio::StoppedState); - setError(QAudio::NoError); - - // Handle change of mode - if (m_audioSource && !m_pullMode) { - delete m_audioSource; - } - m_audioSource = 0; - - close(); - - m_pullMode = false; - - if (!open()) - return nullptr; - - m_audioSource = new PulseOutputPrivate(this); - m_audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered); - - setState(QAudio::IdleState); - - return m_audioSource; -} - -bool QPulseAudioOutput::open() -{ - if (m_opened) - return true; - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - - if (!pulseEngine->context() || pa_context_get_state(pulseEngine->context()) != PA_CONTEXT_READY) { - setError(QAudio::FatalError); - setState(QAudio::StoppedState); - emit stateChanged(m_deviceState); - return false; - } - - pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format); - - if (!pa_sample_spec_valid(&spec)) { - setError(QAudio::OpenError); - setState(QAudio::StoppedState); - emit stateChanged(m_deviceState); - return false; - } - - m_spec = spec; - m_totalTimeValue = 0; - - if (m_streamName.isNull()) - m_streamName = QString(QLatin1String("QtmPulseStream-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8(); - -#ifdef DEBUG_PULSE - qDebug() << "Format: " << QPulseAudioInternal::sampleFormatToQString(spec.format); - qDebug() << "Rate: " << spec.rate; - qDebug() << "Channels: " << spec.channels; - qDebug() << "Frame size: " << pa_frame_size(&spec); -#endif - - pulseEngine->lock(); - - qint64 bytesPerSecond = m_format.sampleRate() * m_format.channelCount() * m_format.sampleSize() / 8; - - pa_proplist *propList = pa_proplist_new(); - if (!m_category.isNull()) - pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, m_category.toLatin1().constData()); - - static const auto mapName = qEnvironmentVariable("QT_PA_CHANNEL_MAP"); - pa_channel_map_def_t mapDef = PA_CHANNEL_MAP_DEFAULT; - if (mapName == QLatin1String("ALSA")) - mapDef = PA_CHANNEL_MAP_ALSA; - else if (mapName == QLatin1String("AUX")) - mapDef = PA_CHANNEL_MAP_AUX; - else if (mapName == QLatin1String("WAVEEX")) - mapDef = PA_CHANNEL_MAP_WAVEEX; - else if (mapName == QLatin1String("OSS")) - mapDef = PA_CHANNEL_MAP_OSS; - else if (!mapName.isEmpty()) - qWarning() << "Unknown pulse audio channel mapping definition:" << mapName; - - pa_channel_map m; - auto channelMap = pa_channel_map_init_extend(&m, m_spec.channels, mapDef); - if (!channelMap) - qWarning() << "QAudioOutput: pa_channel_map_init_extend() Could not initialize channel map"; - - m_stream = pa_stream_new_with_proplist(pulseEngine->context(), m_streamName.constData(), &m_spec, channelMap, propList); - if (!m_stream) { - qWarning() << "QAudioOutput: pa_stream_new_with_proplist() failed!"; - pulseEngine->unlock(); - setError(QAudio::OpenError); - setState(QAudio::StoppedState); - emit stateChanged(m_deviceState); - return false; - } - - pa_proplist_free(propList); - - pa_stream_set_state_callback(m_stream, outputStreamStateCallback, this); - pa_stream_set_write_callback(m_stream, outputStreamWriteCallback, this); - - pa_stream_set_underflow_callback(m_stream, outputStreamUnderflowCallback, this); - pa_stream_set_overflow_callback(m_stream, outputStreamOverflowCallback, this); - pa_stream_set_latency_update_callback(m_stream, outputStreamLatencyCallback, this); - - if (m_bufferSize <= 0 && m_category == LOW_LATENCY_CATEGORY_NAME) { - m_bufferSize = bytesPerSecond * LowLatencyBufferSizeMs / qint64(1000); - } - - pa_buffer_attr requestedBuffer; - requestedBuffer.fragsize = (uint32_t)-1; - requestedBuffer.maxlength = (uint32_t)-1; - requestedBuffer.minreq = (uint32_t)-1; - 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, NULL, NULL) < 0) { - qWarning() << "pa_stream_connect_playback() failed!"; - pa_stream_unref(m_stream); - m_stream = 0; - pulseEngine->unlock(); - setError(QAudio::OpenError); - setState(QAudio::StoppedState); - emit stateChanged(m_deviceState); - return false; - } - - while (pa_stream_get_state(m_stream) != PA_STREAM_READY) - pa_threaded_mainloop_wait(pulseEngine->mainloop()); - - const pa_buffer_attr *buffer = pa_stream_get_buffer_attr(m_stream); - m_periodTime = (m_category == LOW_LATENCY_CATEGORY_NAME) ? LowLatencyPeriodTimeMs : PeriodTimeMs; - m_periodSize = pa_usec_to_bytes(m_periodTime*1000, &m_spec); - m_bufferSize = buffer->tlength; - m_maxBufferSize = buffer->maxlength; - m_audioBuffer = new char[m_maxBufferSize]; - - const qint64 streamSize = m_audioSource ? m_audioSource->size() : 0; - if (m_pullMode && streamSize > 0 && static_cast<qint64>(buffer->prebuf) > streamSize) { - pa_buffer_attr newBufferAttr; - newBufferAttr = *buffer; - newBufferAttr.prebuf = streamSize; - pa_operation *o = pa_stream_set_buffer_attr(m_stream, &newBufferAttr, streamAdjustPrebufferCallback, NULL); - if (o) - pa_operation_unref(o); - } - -#ifdef DEBUG_PULSE - qDebug() << "Buffering info:"; - qDebug() << "\tMax length: " << buffer->maxlength; - qDebug() << "\tTarget length: " << buffer->tlength; - qDebug() << "\tPre-buffering: " << buffer->prebuf; - qDebug() << "\tMinimum request: " << buffer->minreq; - qDebug() << "\tFragment size: " << buffer->fragsize; -#endif - - pulseEngine->unlock(); - - connect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioOutput::onPulseContextFailed); - - m_opened = true; - - m_tickTimer->start(m_periodTime); - - m_elapsedTimeOffset = 0; - m_timeStamp.restart(); - m_clockStamp.restart(); - - return true; -} - -void QPulseAudioOutput::close() -{ - if (!m_opened) - return; - - m_tickTimer->stop(); - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - - if (m_stream) { - pulseEngine->lock(); - - pa_stream_set_state_callback(m_stream, 0, 0); - pa_stream_set_write_callback(m_stream, 0, 0); - pa_stream_set_underflow_callback(m_stream, 0, 0); - pa_stream_set_overflow_callback(m_stream, 0, 0); - pa_stream_set_latency_update_callback(m_stream, 0, 0); - - pa_operation *o = pa_stream_drain(m_stream, outputStreamDrainComplete, NULL); - if (o) - pa_operation_unref(o); - - pa_stream_disconnect(m_stream); - pa_stream_unref(m_stream); - m_stream = NULL; - - pulseEngine->unlock(); - } - - disconnect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioOutput::onPulseContextFailed); - - if (!m_pullMode && m_audioSource) { - delete m_audioSource; - m_audioSource = 0; - } - m_opened = false; - if (m_audioBuffer) { - delete[] m_audioBuffer; - m_audioBuffer = 0; - } -} - -void QPulseAudioOutput::userFeed() -{ - if (m_deviceState == QAudio::StoppedState || m_deviceState == QAudio::SuspendedState) - return; - - m_resuming = false; - - if (m_pullMode) { - int writableSize = bytesFree(); - int chunks = writableSize / m_periodSize; - if (chunks == 0) - return; - - int input = m_periodSize; // always request 1 chunk of data from user - if (input > m_maxBufferSize) - input = m_maxBufferSize; - - int audioBytesPulled = m_audioSource->read(m_audioBuffer, input); - Q_ASSERT(audioBytesPulled <= input); - if (m_audioBuffer && audioBytesPulled > 0) { - if (audioBytesPulled > input) { - qWarning() << "QPulseAudioOutput::userFeed() - Invalid audio data size provided from user:" - << audioBytesPulled << "should be less than" << input; - audioBytesPulled = input; - } - qint64 bytesWritten = write(m_audioBuffer, audioBytesPulled); - Q_ASSERT(bytesWritten == audioBytesPulled); //unfinished write should not happen since the data provided is less than writableSize - Q_UNUSED(bytesWritten); - - if (chunks > 1) { - // PulseAudio needs more data. Ask for it immediately. - QMetaObject::invokeMethod(this, "userFeed", Qt::QueuedConnection); - } - } - } - - if (m_deviceState != QAudio::ActiveState) - return; - - if (m_notifyInterval && (m_timeStamp.elapsed() + m_elapsedTimeOffset) > m_notifyInterval) { - emit notify(); - m_elapsedTimeOffset = m_timeStamp.restart() + m_elapsedTimeOffset - m_notifyInterval; - } -} - -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))); - - 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; - - setError(QAudio::NoError); - setState(QAudio::ActiveState); - - return len; -} - -void QPulseAudioOutput::stop() -{ - if (m_deviceState == QAudio::StoppedState) - return; - - close(); - - setError(QAudio::NoError); - setState(QAudio::StoppedState); -} - -int QPulseAudioOutput::bytesFree() const -{ - if (m_deviceState != QAudio::ActiveState && m_deviceState != QAudio::IdleState) - return 0; - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pulseEngine->lock(); - int writableSize = pa_stream_writable_size(m_stream); - pulseEngine->unlock(); - return writableSize; -} - -int QPulseAudioOutput::periodSize() const -{ - return m_periodSize; -} - -void QPulseAudioOutput::setBufferSize(int value) -{ - m_bufferSize = value; -} - -int QPulseAudioOutput::bufferSize() const -{ - return m_bufferSize; -} - -void QPulseAudioOutput::setNotifyInterval(int ms) -{ - m_notifyInterval = qMax(0, ms); -} - -int QPulseAudioOutput::notifyInterval() const -{ - return m_notifyInterval; -} - -qint64 QPulseAudioOutput::processedUSecs() const -{ - qint64 result = qint64(1000000) * m_totalTimeValue / - (m_format.channelCount() * (m_format.sampleSize() / 8)) / - m_format.sampleRate(); - - return result; -} - -void QPulseAudioOutput::resume() -{ - if (m_deviceState == QAudio::SuspendedState) { - m_resuming = true; - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - - pulseEngine->lock(); - - pa_operation *operation = pa_stream_cork(m_stream, 0, outputStreamSuccessCallback, NULL); - pulseEngine->wait(operation); - pa_operation_unref(operation); - - operation = pa_stream_trigger(m_stream, outputStreamSuccessCallback, NULL); - pulseEngine->wait(operation); - pa_operation_unref(operation); - - pulseEngine->unlock(); - - m_tickTimer->start(m_periodTime); - - setState(m_pullMode ? QAudio::ActiveState : QAudio::IdleState); - setError(QAudio::NoError); - } -} - -void QPulseAudioOutput::setFormat(const QAudioFormat &format) -{ - m_format = format; -} - -QAudioFormat QPulseAudioOutput::format() const -{ - return m_format; -} - -void QPulseAudioOutput::suspend() -{ - if (m_deviceState == QAudio::ActiveState || m_deviceState == QAudio::IdleState) { - setError(QAudio::NoError); - setState(QAudio::SuspendedState); - - m_tickTimer->stop(); - - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pa_operation *operation; - - pulseEngine->lock(); - - operation = pa_stream_cork(m_stream, 1, outputStreamSuccessCallback, NULL); - pulseEngine->wait(operation); - pa_operation_unref(operation); - - pulseEngine->unlock(); - } -} - -qint64 QPulseAudioOutput::elapsedUSecs() const -{ - if (m_deviceState == QAudio::StoppedState) - return 0; - - return m_clockStamp.elapsed() * qint64(1000); -} - -void QPulseAudioOutput::reset() -{ - stop(); -} - -PulseOutputPrivate::PulseOutputPrivate(QPulseAudioOutput *audio) -{ - m_audioDevice = qobject_cast<QPulseAudioOutput*>(audio); -} - -qint64 PulseOutputPrivate::readData(char *data, qint64 len) -{ - Q_UNUSED(data); - Q_UNUSED(len); - - return 0; -} - -qint64 PulseOutputPrivate::writeData(const char *data, qint64 len) -{ - int retry = 0; - qint64 written = 0; - - if ((m_audioDevice->m_deviceState == QAudio::ActiveState - || m_audioDevice->m_deviceState == QAudio::IdleState)) { - while(written < len) { - int chunk = m_audioDevice->write(data+written, (len-written)); - if (chunk <= 0) - retry++; - written+=chunk; - if (retry > 10) - return written; - } - } - - return written; -} - -void QPulseAudioOutput::setVolume(qreal vol) -{ - if (qFuzzyCompare(m_volume, vol)) - return; - - m_volume = qBound(qreal(0), vol, qreal(1)); -} - -qreal QPulseAudioOutput::volume() const -{ - return m_volume; -} - -void QPulseAudioOutput::setCategory(const QString &category) -{ - if (m_category != category) { - m_category = category; - } -} - -QString QPulseAudioOutput::category() const -{ - return m_category; -} - -void QPulseAudioOutput::onPulseContextFailed() -{ - close(); - - setError(QAudio::FatalError); - setState(QAudio::StoppedState); -} - -QT_END_NAMESPACE - -#include "moc_qaudiooutput_pulse.cpp" diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.h b/src/plugins/pulseaudio/qaudiooutput_pulse.h deleted file mode 100644 index e11f2ab2f..000000000 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.h +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QAUDIOOUTPUTPULSE_H -#define QAUDIOOUTPUTPULSE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qfile.h> -#include <QtCore/qtimer.h> -#include <QtCore/qstring.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qelapsedtimer.h> -#include <QtCore/qiodevice.h> - -#include "qaudio.h" -#include "qaudiodeviceinfo.h" -#include "qaudiosystem.h" - -#include <pulse/pulseaudio.h> - -QT_BEGIN_NAMESPACE - -class QPulseAudioOutput : public QAbstractAudioOutput -{ - friend class PulseOutputPrivate; - Q_OBJECT - -public: - QPulseAudioOutput(const QByteArray &device); - ~QPulseAudioOutput(); - - void start(QIODevice *device) override; - QIODevice *start() override; - void stop() override; - void reset() override; - void suspend() override; - void resume() override; - int bytesFree() const override; - int periodSize() const override; - void setBufferSize(int value) override; - int bufferSize() const override; - void setNotifyInterval(int milliSeconds) override; - int notifyInterval() const override; - qint64 processedUSecs() const override; - qint64 elapsedUSecs() const override; - QAudio::Error error() const override; - QAudio::State state() const override; - void setFormat(const QAudioFormat &format) override; - QAudioFormat format() const override; - - void setVolume(qreal volume) override; - qreal volume() const override; - - void setCategory(const QString &category) override; - QString category() const override; - -public: - void streamUnderflowCallback(); - -private: - void setState(QAudio::State state); - void setError(QAudio::Error error); - - bool open(); - void close(); - qint64 write(const char *data, qint64 len); - -private Q_SLOTS: - void userFeed(); - void onPulseContextFailed(); - -private: - QByteArray m_device; - QByteArray m_streamName; - QAudioFormat m_format; - QAudio::Error m_errorState; - QAudio::State m_deviceState; - bool m_pullMode; - bool m_opened; - QIODevice *m_audioSource; - QTimer m_periodTimer; - int m_periodTime; - pa_stream *m_stream; - int m_notifyInterval; - int m_periodSize; - int m_bufferSize; - int m_maxBufferSize; - QElapsedTimer m_clockStamp; - qint64 m_totalTimeValue; - QTimer *m_tickTimer; - char *m_audioBuffer; - QElapsedTimer m_timeStamp; - qint64 m_elapsedTimeOffset; - bool m_resuming; - QString m_category; - - qreal m_volume; - pa_sample_spec m_spec; -}; - -class PulseOutputPrivate : public QIODevice -{ - friend class QPulseAudioOutput; - Q_OBJECT - -public: - PulseOutputPrivate(QPulseAudioOutput *audio); - virtual ~PulseOutputPrivate() {} - -protected: - qint64 readData(char *data, qint64 len) override; - qint64 writeData(const char *data, qint64 len) override; - -private: - QPulseAudioOutput *m_audioDevice; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/pulseaudio/qpulseaudioengine.cpp b/src/plugins/pulseaudio/qpulseaudioengine.cpp deleted file mode 100644 index 653fea57e..000000000 --- a/src/plugins/pulseaudio/qpulseaudioengine.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qdebug.h> - -#include <qaudiodeviceinfo.h> -#include "qpulseaudioengine.h" -#include "qaudiodeviceinfo_pulse.h" -#include "qaudiooutput_pulse.h" -#include "qpulsehelpers.h" -#include <sys/types.h> -#include <unistd.h> - -QT_BEGIN_NAMESPACE - -static void serverInfoCallback(pa_context *context, const pa_server_info *info, void *userdata) -{ - if (!info) { - qWarning() << QString("Failed to get server information: %s").arg(pa_strerror(pa_context_errno(context))); - return; - } - -#ifdef DEBUG_PULSE - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - - pa_sample_spec_snprint(ss, sizeof(ss), &info->sample_spec); - pa_channel_map_snprint(cm, sizeof(cm), &info->channel_map); - - qDebug() << QString("User name: %1\n" - "Host Name: %2\n" - "Server Name: %3\n" - "Server Version: %4\n" - "Default Sample Specification: %5\n" - "Default Channel Map: %6\n" - "Default Sink: %7\n" - "Default Source: %8\n").arg( - info->user_name, - info->host_name, - info->server_name, - info->server_version, - ss, - cm, - info->default_sink_name, - info->default_source_name); -#endif - - QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata); - pulseEngine->m_serverLock.lockForWrite(); - pulseEngine->m_defaultSink = info->default_sink_name; - pulseEngine->m_defaultSource = info->default_source_name; - pulseEngine->m_serverLock.unlock(); - - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); -} - -static void sinkInfoCallback(pa_context *context, const pa_sink_info *info, int isLast, void *userdata) -{ - QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata); - - if (isLast < 0) { - qWarning() << QString("Failed to get sink information: %s").arg(pa_strerror(pa_context_errno(context))); - return; - } - - if (isLast) { - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); - return; - } - - Q_ASSERT(info); - -#ifdef DEBUG_PULSE - QMap<pa_sink_state, QString> stateMap; - stateMap[PA_SINK_INVALID_STATE] = "n/a"; - stateMap[PA_SINK_RUNNING] = "RUNNING"; - stateMap[PA_SINK_IDLE] = "IDLE"; - stateMap[PA_SINK_SUSPENDED] = "SUSPENDED"; - - qDebug() << QString("Sink #%1\n" - "\tState: %2\n" - "\tName: %3\n" - "\tDescription: %4\n" - ).arg(QString::number(info->index), - stateMap.value(info->state), - info->name, - info->description); -#endif - - QAudioFormat format = QPulseAudioInternal::sampleSpecToAudioFormat(info->sample_spec); - - QWriteLocker locker(&pulseEngine->m_sinkLock); - pulseEngine->m_preferredFormats.insert(info->name, format); - pulseEngine->m_sinks.insert(info->index, info->name); -} - -static void sourceInfoCallback(pa_context *context, const pa_source_info *info, int isLast, void *userdata) -{ - Q_UNUSED(context); - QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata); - - if (isLast) { - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); - return; - } - - Q_ASSERT(info); - -#ifdef DEBUG_PULSE - QMap<pa_source_state, QString> stateMap; - stateMap[PA_SOURCE_INVALID_STATE] = "n/a"; - stateMap[PA_SOURCE_RUNNING] = "RUNNING"; - stateMap[PA_SOURCE_IDLE] = "IDLE"; - stateMap[PA_SOURCE_SUSPENDED] = "SUSPENDED"; - - qDebug() << QString("Source #%1\n" - "\tState: %2\n" - "\tName: %3\n" - "\tDescription: %4\n" - ).arg(QString::number(info->index), - stateMap.value(info->state), - info->name, - info->description); -#endif - - QAudioFormat format = QPulseAudioInternal::sampleSpecToAudioFormat(info->sample_spec); - - QWriteLocker locker(&pulseEngine->m_sourceLock); - pulseEngine->m_preferredFormats.insert(info->name, format); - pulseEngine->m_sources.insert(info->index, info->name); -} - -static void event_cb(pa_context* context, pa_subscription_event_type_t t, uint32_t index, void* userdata) -{ - QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata); - - int type = t & PA_SUBSCRIPTION_EVENT_TYPE_MASK; - int facility = t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; - - switch (type) { - case PA_SUBSCRIPTION_EVENT_NEW: - case PA_SUBSCRIPTION_EVENT_CHANGE: - switch (facility) { - case PA_SUBSCRIPTION_EVENT_SERVER: { - pa_operation *op = pa_context_get_server_info(context, serverInfoCallback, userdata); - if (op) - pa_operation_unref(op); - else - qWarning("PulseAudioService: failed to get server info"); - break; - } - case PA_SUBSCRIPTION_EVENT_SINK: { - pa_operation *op = pa_context_get_sink_info_by_index(context, index, sinkInfoCallback, userdata); - if (op) - pa_operation_unref(op); - else - qWarning("PulseAudioService: failed to get sink info"); - break; - } - case PA_SUBSCRIPTION_EVENT_SOURCE: { - pa_operation *op = pa_context_get_source_info_by_index(context, index, sourceInfoCallback, userdata); - if (op) - pa_operation_unref(op); - else - qWarning("PulseAudioService: failed to get source info"); - break; - } - default: - break; - } - break; - case PA_SUBSCRIPTION_EVENT_REMOVE: - switch (facility) { - case PA_SUBSCRIPTION_EVENT_SINK: - pulseEngine->m_sinkLock.lockForWrite(); - pulseEngine->m_preferredFormats.remove(pulseEngine->m_sinks.value(index)); - pulseEngine->m_sinks.remove(index); - pulseEngine->m_sinkLock.unlock(); - break; - case PA_SUBSCRIPTION_EVENT_SOURCE: - pulseEngine->m_sourceLock.lockForWrite(); - pulseEngine->m_preferredFormats.remove(pulseEngine->m_sources.value(index)); - pulseEngine->m_sources.remove(index); - pulseEngine->m_sourceLock.unlock(); - break; - default: - break; - } - break; - default: - break; - } -} - -static void contextStateCallbackInit(pa_context *context, void *userdata) -{ - Q_UNUSED(context); -#ifdef DEBUG_PULSE - qDebug() << QPulseAudioInternal::stateToQString(pa_context_get_state(context)); -#endif - QPulseAudioEngine *pulseEngine = reinterpret_cast<QPulseAudioEngine*>(userdata); - pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); -} - -static void contextStateCallback(pa_context *c, void *userdata) -{ - QPulseAudioEngine *self = reinterpret_cast<QPulseAudioEngine*>(userdata); - pa_context_state_t state = pa_context_get_state(c); - -#ifdef DEBUG_PULSE - qDebug() << QPulseAudioInternal::stateToQString(state); -#endif - - if (state == PA_CONTEXT_FAILED) - QMetaObject::invokeMethod(self, "onContextFailed", Qt::QueuedConnection); -} - -Q_GLOBAL_STATIC(QPulseAudioEngine, pulseEngine); - -QPulseAudioEngine::QPulseAudioEngine(QObject *parent) - : QObject(parent) - , m_mainLoopApi(0) - , m_context(0) - , m_prepared(false) -{ - prepare(); -} - -QPulseAudioEngine::~QPulseAudioEngine() -{ - if (m_prepared) - release(); -} - -void QPulseAudioEngine::prepare() -{ - bool keepGoing = true; - bool ok = true; - - m_mainLoop = pa_threaded_mainloop_new(); - if (m_mainLoop == 0) { - qWarning("PulseAudioService: unable to create pulseaudio mainloop"); - return; - } - - if (pa_threaded_mainloop_start(m_mainLoop) != 0) { - qWarning("PulseAudioService: unable to start pulseaudio mainloop"); - pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; - return; - } - - m_mainLoopApi = pa_threaded_mainloop_get_api(m_mainLoop); - - lock(); - - m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtPulseAudio:%1")).arg(::getpid()).toLatin1().constData()); - - if (m_context == 0) { - qWarning("PulseAudioService: Unable to create new pulseaudio context"); - pa_threaded_mainloop_unlock(m_mainLoop); - pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; - onContextFailed(); - return; - } - - pa_context_set_state_callback(m_context, contextStateCallbackInit, this); - - if (pa_context_connect(m_context, 0, (pa_context_flags_t)0, 0) < 0) { - qWarning("PulseAudioService: pa_context_connect() failed"); - pa_context_unref(m_context); - pa_threaded_mainloop_unlock(m_mainLoop); - pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; - m_context = 0; - return; - } - - pa_threaded_mainloop_wait(m_mainLoop); - - while (keepGoing) { - switch (pa_context_get_state(m_context)) { - case PA_CONTEXT_CONNECTING: - case PA_CONTEXT_AUTHORIZING: - case PA_CONTEXT_SETTING_NAME: - break; - - case PA_CONTEXT_READY: -#ifdef DEBUG_PULSE - qDebug("Connection established."); -#endif - keepGoing = false; - break; - - case PA_CONTEXT_TERMINATED: - qCritical("PulseAudioService: Context terminated."); - keepGoing = false; - ok = false; - break; - - case PA_CONTEXT_FAILED: - default: - qCritical() << QString("PulseAudioService: Connection failure: %1").arg(pa_strerror(pa_context_errno(m_context))); - keepGoing = false; - ok = false; - } - - if (keepGoing) - pa_threaded_mainloop_wait(m_mainLoop); - } - - if (ok) { - pa_context_set_state_callback(m_context, contextStateCallback, this); - - pa_context_set_subscribe_callback(m_context, event_cb, this); - pa_operation *op = pa_context_subscribe(m_context, - pa_subscription_mask_t(PA_SUBSCRIPTION_MASK_SINK | - PA_SUBSCRIPTION_MASK_SOURCE | - PA_SUBSCRIPTION_MASK_SERVER), - NULL, NULL); - if (op) - pa_operation_unref(op); - else - qWarning("PulseAudioService: failed to subscribe to context notifications"); - } else { - pa_context_unref(m_context); - m_context = 0; - } - - unlock(); - - if (ok) { - updateDevices(); - m_prepared = true; - } else { - pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; - onContextFailed(); - } -} - -void QPulseAudioEngine::release() -{ - if (!m_prepared) - return; - - if (m_context) { - pa_context_disconnect(m_context); - pa_context_unref(m_context); - m_context = 0; - } - - if (m_mainLoop) { - pa_threaded_mainloop_stop(m_mainLoop); - pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; - } - - m_prepared = false; -} - -void QPulseAudioEngine::updateDevices() -{ - lock(); - - // Get default input and output devices - pa_operation *operation = pa_context_get_server_info(m_context, serverInfoCallback, this); - if (operation) { - while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(m_mainLoop); - pa_operation_unref(operation); - } else { - qWarning("PulseAudioService: failed to get server info"); - } - - // Get output devices - operation = pa_context_get_sink_info_list(m_context, sinkInfoCallback, this); - if (operation) { - while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(m_mainLoop); - pa_operation_unref(operation); - } else { - qWarning("PulseAudioService: failed to get sink info"); - } - - // Get input devices - operation = pa_context_get_source_info_list(m_context, sourceInfoCallback, this); - if (operation) { - while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(m_mainLoop); - pa_operation_unref(operation); - } else { - qWarning("PulseAudioService: failed to get source info"); - } - - unlock(); -} - -void QPulseAudioEngine::onContextFailed() -{ - // Give a chance to the connected slots to still use the Pulse main loop before releasing it. - emit contextFailed(); - - release(); - - // Try to reconnect later - QTimer::singleShot(3000, this, SLOT(prepare())); -} - -QPulseAudioEngine *QPulseAudioEngine::instance() -{ - return pulseEngine(); -} - -QList<QByteArray> QPulseAudioEngine::availableDevices(QAudio::Mode mode) const -{ - QList<QByteArray> devices; - QByteArray defaultDevice; - - m_serverLock.lockForRead(); - - if (mode == QAudio::AudioOutput) { - QReadLocker locker(&m_sinkLock); - devices = m_sinks.values(); - defaultDevice = m_defaultSink; - } else { - QReadLocker locker(&m_sourceLock); - devices = m_sources.values(); - defaultDevice = m_defaultSource; - } - - m_serverLock.unlock(); - - // Swap the default device to index 0 - devices.removeOne(defaultDevice); - devices.prepend(defaultDevice); - - return devices; -} - -QByteArray QPulseAudioEngine::defaultDevice(QAudio::Mode mode) const -{ - return (mode == QAudio::AudioOutput) ? m_defaultSink : m_defaultSource; -} - -QT_END_NAMESPACE diff --git a/src/plugins/pulseaudio/qpulseaudioengine.h b/src/plugins/pulseaudio/qpulseaudioengine.h deleted file mode 100644 index a19be1841..000000000 --- a/src/plugins/pulseaudio/qpulseaudioengine.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPULSEAUDIOENGINE_H -#define QPULSEAUDIOENGINE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qmap.h> -#include <QtCore/qbytearray.h> -#include <QtCore/qreadwritelock.h> -#include <QtMultimedia/qaudiosystemplugin.h> -#include <pulse/pulseaudio.h> -#include "qpulsehelpers.h" -#include <qaudioformat.h> - -QT_BEGIN_NAMESPACE - -class QPulseAudioEngine : public QObject -{ - Q_OBJECT - -public: - QPulseAudioEngine(QObject *parent = 0); - ~QPulseAudioEngine(); - - static QPulseAudioEngine *instance(); - pa_threaded_mainloop *mainloop() { return m_mainLoop; } - pa_context *context() { return m_context; } - - inline void lock() - { - if (m_mainLoop) - pa_threaded_mainloop_lock(m_mainLoop); - } - - inline void unlock() - { - if (m_mainLoop) - pa_threaded_mainloop_unlock(m_mainLoop); - } - - inline void wait(pa_operation *op) - { - while (m_mainLoop && pa_operation_get_state(op) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(m_mainLoop); - } - - QList<QByteArray> availableDevices(QAudio::Mode mode) const; - QByteArray defaultDevice(QAudio::Mode mode) const; - -Q_SIGNALS: - void contextFailed(); - -private Q_SLOTS: - void prepare(); - void onContextFailed(); - -private: - void updateDevices(); - void release(); - -public: - QMap<int, QByteArray> m_sinks; - QMap<int, QByteArray> m_sources; - QMap<QByteArray, QAudioFormat> m_preferredFormats; - - QByteArray m_defaultSink; - QByteArray m_defaultSource; - - mutable QReadWriteLock m_sinkLock; - mutable QReadWriteLock m_sourceLock; - mutable QReadWriteLock m_serverLock; - -private: - pa_mainloop_api *m_mainLoopApi; - pa_threaded_mainloop *m_mainLoop; - pa_context *m_context; - bool m_prepared; - }; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/pulseaudio/qpulseaudioplugin.cpp b/src/plugins/pulseaudio/qpulseaudioplugin.cpp deleted file mode 100644 index 6b3019279..000000000 --- a/src/plugins/pulseaudio/qpulseaudioplugin.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qaudiodeviceinfo.h> - -#include "qpulseaudioplugin.h" -#include "qaudiodeviceinfo_pulse.h" -#include "qaudiooutput_pulse.h" -#include "qaudioinput_pulse.h" -#include "qpulseaudioengine.h" - -QT_BEGIN_NAMESPACE - -QPulseAudioPlugin::QPulseAudioPlugin(QObject *parent) - : QAudioSystemPlugin(parent) - , m_pulseEngine(QPulseAudioEngine::instance()) -{ -} - -QByteArray QPulseAudioPlugin::defaultDevice(QAudio::Mode mode) const -{ - return m_pulseEngine->defaultDevice(mode); -} - -QList<QByteArray> QPulseAudioPlugin::availableDevices(QAudio::Mode mode) const -{ - return m_pulseEngine->availableDevices(mode); -} - -QAbstractAudioInput *QPulseAudioPlugin::createInput(const QByteArray &device) -{ - QPulseAudioInput *input = new QPulseAudioInput(device); - return input; -} - -QAbstractAudioOutput *QPulseAudioPlugin::createOutput(const QByteArray &device) -{ - - QPulseAudioOutput *output = new QPulseAudioOutput(device); - return output; -} - -QAbstractAudioDeviceInfo *QPulseAudioPlugin::createDeviceInfo(const QByteArray &device, QAudio::Mode mode) -{ - QPulseAudioDeviceInfo *deviceInfo = new QPulseAudioDeviceInfo(device, mode); - return deviceInfo; -} - -QT_END_NAMESPACE diff --git a/src/plugins/pulseaudio/qpulseaudioplugin.h b/src/plugins/pulseaudio/qpulseaudioplugin.h deleted file mode 100644 index 7d27cad48..000000000 --- a/src/plugins/pulseaudio/qpulseaudioplugin.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPULSEAUDIOPLUGIN_H -#define QPULSEAUDIOPLUGIN_H - -#include <QtMultimedia/qaudiosystemplugin.h> -#include <QtMultimedia/private/qaudiosystempluginext_p.h> - -QT_BEGIN_NAMESPACE - -class QPulseAudioEngine; - -class QPulseAudioPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension -{ - Q_OBJECT - - Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "pulseaudio.json") - Q_INTERFACES(QAudioSystemPluginExtension) - -public: - QPulseAudioPlugin(QObject *parent = 0); - ~QPulseAudioPlugin() {} - - QByteArray defaultDevice(QAudio::Mode mode) const override; - QList<QByteArray> availableDevices(QAudio::Mode mode) const override; - QAbstractAudioInput *createInput(const QByteArray &device) override; - QAbstractAudioOutput *createOutput(const QByteArray &device) override; - QAbstractAudioDeviceInfo *createDeviceInfo(const QByteArray &device, QAudio::Mode mode) override; - -private: - QPulseAudioEngine *m_pulseEngine; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/pulseaudio/qpulsehelpers.cpp b/src/plugins/pulseaudio/qpulsehelpers.cpp deleted file mode 100644 index 0604c97f5..000000000 --- a/src/plugins/pulseaudio/qpulsehelpers.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpulsehelpers.h" - -QT_BEGIN_NAMESPACE - -namespace QPulseAudioInternal -{ -pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format) -{ - pa_sample_spec spec; - - spec.rate = format.sampleRate(); - spec.channels = format.channelCount(); - spec.format = PA_SAMPLE_INVALID; - const bool isBigEndian = (format.byteOrder() == QAudioFormat::BigEndian); - - if (format.sampleType() == QAudioFormat::UnSignedInt) { - if (format.sampleSize() == 8) - spec.format = PA_SAMPLE_U8; - } else if (format.sampleType() == QAudioFormat::SignedInt) { - if (format.sampleSize() == 16) { - spec.format = isBigEndian ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE; - } else if (format.sampleSize() == 24) { - spec.format = isBigEndian ? PA_SAMPLE_S24BE : PA_SAMPLE_S24LE; - } else if (format.sampleSize() == 32) { - spec.format = isBigEndian ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE; - } - } else if (format.sampleType() == QAudioFormat::Float) { - if (format.sampleSize() == 32) - spec.format = isBigEndian ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE; - } - - return spec; -} - -#ifdef DEBUG_PULSE -QString stateToQString(pa_stream_state_t state) -{ - switch (state) - { - case PA_STREAM_UNCONNECTED: return "Unconnected"; - case PA_STREAM_CREATING: return "Creating"; - case PA_STREAM_READY: return "Ready"; - case PA_STREAM_FAILED: return "Failed"; - case PA_STREAM_TERMINATED: return "Terminated"; - } - - return QString("Unknown state: %0").arg(state); -} - -QString sampleFormatToQString(pa_sample_format format) -{ - switch (format) - { - case PA_SAMPLE_U8: return "Unsigned 8 Bit PCM."; - case PA_SAMPLE_ALAW: return "8 Bit a-Law "; - case PA_SAMPLE_ULAW: return "8 Bit mu-Law"; - case PA_SAMPLE_S16LE: return "Signed 16 Bit PCM, little endian (PC)."; - case PA_SAMPLE_S16BE: return "Signed 16 Bit PCM, big endian."; - case PA_SAMPLE_FLOAT32LE: return "32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0"; - case PA_SAMPLE_FLOAT32BE: return "32 Bit IEEE floating point, big endian, range -1.0 to 1.0"; - case PA_SAMPLE_S32LE: return "Signed 32 Bit PCM, little endian (PC)."; - case PA_SAMPLE_S32BE: return "Signed 32 Bit PCM, big endian."; - case PA_SAMPLE_S24LE: return "Signed 24 Bit PCM packed, little endian (PC)."; - case PA_SAMPLE_S24BE: return "Signed 24 Bit PCM packed, big endian."; - case PA_SAMPLE_S24_32LE: return "Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC)."; - case PA_SAMPLE_S24_32BE: return "Signed 24 Bit PCM in LSB of 32 Bit words, big endian."; - case PA_SAMPLE_MAX: return "Upper limit of valid sample types."; - case PA_SAMPLE_INVALID: return "Invalid sample format"; - } - - return QString("Invalid value: %0").arg(format); -} - -QString stateToQString(pa_context_state_t state) -{ - switch (state) - { - case PA_CONTEXT_UNCONNECTED: return "Unconnected"; - case PA_CONTEXT_CONNECTING: return "Connecting"; - case PA_CONTEXT_AUTHORIZING: return "Authorizing"; - case PA_CONTEXT_SETTING_NAME: return "Setting Name"; - case PA_CONTEXT_READY: return "Ready"; - case PA_CONTEXT_FAILED: return "Failed"; - case PA_CONTEXT_TERMINATED: return "Terminated"; - } - - return QString("Unknown state: %0").arg(state); -} -#endif - -QAudioFormat sampleSpecToAudioFormat(pa_sample_spec spec) -{ - QAudioFormat format; - format.setSampleRate(spec.rate); - format.setChannelCount(spec.channels); - format.setCodec("audio/pcm"); - - switch (spec.format) { - case PA_SAMPLE_U8: - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::UnSignedInt); - format.setSampleSize(8); - break; - case PA_SAMPLE_ALAW: - // TODO: - break; - case PA_SAMPLE_ULAW: - // TODO: - break; - case PA_SAMPLE_S16LE: - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(16); - break; - case PA_SAMPLE_S16BE: - format.setByteOrder(QAudioFormat::BigEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(16); - break; - case PA_SAMPLE_FLOAT32LE: - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::Float); - format.setSampleSize(32); - break; - case PA_SAMPLE_FLOAT32BE: - format.setByteOrder(QAudioFormat::BigEndian); - format.setSampleType(QAudioFormat::Float); - format.setSampleSize(32); - break; - case PA_SAMPLE_S32LE: - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(32); - break; - case PA_SAMPLE_S32BE: - format.setByteOrder(QAudioFormat::BigEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(32); - break; - case PA_SAMPLE_S24LE: - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(24); - break; - case PA_SAMPLE_S24BE: - format.setByteOrder(QAudioFormat::BigEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(24); - break; - case PA_SAMPLE_S24_32LE: - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(24); - break; - case PA_SAMPLE_S24_32BE: - format.setByteOrder(QAudioFormat::BigEndian); - format.setSampleType(QAudioFormat::SignedInt); - format.setSampleSize(24); - break; - case PA_SAMPLE_MAX: - case PA_SAMPLE_INVALID: - default: - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::Unknown); - format.setSampleSize(0); - } - - return format; -} -} - -QT_END_NAMESPACE diff --git a/src/plugins/pulseaudio/qpulsehelpers.h b/src/plugins/pulseaudio/qpulsehelpers.h deleted file mode 100644 index 279cecc2f..000000000 --- a/src/plugins/pulseaudio/qpulsehelpers.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPULSEHELPER_H -#define QPULSEHELPER_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qaudiodeviceinfo.h" -#include <qaudioformat.h> -#include <pulse/pulseaudio.h> - -QT_BEGIN_NAMESPACE - -namespace QPulseAudioInternal -{ -pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format); -QString stateToQString(pa_stream_state_t state); -QString stateToQString(pa_context_state_t state); -QString sampleFormatToQString(pa_sample_format format); -QAudioFormat sampleSpecToAudioFormat(pa_sample_spec spec); -} - -QT_END_NAMESPACE - -#endif |