summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-05-21 14:08:18 +0200
committerLars Knoll <lars.knoll@qt.io>2021-05-21 12:28:41 +0000
commitfaaa989d87831b2d287e6170af4a44cdef087780 (patch)
tree436a1e095f0af5354bab24e56db6b0c2960e6955 /src/multimedia
parent6e93058aa909875225319edf1ebb4d2d1697d527 (diff)
Fix the qaudioinput test failures on macOS
There was a race condition in the code as the audio samples can be read read the device from a separate thread. Also the buffer to write to needs to be opened. Change-Id: I89896a8e3258999d51e1415f75df979405306937 Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/platform/darwin/audio/qcoreaudioinput.mm67
-rw-r--r--src/multimedia/platform/darwin/audio/qcoreaudioinput_p.h11
2 files changed, 51 insertions, 27 deletions
diff --git a/src/multimedia/platform/darwin/audio/qcoreaudioinput.mm b/src/multimedia/platform/darwin/audio/qcoreaudioinput.mm
index a6d3e17af..893bed16c 100644
--- a/src/multimedia/platform/darwin/audio/qcoreaudioinput.mm
+++ b/src/multimedia/platform/darwin/audio/qcoreaudioinput.mm
@@ -457,7 +457,7 @@ CoreAudioInput::CoreAudioInput(const QAudioDeviceInfo &device)
, m_clockFrequency(CoreAudioUtils::frequency() / 1000)
, m_errorCode(QAudio::NoError)
, m_stateCode(QAudio::StoppedState)
- , m_audioBuffer(0)
+ , m_audioBuffer(nullptr)
, m_volume(1.0)
{
QAudioDeviceInfo di = device;
@@ -652,13 +652,16 @@ bool CoreAudioInput::open()
// Now allocate a few buffers to be safe.
m_periodSizeBytes = m_internalBufferSize = numberOfFrames * m_streamFormat.mBytesPerFrame;
- m_audioBuffer = new QCoreAudioInputBuffer(m_internalBufferSize * 4,
- m_periodSizeBytes,
- m_deviceFormat,
- m_streamFormat,
- this);
+ {
+ QMutexLocker lock(m_audioBuffer);
+ m_audioBuffer = new QCoreAudioInputBuffer(m_internalBufferSize * 4,
+ m_periodSizeBytes,
+ m_deviceFormat,
+ m_streamFormat,
+ this);
- m_audioBuffer->setVolume(m_volume);
+ m_audioBuffer->setVolume(m_volume);
+ }
m_audioIO = new QCoreAudioInputDevice(m_audioBuffer, this);
// Init
@@ -675,6 +678,7 @@ bool CoreAudioInput::open()
void CoreAudioInput::close()
{
+ stop();
if (m_audioUnit != 0) {
AudioOutputUnitStop(m_audioUnit);
AudioUnitUninitialize(m_audioUnit);
@@ -682,6 +686,8 @@ void CoreAudioInput::close()
}
delete m_audioBuffer;
+ m_audioBuffer = nullptr;
+ m_isOpen = false;
}
void CoreAudioInput::start(QIODevice *device)
@@ -695,8 +701,11 @@ void CoreAudioInput::start(QIODevice *device)
}
reset();
- m_audioBuffer->reset();
- m_audioBuffer->setFlushDevice(op);
+ {
+ QMutexLocker lock(m_audioBuffer);
+ m_audioBuffer->reset();
+ m_audioBuffer->setFlushDevice(op);
+ }
if (op == 0)
op = m_audioIO;
@@ -723,8 +732,11 @@ QIODevice *CoreAudioInput::start()
}
reset();
- m_audioBuffer->reset();
- m_audioBuffer->setFlushDevice(op);
+ {
+ QMutexLocker lock(m_audioBuffer);
+ m_audioBuffer->reset();
+ m_audioBuffer->setFlushDevice(op);
+ }
if (op == 0)
op = m_audioIO;
@@ -744,7 +756,7 @@ QIODevice *CoreAudioInput::start()
void CoreAudioInput::stop()
{
- QMutexLocker lock(&m_mutex);
+ QMutexLocker lock(m_audioBuffer);
if (m_stateCode != QAudio::StoppedState) {
audioThreadStop();
m_audioBuffer->flush(true);
@@ -758,7 +770,7 @@ void CoreAudioInput::stop()
void CoreAudioInput::reset()
{
- QMutexLocker lock(&m_mutex);
+ QMutexLocker lock(m_audioBuffer);
if (m_stateCode != QAudio::StoppedState) {
audioThreadStop();
@@ -772,7 +784,7 @@ void CoreAudioInput::reset()
void CoreAudioInput::suspend()
{
- QMutexLocker lock(&m_mutex);
+ QMutexLocker lock(m_audioBuffer);
if (m_stateCode == QAudio::ActiveState || m_stateCode == QAudio::IdleState) {
audioThreadStop();
@@ -785,7 +797,7 @@ void CoreAudioInput::suspend()
void CoreAudioInput::resume()
{
- QMutexLocker lock(&m_mutex);
+ QMutexLocker lock(m_audioBuffer);
if (m_stateCode == QAudio::SuspendedState) {
audioThreadStart();
@@ -798,6 +810,7 @@ void CoreAudioInput::resume()
qsizetype CoreAudioInput::bytesReady() const
{
+ QMutexLocker lock(m_audioBuffer);
if (!m_audioBuffer)
return 0;
return m_audioBuffer->used();
@@ -846,6 +859,7 @@ QAudioFormat CoreAudioInput::format() const
void CoreAudioInput::setVolume(qreal volume)
{
+ QMutexLocker lock(m_audioBuffer);
m_volume = volume;
if (m_audioBuffer)
m_audioBuffer->setVolume(m_volume);
@@ -874,20 +888,20 @@ void CoreAudioInput::audioThreadStop()
{
stopTimers();
if (m_audioThreadState.testAndSetAcquire(Running, Stopped))
- m_threadFinished.wait(&m_mutex);
+ m_audioBuffer->wait();
}
void CoreAudioInput::audioDeviceStop()
{
AudioOutputUnitStop(m_audioUnit);
m_audioThreadState.storeRelaxed(Stopped);
- m_threadFinished.wakeOne();
+ m_audioBuffer->wake();
}
void CoreAudioInput::audioDeviceActive()
{
if (m_stateCode == QAudio::IdleState) {
- QMutexLocker lock(&m_mutex);
+ QMutexLocker lock(m_audioBuffer);
m_stateCode = QAudio::ActiveState;
emit stateChanged(m_stateCode);
}
@@ -896,7 +910,7 @@ void CoreAudioInput::audioDeviceActive()
void CoreAudioInput::audioDeviceFull()
{
if (m_stateCode == QAudio::ActiveState) {
- QMutexLocker lock(&m_mutex);
+ QMutexLocker lock(m_audioBuffer);
m_errorCode = QAudio::UnderrunError;
m_stateCode = QAudio::IdleState;
emit stateChanged(m_stateCode);
@@ -906,7 +920,7 @@ void CoreAudioInput::audioDeviceFull()
void CoreAudioInput::audioDeviceError()
{
if (m_stateCode == QAudio::ActiveState) {
- QMutexLocker lock(&m_mutex);
+ QMutexLocker lock(m_audioBuffer);
audioDeviceStop();
m_errorCode = QAudio::IOError;
@@ -937,11 +951,14 @@ OSStatus CoreAudioInput::inputCallback(void *inRefCon, AudioUnitRenderActionFlag
else {
qint64 framesWritten;
- framesWritten = d->m_audioBuffer->renderFromDevice(d->m_audioUnit,
- ioActionFlags,
- inTimeStamp,
- inBusNumber,
- inNumberFrames);
+ {
+ QMutexLocker locker(d->m_audioBuffer);
+ framesWritten = d->m_audioBuffer->renderFromDevice(d->m_audioUnit,
+ ioActionFlags,
+ inTimeStamp,
+ inBusNumber,
+ inNumberFrames);
+ }
if (framesWritten > 0) {
d->m_totalFrames += framesWritten;
diff --git a/src/multimedia/platform/darwin/audio/qcoreaudioinput_p.h b/src/multimedia/platform/darwin/audio/qcoreaudioinput_p.h
index b2124cc8c..acbe0ff14 100644
--- a/src/multimedia/platform/darwin/audio/qcoreaudioinput_p.h
+++ b/src/multimedia/platform/darwin/audio/qcoreaudioinput_p.h
@@ -141,6 +141,12 @@ public:
int available() const;
int used() const;
+ void lock() { m_mutex.lock(); }
+ void unlock() { m_mutex.unlock(); }
+
+ void wait() { m_threadFinished.wait(&m_mutex); }
+ void wake() { m_threadFinished.wakeOne(); }
+
signals:
void readyRead();
@@ -148,6 +154,9 @@ private slots:
void flushBuffer();
private:
+ QMutex m_mutex;
+ QWaitCondition m_threadFinished;
+
bool m_deviceError;
int m_maxPeriodSize;
int m_periodTime;
@@ -260,8 +269,6 @@ private:
QAudio::Error m_errorCode;
QAudio::State m_stateCode;
QCoreAudioInputBuffer *m_audioBuffer;
- QMutex m_mutex;
- QWaitCondition m_threadFinished;
QAtomicInt m_audioThreadState;
AudioStreamBasicDescription m_streamFormat;
AudioStreamBasicDescription m_deviceFormat;