/**************************************************************************** ** ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** 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 Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/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 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef IOSAUDIOOUTPUT_H #define IOSAUDIOOUTPUT_H #include #if defined(Q_OS_OSX) # include #endif #include #include #include #include #include QT_BEGIN_NAMESPACE class CoreAudioOutputBuffer; class QTimer; class CoreAudioDeviceInfo; class CoreAudioRingBuffer; class CoreAudioOutputBuffer : public QObject { Q_OBJECT public: CoreAudioOutputBuffer(int bufferSize, int maxPeriodSize, QAudioFormat const& audioFormat); ~CoreAudioOutputBuffer(); qint64 readFrames(char *data, qint64 maxFrames); qint64 writeBytes(const char *data, qint64 maxSize); int available() const; void reset(); void setPrefetchDevice(QIODevice *device); void startFillTimer(); void stopFillTimer(); signals: void readyRead(); private slots: void fillBuffer(); private: bool m_deviceError; int m_maxPeriodSize; int m_bytesPerFrame; int m_periodTime; QIODevice *m_device; QTimer *m_fillTimer; CoreAudioRingBuffer *m_buffer; }; class CoreAudioOutputDevice : public QIODevice { public: CoreAudioOutputDevice(CoreAudioOutputBuffer *audioBuffer, QObject *parent); qint64 readData(char *data, qint64 len); qint64 writeData(const char *data, qint64 len); bool isSequential() const { return true; } private: CoreAudioOutputBuffer *m_audioBuffer; }; class CoreAudioOutput : public QAbstractAudioOutput { Q_OBJECT public: CoreAudioOutput(const QByteArray &device); ~CoreAudioOutput(); void start(QIODevice *device); QIODevice *start(); void stop(); void reset(); void suspend(); void resume(); int bytesFree() const; int periodSize() const; void setBufferSize(int value); int bufferSize() const; void setNotifyInterval(int milliSeconds); int notifyInterval() const; qint64 processedUSecs() const; qint64 elapsedUSecs() const; QAudio::Error error() const; QAudio::State state() const; void setFormat(const QAudioFormat &format); QAudioFormat format() const; void setVolume(qreal volume); qreal volume() const; void setCategory(const QString &category); QString category() const; private slots: void deviceStopped(); void inputReady(); private: enum { Running, Draining, Stopped }; static OSStatus renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); bool open(); void close(); void audioThreadStart(); void audioThreadStop(); void audioThreadDrain(); void audioDeviceStop(); void audioDeviceIdle(); void audioDeviceError(); void startTimers(); void stopTimers(); QByteArray m_device; bool m_isOpen; int m_internalBufferSize; int m_periodSizeBytes; qint64 m_totalFrames; QAudioFormat m_audioFormat; QIODevice *m_audioIO; #if defined(Q_OS_OSX) AudioDeviceID m_audioDeviceId; #endif AudioUnit m_audioUnit; Float64 m_clockFrequency; UInt64 m_startTime; AudioStreamBasicDescription m_streamFormat; CoreAudioOutputBuffer *m_audioBuffer; QAtomicInt m_audioThreadState; QWaitCondition m_threadFinished; QMutex m_mutex; QTimer *m_intervalTimer; CoreAudioDeviceInfo *m_audioDeviceInfo; qreal m_cachedVolume; QAudio::Error m_errorCode; QAudio::State m_stateCode; }; QT_END_NAMESPACE #endif // IOSAUDIOOUTPUT_H