diff options
author | Scott Murray <scott.murray@konsulko.com> | 2017-04-02 12:49:28 -0400 |
---|---|---|
committer | Scott Murray <scott.murray@konsulko.com> | 2017-04-10 09:21:36 -0400 |
commit | aeb67506173a7b8cef089fa725c3abe1f629dc67 (patch) | |
tree | ef427cbebb92d873d9a2903445c32320ab20c8eb /OutputBuffer.cpp | |
parent | a30670cd12e03dc874d2f22c48f497817c78ecdc (diff) |
Switch to using Qt's QAudioOutput for outputHEADflounder_5.99.1flounder/5.99.1dab_3.99.1dab/3.99.15.99.13.99.1master
The underlying issue in the hang reported in SPEC-455 is that due to
the synchronous nature of the pa_simple_* PulseAudio API, the
pa_simple_write call used blocks when a stream is corked . That
prevents the tuner plugin's output thread from exiting when playback is
stopped, resulting in the observed hang. After examining the available
options, it seemed like switching to Qt's QAudioOutput class made sense
since it allows using the asynchronous PulseAudio API easily, and like
the QRadio class the tuner plugin implements, it is part of QtMultimedia
itself.
Note that the radio_output.* files have been removed as the code is no
longer used, and a new pair of OutputBuffer source files have been added
to contain the small class that is used to connect the RTL-SDR output to
QAudioOutput.
Bug-AGL: SPEC-455
Change-Id: I0d690143b9c70fdca24f9fbf3b016feef8ae627b
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Diffstat (limited to 'OutputBuffer.cpp')
-rw-r--r-- | OutputBuffer.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/OutputBuffer.cpp b/OutputBuffer.cpp new file mode 100644 index 0000000..c6fe30a --- /dev/null +++ b/OutputBuffer.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2017 Konsulko Group + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <OutputBuffer.h> + +OutputBuffer::OutputBuffer(const QAudioFormat &format, QObject *parent) + : QIODevice(parent) +{ + m_sample_size = format.bytesPerFrame(); +} + +OutputBuffer::~OutputBuffer() +{ +} + +void OutputBuffer::start() +{ + open(QIODevice::ReadWrite); +} + +void OutputBuffer::stop() +{ + close(); + QMutexLocker locker(&m_mutex); + m_buffer.clear(); +} + +qint64 OutputBuffer::readData(char *data, qint64 len) +{ + QMutexLocker locker(&m_mutex); + int n = qMin((qint64) m_buffer.size(), len); + + // Make sure reads are in units of the sample size + n = n - (n % m_sample_size); + + if (!m_buffer.isEmpty()) { + memcpy(data, m_buffer.constData(), n); + m_buffer.remove(0, n); + } + return n; +} + +qint64 OutputBuffer::writeData(const char *data, qint64 len) +{ + QMutexLocker locker(&m_mutex); + m_buffer.append(data, len); + return len; +} + +qint64 OutputBuffer::bytesAvailable() +{ + QMutexLocker locker(&m_mutex); + return m_buffer.size() + QIODevice::bytesAvailable(); +} |