summaryrefslogtreecommitdiffstats
path: root/src/multimedia/audio/qaudioinput_mac_p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/audio/qaudioinput_mac_p.cpp')
-rw-r--r--src/multimedia/audio/qaudioinput_mac_p.cpp989
1 files changed, 0 insertions, 989 deletions
diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp
deleted file mode 100644
index 184935a..0000000
--- a/src/multimedia/audio/qaudioinput_mac_p.cpp
+++ /dev/null
@@ -1,989 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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.
-//
-// INTERNAL USE ONLY: Do NOT use for any other purpose.
-//
-
-#include <QtCore/qendian.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qdebug.h>
-
-#include <qaudioinput.h>
-
-#include "qaudio_mac_p.h"
-#include "qaudioinput_mac_p.h"
-#include "qaudiodeviceinfo_mac_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-namespace QtMultimediaInternal
-{
-
-static const int default_buffer_size = 4 * 1024;
-
-class QAudioBufferList
-{
-public:
- QAudioBufferList(AudioStreamBasicDescription const& streamFormat):
- owner(false),
- sf(streamFormat)
- {
- const bool isInterleaved = (sf.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
- const int numberOfBuffers = isInterleaved ? 1 : sf.mChannelsPerFrame;
-
- dataSize = 0;
-
- bfs = reinterpret_cast<AudioBufferList*>(qMalloc(sizeof(AudioBufferList) +
- (sizeof(AudioBuffer) * numberOfBuffers)));
-
- bfs->mNumberBuffers = numberOfBuffers;
- for (int i = 0; i < numberOfBuffers; ++i) {
- bfs->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1;
- bfs->mBuffers[i].mDataByteSize = 0;
- bfs->mBuffers[i].mData = 0;
- }
- }
-
- QAudioBufferList(AudioStreamBasicDescription const& streamFormat, char* buffer, int bufferSize):
- owner(false),
- sf(streamFormat),
- bfs(0)
- {
- dataSize = bufferSize;
-
- bfs = reinterpret_cast<AudioBufferList*>(qMalloc(sizeof(AudioBufferList) + sizeof(AudioBuffer)));
-
- bfs->mNumberBuffers = 1;
- bfs->mBuffers[0].mNumberChannels = 1;
- bfs->mBuffers[0].mDataByteSize = dataSize;
- bfs->mBuffers[0].mData = buffer;
- }
-
- QAudioBufferList(AudioStreamBasicDescription const& streamFormat, int framesToBuffer):
- owner(true),
- sf(streamFormat),
- bfs(0)
- {
- const bool isInterleaved = (sf.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
- const int numberOfBuffers = isInterleaved ? 1 : sf.mChannelsPerFrame;
-
- dataSize = framesToBuffer * sf.mBytesPerFrame;
-
- bfs = reinterpret_cast<AudioBufferList*>(qMalloc(sizeof(AudioBufferList) +
- (sizeof(AudioBuffer) * numberOfBuffers)));
- bfs->mNumberBuffers = numberOfBuffers;
- for (int i = 0; i < numberOfBuffers; ++i) {
- bfs->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1;
- bfs->mBuffers[i].mDataByteSize = dataSize;
- bfs->mBuffers[i].mData = qMalloc(dataSize);
- }
- }
-
- ~QAudioBufferList()
- {
- if (owner) {
- for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i)
- qFree(bfs->mBuffers[i].mData);
- }
-
- qFree(bfs);
- }
-
- AudioBufferList* audioBufferList() const
- {
- return bfs;
- }
-
- char* data(int buffer = 0) const
- {
- return static_cast<char*>(bfs->mBuffers[buffer].mData);
- }
-
- qint64 bufferSize(int buffer = 0) const
- {
- return bfs->mBuffers[buffer].mDataByteSize;
- }
-
- int frameCount(int buffer = 0) const
- {
- return bfs->mBuffers[buffer].mDataByteSize / sf.mBytesPerFrame;
- }
-
- int packetCount(int buffer = 0) const
- {
- return bfs->mBuffers[buffer].mDataByteSize / sf.mBytesPerPacket;
- }
-
- int packetSize() const
- {
- return sf.mBytesPerPacket;
- }
-
- void reset()
- {
- for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i) {
- bfs->mBuffers[i].mDataByteSize = dataSize;
- bfs->mBuffers[i].mData = 0;
- }
- }
-
-private:
- bool owner;
- int dataSize;
- AudioStreamBasicDescription sf;
- AudioBufferList* bfs;
-};
-
-class QAudioPacketFeeder
-{
-public:
- QAudioPacketFeeder(QAudioBufferList* abl):
- audioBufferList(abl)
- {
- totalPackets = audioBufferList->packetCount();
- position = 0;
- }
-
- bool feed(AudioBufferList& dst, UInt32& packetCount)
- {
- if (position == totalPackets) {
- dst.mBuffers[0].mDataByteSize = 0;
- packetCount = 0;
- return false;
- }
-
- if (totalPackets - position < packetCount)
- packetCount = totalPackets - position;
-
- dst.mBuffers[0].mDataByteSize = packetCount * audioBufferList->packetSize();
- dst.mBuffers[0].mData = audioBufferList->data() + (position * audioBufferList->packetSize());
-
- position += packetCount;
-
- return true;
- }
-
- bool empty() const
- {
- return position == totalPackets;
- }
-
-private:
- UInt32 totalPackets;
- UInt32 position;
- QAudioBufferList* audioBufferList;
-};
-
-class QAudioInputBuffer : public QObject
-{
- Q_OBJECT
-
-public:
- QAudioInputBuffer(int bufferSize,
- int maxPeriodSize,
- AudioStreamBasicDescription const& inputFormat,
- AudioStreamBasicDescription const& outputFormat,
- QObject* parent):
- QObject(parent),
- m_deviceError(false),
- m_audioConverter(0),
- m_inputFormat(inputFormat),
- m_outputFormat(outputFormat)
- {
- m_maxPeriodSize = maxPeriodSize;
- m_periodTime = m_maxPeriodSize / m_outputFormat.mBytesPerFrame * 1000 / m_outputFormat.mSampleRate;
- m_buffer = new QAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize)));
- m_inputBufferList = new QAudioBufferList(m_inputFormat);
-
- m_flushTimer = new QTimer(this);
- connect(m_flushTimer, SIGNAL(timeout()), SLOT(flushBuffer()));
-
- if (toQAudioFormat(inputFormat) != toQAudioFormat(outputFormat)) {
- if (AudioConverterNew(&m_inputFormat, &m_outputFormat, &m_audioConverter) != noErr) {
- qWarning() << "QAudioInput: Unable to create an Audio Converter";
- m_audioConverter = 0;
- }
- }
- }
-
- ~QAudioInputBuffer()
- {
- delete m_buffer;
- }
-
- qint64 renderFromDevice(AudioUnit audioUnit,
- AudioUnitRenderActionFlags* ioActionFlags,
- const AudioTimeStamp* inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames)
- {
- const bool pullMode = m_device == 0;
-
- OSStatus err;
- qint64 framesRendered = 0;
-
- m_inputBufferList->reset();
- err = AudioUnitRender(audioUnit,
- ioActionFlags,
- inTimeStamp,
- inBusNumber,
- inNumberFrames,
- m_inputBufferList->audioBufferList());
-
- if (m_audioConverter != 0) {
- QAudioPacketFeeder feeder(m_inputBufferList);
-
- int copied = 0;
- const int available = m_buffer->free();
-
- while (err == noErr && !feeder.empty()) {
- QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available);
-
- if (region.second == 0)
- break;
-
- AudioBufferList output;
- output.mNumberBuffers = 1;
- output.mBuffers[0].mNumberChannels = 1;
- output.mBuffers[0].mDataByteSize = region.second;
- output.mBuffers[0].mData = region.first;
-
- UInt32 packetSize = region.second / m_outputFormat.mBytesPerPacket;
- err = AudioConverterFillComplexBuffer(m_audioConverter,
- converterCallback,
- &feeder,
- &packetSize,
- &output,
- 0);
- region.second = output.mBuffers[0].mDataByteSize;
- copied += region.second;
-
- m_buffer->releaseWriteRegion(region);
- }
-
- framesRendered += copied / m_outputFormat.mBytesPerFrame;
- }
- else {
- const int available = m_inputBufferList->bufferSize();
- bool wecan = true;
- int copied = 0;
-
- while (wecan && copied < available) {
- QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available - copied);
-
- if (region.second > 0) {
- memcpy(region.first, m_inputBufferList->data() + copied, region.second);
- copied += region.second;
- }
- else
- wecan = false;
-
- m_buffer->releaseWriteRegion(region);
- }
-
- framesRendered = copied / m_outputFormat.mBytesPerFrame;
- }
-
- if (pullMode && framesRendered > 0)
- emit readyRead();
-
- return framesRendered;
- }
-
- qint64 readBytes(char* data, qint64 len)
- {
- bool wecan = true;
- qint64 bytesCopied = 0;
-
- len -= len % m_maxPeriodSize;
- while (wecan && bytesCopied < len) {
- QAudioRingBuffer::Region region = m_buffer->acquireReadRegion(len - bytesCopied);
-
- if (region.second > 0) {
- memcpy(data + bytesCopied, region.first, region.second);
- bytesCopied += region.second;
- }
- else
- wecan = false;
-
- m_buffer->releaseReadRegion(region);
- }
-
- return bytesCopied;
- }
-
- void setFlushDevice(QIODevice* device)
- {
- if (m_device != device)
- m_device = device;
- }
-
- void startFlushTimer()
- {
- if (m_device != 0) {
- m_flushTimer->start((m_buffer->size() - (m_maxPeriodSize * 2)) / m_maxPeriodSize * m_periodTime);
- }
- }
-
- void stopFlushTimer()
- {
- m_flushTimer->stop();
- }
-
- void flush(bool all = false)
- {
- if (m_device == 0)
- return;
-
- const int used = m_buffer->used();
- const int readSize = all ? used : used - (used % m_maxPeriodSize);
-
- if (readSize > 0) {
- bool wecan = true;
- int flushed = 0;
-
- while (!m_deviceError && wecan && flushed < readSize) {
- QAudioRingBuffer::Region region = m_buffer->acquireReadRegion(readSize - flushed);
-
- if (region.second > 0) {
- int bytesWritten = m_device->write(region.first, region.second);
- if (bytesWritten < 0) {
- stopFlushTimer();
- m_deviceError = true;
- }
- else {
- region.second = bytesWritten;
- flushed += bytesWritten;
- wecan = bytesWritten != 0;
- }
- }
- else
- wecan = false;
-
- m_buffer->releaseReadRegion(region);
- }
- }
- }
-
- void reset()
- {
- m_buffer->reset();
- m_deviceError = false;
- }
-
- int available() const
- {
- return m_buffer->free();
- }
-
- int used() const
- {
- return m_buffer->used();
- }
-
-signals:
- void readyRead();
-
-private slots:
- void flushBuffer()
- {
- flush();
- }
-
-private:
- bool m_deviceError;
- int m_maxPeriodSize;
- int m_periodTime;
- QIODevice* m_device;
- QTimer* m_flushTimer;
- QAudioRingBuffer* m_buffer;
- QAudioBufferList* m_inputBufferList;
- AudioConverterRef m_audioConverter;
- AudioStreamBasicDescription m_inputFormat;
- AudioStreamBasicDescription m_outputFormat;
-
- const static OSStatus as_empty = 'qtem';
-
- // Converter callback
- static OSStatus converterCallback(AudioConverterRef inAudioConverter,
- UInt32* ioNumberDataPackets,
- AudioBufferList* ioData,
- AudioStreamPacketDescription** outDataPacketDescription,
- void* inUserData)
- {
- Q_UNUSED(inAudioConverter);
- Q_UNUSED(outDataPacketDescription);
-
- QAudioPacketFeeder* feeder = static_cast<QAudioPacketFeeder*>(inUserData);
-
- if (!feeder->feed(*ioData, *ioNumberDataPackets))
- return as_empty;
-
- return noErr;
- }
-};
-
-
-class MacInputDevice : public QIODevice
-{
- Q_OBJECT
-
-public:
- MacInputDevice(QAudioInputBuffer* audioBuffer, QObject* parent):
- QIODevice(parent),
- m_audioBuffer(audioBuffer)
- {
- open(QIODevice::ReadOnly | QIODevice::Unbuffered);
- connect(m_audioBuffer, SIGNAL(readyRead()), SIGNAL(readyRead()));
- }
-
- qint64 readData(char* data, qint64 len)
- {
- return m_audioBuffer->readBytes(data, len);
- }
-
- qint64 writeData(const char* data, qint64 len)
- {
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- return 0;
- }
-
- bool isSequential() const
- {
- return true;
- }
-
-private:
- QAudioInputBuffer* m_audioBuffer;
-};
-
-}
-
-
-QAudioInputPrivate::QAudioInputPrivate(const QByteArray& device)
-{
- QDataStream ds(device);
- quint32 did, mode;
-
- ds >> did >> mode;
-
- if (QAudio::Mode(mode) == QAudio::AudioOutput)
- errorCode = QAudio::OpenError;
- else {
- audioDeviceInfo = new QAudioDeviceInfoInternal(device, QAudio::AudioInput);
- isOpen = false;
- audioDeviceId = AudioDeviceID(did);
- audioUnit = 0;
- startTime = 0;
- totalFrames = 0;
- audioBuffer = 0;
- internalBufferSize = QtMultimediaInternal::default_buffer_size;
- clockFrequency = AudioGetHostClockFrequency() / 1000;
- errorCode = QAudio::NoError;
- stateCode = QAudio::StoppedState;
-
- intervalTimer = new QTimer(this);
- intervalTimer->setInterval(1000);
- connect(intervalTimer, SIGNAL(timeout()), SIGNAL(notify()));
- }
-}
-
-QAudioInputPrivate::~QAudioInputPrivate()
-{
- close();
- delete audioDeviceInfo;
-}
-
-bool QAudioInputPrivate::open()
-{
- UInt32 size = 0;
-
- if (isOpen)
- return true;
-
- ComponentDescription cd;
- cd.componentType = kAudioUnitType_Output;
- cd.componentSubType = kAudioUnitSubType_HALOutput;
- cd.componentManufacturer = kAudioUnitManufacturer_Apple;
- cd.componentFlags = 0;
- cd.componentFlagsMask = 0;
-
- // Open
- Component cp = FindNextComponent(NULL, &cd);
- if (cp == 0) {
- qWarning() << "QAudioInput: Failed to find HAL Output component";
- return false;
- }
-
- if (OpenAComponent(cp, &audioUnit) != noErr) {
- qWarning() << "QAudioInput: Unable to Open Output Component";
- return false;
- }
-
- // Set mode
- // switch to input mode
- UInt32 enable = 1;
- if (AudioUnitSetProperty(audioUnit,
- kAudioOutputUnitProperty_EnableIO,
- kAudioUnitScope_Input,
- 1,
- &enable,
- sizeof(enable)) != noErr) {
- qWarning() << "QAudioInput: Unable to switch to input mode (Enable Input)";
- return false;
- }
-
- enable = 0;
- if (AudioUnitSetProperty(audioUnit,
- kAudioOutputUnitProperty_EnableIO,
- kAudioUnitScope_Output,
- 0,
- &enable,
- sizeof(enable)) != noErr) {
- qWarning() << "QAudioInput: Unable to switch to input mode (Disable output)";
- return false;
- }
-
- // register callback
- AURenderCallbackStruct cb;
- cb.inputProc = inputCallback;
- cb.inputProcRefCon = this;
-
- if (AudioUnitSetProperty(audioUnit,
- kAudioOutputUnitProperty_SetInputCallback,
- kAudioUnitScope_Global,
- 0,
- &cb,
- sizeof(cb)) != noErr) {
- qWarning() << "QAudioInput: Failed to set AudioUnit callback";
- return false;
- }
-
- // Set Audio Device
- if (AudioUnitSetProperty(audioUnit,
- kAudioOutputUnitProperty_CurrentDevice,
- kAudioUnitScope_Global,
- 0,
- &audioDeviceId,
- sizeof(audioDeviceId)) != noErr) {
- qWarning() << "QAudioInput: Unable to use configured device";
- return false;
- }
-
- // Set format
- // Wanted
- streamFormat = toAudioStreamBasicDescription(audioFormat);
-
- // Required on unit
- if (audioFormat == audioDeviceInfo->preferredFormat()) {
- deviceFormat = streamFormat;
- AudioUnitSetProperty(audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output,
- 1,
- &deviceFormat,
- sizeof(deviceFormat));
- }
- else {
- size = sizeof(deviceFormat);
- if (AudioUnitGetProperty(audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input,
- 1,
- &deviceFormat,
- &size) != noErr) {
- qWarning() << "QAudioInput: Unable to retrieve device format";
- return false;
- }
-
- if (AudioUnitSetProperty(audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output,
- 1,
- &deviceFormat,
- sizeof(deviceFormat)) != noErr) {
- qWarning() << "QAudioInput: Unable to set device format";
- return false;
- }
- }
-
- // Setup buffers
- UInt32 numberOfFrames;
- size = sizeof(UInt32);
- if (AudioUnitGetProperty(audioUnit,
- kAudioDevicePropertyBufferFrameSize,
- kAudioUnitScope_Global,
- 0,
- &numberOfFrames,
- &size) != noErr) {
- qWarning() << "QAudioInput: Failed to get audio period size";
- return false;
- }
-
- // Allocate buffer
- periodSizeBytes = numberOfFrames * streamFormat.mBytesPerFrame;
-
- if (internalBufferSize < periodSizeBytes * 2)
- internalBufferSize = periodSizeBytes * 2;
- else
- internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame;
-
- audioBuffer = new QtMultimediaInternal::QAudioInputBuffer(internalBufferSize,
- periodSizeBytes,
- deviceFormat,
- streamFormat,
- this);
-
- audioIO = new QtMultimediaInternal::MacInputDevice(audioBuffer, this);
-
- // Init
- if (AudioUnitInitialize(audioUnit) != noErr) {
- qWarning() << "QAudioInput: Failed to initialize AudioUnit";
- return false;
- }
-
- isOpen = true;
-
- return isOpen;
-}
-
-void QAudioInputPrivate::close()
-{
- if (audioUnit != 0) {
- AudioOutputUnitStop(audioUnit);
- AudioUnitUninitialize(audioUnit);
- CloseComponent(audioUnit);
- }
-
- delete audioBuffer;
-}
-
-QAudioFormat QAudioInputPrivate::format() const
-{
- return audioFormat;
-}
-
-void QAudioInputPrivate::setFormat(const QAudioFormat& fmt)
-{
- if (stateCode == QAudio::StoppedState)
- audioFormat = fmt;
-}
-
-void QAudioInputPrivate::start(QIODevice* device)
-{
- QIODevice* op = device;
-
- if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) {
- stateCode = QAudio::StoppedState;
- errorCode = QAudio::OpenError;
- return;
- }
-
- reset();
- audioBuffer->reset();
- audioBuffer->setFlushDevice(op);
-
- if (op == 0)
- op = audioIO;
-
- // Start
- startTime = AudioGetCurrentHostTime();
- totalFrames = 0;
-
- audioThreadStart();
-
- stateCode = QAudio::ActiveState;
- errorCode = QAudio::NoError;
- emit stateChanged(stateCode);
-}
-
-QIODevice* QAudioInputPrivate::start()
-{
- QIODevice* op = 0;
-
- if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) {
- stateCode = QAudio::StoppedState;
- errorCode = QAudio::OpenError;
- return audioIO;
- }
-
- reset();
- audioBuffer->reset();
- audioBuffer->setFlushDevice(op);
-
- if (op == 0)
- op = audioIO;
-
- // Start
- startTime = AudioGetCurrentHostTime();
- totalFrames = 0;
-
- audioThreadStart();
-
- stateCode = QAudio::ActiveState;
- errorCode = QAudio::NoError;
- emit stateChanged(stateCode);
-
- return op;
-}
-
-void QAudioInputPrivate::stop()
-{
- QMutexLocker lock(&mutex);
- if (stateCode != QAudio::StoppedState) {
- audioThreadStop();
- audioBuffer->flush(true);
-
- errorCode = QAudio::NoError;
- stateCode = QAudio::StoppedState;
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
- }
-}
-
-void QAudioInputPrivate::reset()
-{
- QMutexLocker lock(&mutex);
- if (stateCode != QAudio::StoppedState) {
- audioThreadStop();
-
- errorCode = QAudio::NoError;
- stateCode = QAudio::StoppedState;
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
- }
-}
-
-void QAudioInputPrivate::suspend()
-{
- QMutexLocker lock(&mutex);
- if (stateCode == QAudio::ActiveState || stateCode == QAudio::IdleState) {
- audioThreadStop();
-
- errorCode = QAudio::NoError;
- stateCode = QAudio::SuspendedState;
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
- }
-}
-
-void QAudioInputPrivate::resume()
-{
- QMutexLocker lock(&mutex);
- if (stateCode == QAudio::SuspendedState) {
- audioThreadStart();
-
- errorCode = QAudio::NoError;
- stateCode = QAudio::ActiveState;
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
- }
-}
-
-int QAudioInputPrivate::bytesReady() const
-{
- return audioBuffer->used();
-}
-
-int QAudioInputPrivate::periodSize() const
-{
- return periodSizeBytes;
-}
-
-void QAudioInputPrivate::setBufferSize(int bs)
-{
- internalBufferSize = bs;
-}
-
-int QAudioInputPrivate::bufferSize() const
-{
- return internalBufferSize;
-}
-
-void QAudioInputPrivate::setNotifyInterval(int milliSeconds)
-{
- if (intervalTimer->interval() == milliSeconds)
- return;
-
- if (milliSeconds <= 0)
- milliSeconds = 0;
-
- intervalTimer->setInterval(milliSeconds);
-}
-
-int QAudioInputPrivate::notifyInterval() const
-{
- return intervalTimer->interval();
-}
-
-qint64 QAudioInputPrivate::processedUSecs() const
-{
- return totalFrames * 1000000 / audioFormat.frequency();
-}
-
-qint64 QAudioInputPrivate::elapsedUSecs() const
-{
- if (stateCode == QAudio::StoppedState)
- return 0;
-
- return (AudioGetCurrentHostTime() - startTime) / (clockFrequency / 1000);
-}
-
-QAudio::Error QAudioInputPrivate::error() const
-{
- return errorCode;
-}
-
-QAudio::State QAudioInputPrivate::state() const
-{
- return stateCode;
-}
-
-void QAudioInputPrivate::audioThreadStop()
-{
- stopTimers();
- if (audioThreadState.testAndSetAcquire(Running, Stopped))
- threadFinished.wait(&mutex);
-}
-
-void QAudioInputPrivate::audioThreadStart()
-{
- startTimers();
- audioThreadState = Running;
- AudioOutputUnitStart(audioUnit);
-}
-
-void QAudioInputPrivate::audioDeviceStop()
-{
- AudioOutputUnitStop(audioUnit);
- audioThreadState = Stopped;
- threadFinished.wakeOne();
-}
-
-void QAudioInputPrivate::audioDeviceFull()
-{
- QMutexLocker lock(&mutex);
- if (stateCode == QAudio::ActiveState) {
- audioDeviceStop();
-
- errorCode = QAudio::UnderrunError;
- stateCode = QAudio::IdleState;
- QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
- }
-}
-
-void QAudioInputPrivate::audioDeviceError()
-{
- QMutexLocker lock(&mutex);
- if (stateCode == QAudio::ActiveState) {
- audioDeviceStop();
-
- errorCode = QAudio::IOError;
- stateCode = QAudio::StoppedState;
- QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
- }
-}
-
-void QAudioInputPrivate::startTimers()
-{
- audioBuffer->startFlushTimer();
- if (intervalTimer->interval() > 0)
- intervalTimer->start();
-}
-
-void QAudioInputPrivate::stopTimers()
-{
- audioBuffer->stopFlushTimer();
- intervalTimer->stop();
-}
-
-void QAudioInputPrivate::deviceStopped()
-{
- stopTimers();
- emit stateChanged(stateCode);
-}
-
-// Input callback
-OSStatus QAudioInputPrivate::inputCallback(void* inRefCon,
- AudioUnitRenderActionFlags* ioActionFlags,
- const AudioTimeStamp* inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList* ioData)
-{
- Q_UNUSED(ioData);
-
- QAudioInputPrivate* d = static_cast<QAudioInputPrivate*>(inRefCon);
-
- const int threadState = d->audioThreadState.fetchAndAddAcquire(0);
- if (threadState == Stopped)
- d->audioDeviceStop();
- else {
- qint64 framesWritten;
-
- framesWritten = d->audioBuffer->renderFromDevice(d->audioUnit,
- ioActionFlags,
- inTimeStamp,
- inBusNumber,
- inNumberFrames);
-
- if (framesWritten > 0)
- d->totalFrames += framesWritten;
- else if (framesWritten == 0)
- d->audioDeviceFull();
- else if (framesWritten < 0)
- d->audioDeviceError();
- }
-
- return noErr;
-}
-
-
-QT_END_NAMESPACE
-
-#include "qaudioinput_mac_p.moc"