From 53f6413bd9695f48fa94add249c4b6f832f8bf8a Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 25 Dec 2016 20:04:19 +0100 Subject: [PATCH] Audio input: removed mutex lock on write data. Audio output: removed mutex lock on read data --- sdrbase/audio/audioinput.cpp | 367 +++++++++++++++++----------------- sdrbase/audio/audiooutput.cpp | 9 +- 2 files changed, 189 insertions(+), 187 deletions(-) diff --git a/sdrbase/audio/audioinput.cpp b/sdrbase/audio/audioinput.cpp index ca84df4b7..29d9ac073 100644 --- a/sdrbase/audio/audioinput.cpp +++ b/sdrbase/audio/audioinput.cpp @@ -1,183 +1,184 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB // -// // -// This program is free software; you can redistribute it and/or modify // -// it under the terms of the GNU General Public License as published by // -// the Free Software Foundation as version 3 of the License, or // -// // -// This program is distributed in the hope that it will be useful, // -// but WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // -// GNU General Public License V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include "audio/audioinput.h" -#include "audio/audiofifo.h" - -AudioInput::AudioInput() : - m_mutex(), - m_audioInput(0), - m_audioUsageCount(0), - m_onExit(false), - m_audioFifos() -{ -} - -AudioInput::~AudioInput() -{ - stop(); - - QMutexLocker mutexLocker(&m_mutex); - - for (AudioFifos::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) - { - delete *it; - } - - m_audioFifos.clear(); -} - -bool AudioInput::start(int device, int rate) -{ - QMutexLocker mutexLocker(&m_mutex); - - if (m_audioUsageCount == 0) - { - QAudioDeviceInfo devInfo; - - if (device < 0) - { - devInfo = QAudioDeviceInfo::defaultInputDevice(); - qWarning("AudioInput::start: using default device %s", qPrintable(devInfo.defaultInputDevice().deviceName())); - } - else - { - QList devicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); - - if (device < devicesInfo.size()) - { - devInfo = devicesInfo[device]; - qWarning("AudioInput::start: using audio device #%d: %s", device, qPrintable(devInfo.defaultInputDevice().deviceName())); - } - else - { - devInfo = QAudioDeviceInfo::defaultInputDevice(); - qWarning("AudioInput::start: audio device #%d does not exist. Using default device %s", device, qPrintable(devInfo.defaultInputDevice().deviceName())); - } - } - - //QAudioDeviceInfo devInfo(QAudioDeviceInfo::defaultOutputDevice()); - - m_audioFormat.setSampleRate(rate); - m_audioFormat.setChannelCount(2); - m_audioFormat.setSampleSize(16); - m_audioFormat.setCodec("audio/pcm"); - m_audioFormat.setByteOrder(QAudioFormat::LittleEndian); - m_audioFormat.setSampleType(QAudioFormat::SignedInt); - - if (!devInfo.isFormatSupported(m_audioFormat)) - { - m_audioFormat = devInfo.nearestFormat(m_audioFormat); - qWarning("AudioInput::start: %d Hz S16_LE audio format not supported. New rate: %d", rate, m_audioFormat.sampleRate()); - } - - if (m_audioFormat.sampleSize() != 16) - { - qWarning("AudioInput::start: Audio device ( %s ) failed", qPrintable(devInfo.defaultInputDevice().deviceName())); - return false; - } - - m_audioInput = new QAudioInput(devInfo, m_audioFormat); - - QIODevice::open(QIODevice::ReadWrite); - - m_audioInput->start(this); - - if (m_audioInput->state() != QAudio::ActiveState) - { - qWarning("AudioInput::start: cannot start"); - } - } - - m_audioUsageCount++; - - return true; -} - -void AudioInput::stop() -{ - qDebug("AudioInput::stop"); - - QMutexLocker mutexLocker(&m_mutex); - - if (m_audioUsageCount > 0) - { - m_audioUsageCount--; - - if (m_audioUsageCount == 0) - { - QIODevice::close(); - - if (!m_onExit) { - delete m_audioInput; - } - } - } -} - -void AudioInput::addFifo(AudioFifo* audioFifo) -{ - QMutexLocker mutexLocker(&m_mutex); - - m_audioFifos.push_back(audioFifo); -} - -void AudioInput::removeFifo(AudioFifo* audioFifo) -{ - QMutexLocker mutexLocker(&m_mutex); - - m_audioFifos.remove(audioFifo); -} - -qint64 AudioInput::readData(char* data, qint64 maxLen) -{ - Q_UNUSED(data); - Q_UNUSED(maxLen); - return 0; -} - -qint64 AudioInput::writeData(const char *data, qint64 len) -{ - // @TODO: Study this mutex on OSX, for now deadlocks possible -#ifndef __APPLE__ - QMutexLocker mutexLocker(&m_mutex); -#endif - - if ((m_audioFormat.sampleSize() != 16) - || (m_audioFormat.sampleType() != QAudioFormat::SignedInt) - || (m_audioFormat.byteOrder() != QAudioFormat::LittleEndian)) - { - qCritical("AudioInput::writeData: invalid format not S16LE"); - return 0; - } - - if (m_audioFormat.channelCount() != 2) { - qCritical("AudioInput::writeData: invalid format not stereo"); - return 0; - } - - for (AudioFifos::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) - { - (*it)->write(reinterpret_cast(data), len/4, 10); - } - - return len; -} - +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include "audio/audioinput.h" +#include "audio/audiofifo.h" + +AudioInput::AudioInput() : + m_mutex(), + m_audioInput(0), + m_audioUsageCount(0), + m_onExit(false), + m_audioFifos() +{ +} + +AudioInput::~AudioInput() +{ + stop(); + + QMutexLocker mutexLocker(&m_mutex); + + for (AudioFifos::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) + { + delete *it; + } + + m_audioFifos.clear(); +} + +bool AudioInput::start(int device, int rate) +{ + QMutexLocker mutexLocker(&m_mutex); + + if (m_audioUsageCount == 0) + { + QAudioDeviceInfo devInfo; + + if (device < 0) + { + devInfo = QAudioDeviceInfo::defaultInputDevice(); + qWarning("AudioInput::start: using default device %s", qPrintable(devInfo.defaultInputDevice().deviceName())); + } + else + { + QList devicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); + + if (device < devicesInfo.size()) + { + devInfo = devicesInfo[device]; + qWarning("AudioInput::start: using audio device #%d: %s", device, qPrintable(devInfo.defaultInputDevice().deviceName())); + } + else + { + devInfo = QAudioDeviceInfo::defaultInputDevice(); + qWarning("AudioInput::start: audio device #%d does not exist. Using default device %s", device, qPrintable(devInfo.defaultInputDevice().deviceName())); + } + } + + //QAudioDeviceInfo devInfo(QAudioDeviceInfo::defaultOutputDevice()); + + m_audioFormat.setSampleRate(rate); + m_audioFormat.setChannelCount(2); + m_audioFormat.setSampleSize(16); + m_audioFormat.setCodec("audio/pcm"); + m_audioFormat.setByteOrder(QAudioFormat::LittleEndian); + m_audioFormat.setSampleType(QAudioFormat::SignedInt); + + if (!devInfo.isFormatSupported(m_audioFormat)) + { + m_audioFormat = devInfo.nearestFormat(m_audioFormat); + qWarning("AudioInput::start: %d Hz S16_LE audio format not supported. New rate: %d", rate, m_audioFormat.sampleRate()); + } + + if (m_audioFormat.sampleSize() != 16) + { + qWarning("AudioInput::start: Audio device ( %s ) failed", qPrintable(devInfo.defaultInputDevice().deviceName())); + return false; + } + + m_audioInput = new QAudioInput(devInfo, m_audioFormat); + + QIODevice::open(QIODevice::ReadWrite); + + m_audioInput->start(this); + + if (m_audioInput->state() != QAudio::ActiveState) + { + qWarning("AudioInput::start: cannot start"); + } + } + + m_audioUsageCount++; + + return true; +} + +void AudioInput::stop() +{ + qDebug("AudioInput::stop"); + + QMutexLocker mutexLocker(&m_mutex); + + if (m_audioUsageCount > 0) + { + m_audioUsageCount--; + + if (m_audioUsageCount == 0) + { + QIODevice::close(); + + if (!m_onExit) { + delete m_audioInput; + } + } + } +} + +void AudioInput::addFifo(AudioFifo* audioFifo) +{ + QMutexLocker mutexLocker(&m_mutex); + + m_audioFifos.push_back(audioFifo); +} + +void AudioInput::removeFifo(AudioFifo* audioFifo) +{ + QMutexLocker mutexLocker(&m_mutex); + + m_audioFifos.remove(audioFifo); +} + +qint64 AudioInput::readData(char* data, qint64 maxLen) +{ + Q_UNUSED(data); + Q_UNUSED(maxLen); + return 0; +} + +qint64 AudioInput::writeData(const char *data, qint64 len) +{ + // Study this mutex on OSX, for now deadlocks possible + // Removed as it may indeed cause lockups and is in fact useless. +//#ifndef __APPLE__ +// QMutexLocker mutexLocker(&m_mutex); +//#endif + + if ((m_audioFormat.sampleSize() != 16) + || (m_audioFormat.sampleType() != QAudioFormat::SignedInt) + || (m_audioFormat.byteOrder() != QAudioFormat::LittleEndian)) + { + qCritical("AudioInput::writeData: invalid format not S16LE"); + return 0; + } + + if (m_audioFormat.channelCount() != 2) { + qCritical("AudioInput::writeData: invalid format not stereo"); + return 0; + } + + for (AudioFifos::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) + { + (*it)->write(reinterpret_cast(data), len/4, 10); + } + + return len; +} + diff --git a/sdrbase/audio/audiooutput.cpp b/sdrbase/audio/audiooutput.cpp index 9f5d264c2..31698243b 100644 --- a/sdrbase/audio/audiooutput.cpp +++ b/sdrbase/audio/audiooutput.cpp @@ -158,10 +158,11 @@ qint64 AudioOutput::readData(char* data, qint64 maxLen) { //qDebug("AudioOutput::readData: %lld", maxLen); - // @TODO: Study this mutex on OSX, for now deadlocks possible -#ifndef __APPLE__ - QMutexLocker mutexLocker(&m_mutex); -#endif + // Study this mutex on OSX, for now deadlocks possible + // Removed as it may indeed cause lockups and is in fact useless. +//#ifndef __APPLE__ +// QMutexLocker mutexLocker(&m_mutex); +//#endif unsigned int framesPerBuffer = maxLen / 4;