/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "coreaudiooutput.h"
#include "coreaudiosessionmanager.h"
#include "coreaudiodeviceinfo.h"
#include "coreaudioutils.h"

#include <QtCore/QDataStream>
#include <QtCore/QTimer>
#include <QtCore/QDebug>

#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#if defined(Q_OS_OSX)
# include <AudioUnit/AudioComponent.h>
#endif

#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
# include <QtMultimedia/private/qaudiohelpers_p.h>
#endif

QT_BEGIN_NAMESPACE

static const int DEFAULT_BUFFER_SIZE = 8 * 1024;

CoreAudioOutputBuffer::CoreAudioOutputBuffer(int bufferSize, int maxPeriodSize, const QAudioFormat &audioFormat)
    : m_deviceError(false)
    , m_maxPeriodSize(maxPeriodSize)
    , m_device(0)
{
    m_buffer = new CoreAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize)));
    m_bytesPerFrame = (audioFormat.sampleSize() / 8) * audioFormat.channelCount();
    m_periodTime = m_maxPeriodSize / m_bytesPerFrame * 1000 / audioFormat.sampleRate();

    m_fillTimer = new QTimer(this);
    connect(m_fillTimer, SIGNAL(timeout()), SLOT(fillBuffer()));
}

CoreAudioOutputBuffer::~CoreAudioOutputBuffer()
{
    delete m_buffer;
}

qint64 CoreAudioOutputBuffer::readFrames(char *data, qint64 maxFrames)
{
    bool    wecan = true;
    qint64  framesRead = 0;

    while (wecan && framesRead < maxFrames) {
        CoreAudioRingBuffer::Region region = m_buffer->acquireReadRegion((maxFrames - framesRead) * m_bytesPerFrame);

        if (region.second > 0) {
            // Ensure that we only read whole frames.
            region.second -= region.second % m_bytesPerFrame;

            if (region.second > 0) {
                memcpy(data + (framesRead * m_bytesPerFrame), region.first, region.second);
                framesRead += region.second / m_bytesPerFrame;
            } else
                wecan = false; // If there is only a partial frame left we should exit.
        }
        else
            wecan = false;

        m_buffer->releaseReadRegion(region);
    }

    if (framesRead == 0 && m_deviceError)
        framesRead = -1;

    return framesRead;
}

qint64 CoreAudioOutputBuffer::writeBytes(const char *data, qint64 maxSize)
{
    bool    wecan = true;
    qint64  bytesWritten = 0;

    maxSize -= maxSize % m_bytesPerFrame;
    while (wecan && bytesWritten < maxSize) {
        CoreAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(maxSize - bytesWritten);

        if (region.second > 0) {
            memcpy(region.first, data + bytesWritten, region.second);
            bytesWritten += region.second;
        }
        else
            wecan = false;

        m_buffer->releaseWriteRegion(region);
    }

    if (bytesWritten > 0)
        emit readyRead();

    return bytesWritten;
}

int CoreAudioOutputBuffer::available() const
{
    return m_buffer->free();
}

void CoreAudioOutputBuffer::reset()
{
    m_buffer->reset();
    m_device = 0;
    m_deviceError = false;
}

void CoreAudioOutputBuffer::setPrefetchDevice(QIODevice *device)
{
    if (m_device != device) {
        m_device = device;
        if (m_device != 0)
            fillBuffer();
    }
}

void CoreAudioOutputBuffer::startFillTimer()
{
    if (m_device != 0)
        m_fillTimer->start(m_buffer->size() / 2 / m_maxPeriodSize * m_periodTime);
}

void CoreAudioOutputBuffer::stopFillTimer()
{
    m_fillTimer->stop();
}

void CoreAudioOutputBuffer::fillBuffer()
{
    const int free = m_buffer->free();
    const int writeSize = free - (free % m_maxPeriodSize);

    if (writeSize > 0) {
        bool    wecan = true;
        int     filled = 0;

        while (!m_deviceError && wecan && filled < writeSize) {
            CoreAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(writeSize - filled);

            if (region.second > 0) {
                region.second = m_device->read(region.first, region.second);
                if (region.second > 0)
                    filled += region.second;
                else if (region.second == 0)
                    wecan = false;
                else if (region.second < 0) {
                    m_fillTimer->stop();
                    region.second = 0;
                    m_deviceError = true;
                }
            }
            else
                wecan = false;

            m_buffer->releaseWriteRegion(region);
        }

        if (filled > 0)
            emit readyRead();
    }
}

CoreAudioOutputDevice::CoreAudioOutputDevice(CoreAudioOutputBuffer *audioBuffer, QObject *parent)
    : QIODevice(parent)
    , m_audioBuffer(audioBuffer)
{
    open(QIODevice::WriteOnly | QIODevice::Unbuffered);
}

qint64 CoreAudioOutputDevice::readData(char *data, qint64 len)
{
    Q_UNUSED(data);
    Q_UNUSED(len);

    return 0;
}

qint64 CoreAudioOutputDevice::writeData(const char *data, qint64 len)
{
    return m_audioBuffer->writeBytes(data, len);
}

CoreAudioOutput::CoreAudioOutput(const QByteArray &device)
    : m_isOpen(false)
    , m_internalBufferSize(DEFAULT_BUFFER_SIZE)
    , m_totalFrames(0)
    , m_audioIO(0)
    , m_audioUnit(0)
    , m_startTime(0)
    , m_audioBuffer(0)
    , m_cachedVolume(1.0)
    , m_volume(1.0)
    , m_pullMode(false)
    , m_errorCode(QAudio::NoError)
    , m_stateCode(QAudio::StoppedState)
{
#if defined(Q_OS_OSX)
    quint32 deviceID;
    QDataStream dataStream(device);
    dataStream >> deviceID >> m_device;
    m_audioDeviceId = AudioDeviceID(deviceID);
#else //iOS
    m_device = device;
#endif

    m_clockFrequency = CoreAudioUtils::frequency() / 1000;
    m_audioDeviceInfo = new CoreAudioDeviceInfo(device, QAudio::AudioOutput);
    m_audioThreadState.store(Stopped);

    m_intervalTimer = new QTimer(this);
    m_intervalTimer->setInterval(1000);
    connect(m_intervalTimer, SIGNAL(timeout()), this, SIGNAL(notify()));
}

CoreAudioOutput::~CoreAudioOutput()
{
    close();
    delete m_audioDeviceInfo;
}

void CoreAudioOutput::start(QIODevice *device)
{
    QIODevice* op = device;

    if (!m_audioDeviceInfo->isFormatSupported(m_audioFormat) || !open()) {
        m_stateCode = QAudio::StoppedState;
        m_errorCode = QAudio::OpenError;
        return;
    }

    reset();
    m_audioBuffer->reset();
    m_audioBuffer->setPrefetchDevice(op);

    if (op == 0) {
        op = m_audioIO;
        m_stateCode = QAudio::IdleState;
    }
    else
        m_stateCode = QAudio::ActiveState;

    // Start
    m_pullMode = true;
    m_errorCode = QAudio::NoError;
    m_totalFrames = 0;
    m_startTime = CoreAudioUtils::currentTime();

    if (m_stateCode == QAudio::ActiveState)
        audioThreadStart();

    emit stateChanged(m_stateCode);
}

QIODevice *CoreAudioOutput::start()
{
    if (!m_audioDeviceInfo->isFormatSupported(m_audioFormat) || !open()) {
        m_stateCode = QAudio::StoppedState;
        m_errorCode = QAudio::OpenError;
        return m_audioIO;
    }

    reset();
    m_audioBuffer->reset();
    m_audioBuffer->setPrefetchDevice(0);

    m_stateCode = QAudio::IdleState;

    // Start
    m_pullMode = false;
    m_errorCode = QAudio::NoError;
    m_totalFrames = 0;
    m_startTime = CoreAudioUtils::currentTime();

    emit stateChanged(m_stateCode);

    return m_audioIO;
}

void CoreAudioOutput::stop()
{
    QMutexLocker lock(&m_mutex);
    if (m_stateCode != QAudio::StoppedState) {
        audioThreadDrain();

        m_stateCode = QAudio::StoppedState;
        m_errorCode = QAudio::NoError;
        emit stateChanged(m_stateCode);
    }
}

void CoreAudioOutput::reset()
{
    QMutexLocker lock(&m_mutex);
    if (m_stateCode != QAudio::StoppedState) {
        audioThreadStop();

        m_stateCode = QAudio::StoppedState;
        m_errorCode = QAudio::NoError;
        emit stateChanged(m_stateCode);
    }
}

void CoreAudioOutput::suspend()
{
    QMutexLocker lock(&m_mutex);
    if (m_stateCode == QAudio::ActiveState || m_stateCode == QAudio::IdleState) {
        audioThreadStop();

        m_stateCode = QAudio::SuspendedState;
        m_errorCode = QAudio::NoError;
        emit stateChanged(m_stateCode);
    }
}

void CoreAudioOutput::resume()
{
    QMutexLocker lock(&m_mutex);
    if (m_stateCode == QAudio::SuspendedState) {
        audioThreadStart();

        m_stateCode = m_pullMode ? QAudio::ActiveState : QAudio::IdleState;
        m_errorCode = QAudio::NoError;
        emit stateChanged(m_stateCode);
    }
}

int CoreAudioOutput::bytesFree() const
{
    return m_audioBuffer->available();
}

int CoreAudioOutput::periodSize() const
{
    return m_periodSizeBytes;
}

void CoreAudioOutput::setBufferSize(int value)
{
    if (m_stateCode == QAudio::StoppedState)
        m_internalBufferSize = value;
}

int CoreAudioOutput::bufferSize() const
{
    return m_internalBufferSize;
}

void CoreAudioOutput::setNotifyInterval(int milliSeconds)
{
    if (m_intervalTimer->interval() == milliSeconds)
        return;

    if (milliSeconds <= 0)
        milliSeconds = 0;

    m_intervalTimer->setInterval(milliSeconds);
}

int CoreAudioOutput::notifyInterval() const
{
    return m_intervalTimer->interval();
}

qint64 CoreAudioOutput::processedUSecs() const
{
    return m_totalFrames * 1000000 / m_audioFormat.sampleRate();
}

qint64 CoreAudioOutput::elapsedUSecs() const
{
    if (m_stateCode == QAudio::StoppedState)
        return 0;

    return (CoreAudioUtils::currentTime() - m_startTime) / (m_clockFrequency / 1000);
}

QAudio::Error CoreAudioOutput::error() const
{
    return m_errorCode;
}

QAudio::State CoreAudioOutput::state() const
{
    return m_stateCode;
}

void CoreAudioOutput::setFormat(const QAudioFormat &format)
{
    if (m_stateCode == QAudio::StoppedState)
        m_audioFormat = format;
}

QAudioFormat CoreAudioOutput::format() const
{
    return m_audioFormat;
}

void CoreAudioOutput::setVolume(qreal volume)
{
    m_cachedVolume = qBound(qreal(0.0), volume, qreal(1.0));
    if (!m_isOpen)
        return;

#if defined(Q_OS_OSX)
    //on OS X the volume can be set directly on the AudioUnit
    if (AudioUnitSetParameter(m_audioUnit,
                              kHALOutputParam_Volume,
                              kAudioUnitScope_Global,
                              0 /* bus */,
                              m_cachedVolume,
                              0) == noErr)
        m_volume = m_cachedVolume;
#endif
}

qreal CoreAudioOutput::volume() const
{
    return m_cachedVolume;
}

void CoreAudioOutput::setCategory(const QString &category)
{
    Q_UNUSED(category);
}

QString CoreAudioOutput::category() const
{
    return QString();
}

void CoreAudioOutput::deviceStopped()
{
    m_intervalTimer->stop();
    emit stateChanged(m_stateCode);
}

void CoreAudioOutput::inputReady()
{
    QMutexLocker lock(&m_mutex);
    if (m_stateCode == QAudio::IdleState) {
        audioThreadStart();

        m_stateCode = QAudio::ActiveState;
        m_errorCode = QAudio::NoError;

        emit stateChanged(m_stateCode);
    }
}

OSStatus CoreAudioOutput::renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
    Q_UNUSED(ioActionFlags)
    Q_UNUSED(inTimeStamp)
    Q_UNUSED(inBusNumber)
    Q_UNUSED(inNumberFrames)

    CoreAudioOutput* d = static_cast<CoreAudioOutput*>(inRefCon);

    const int threadState = d->m_audioThreadState.fetchAndAddAcquire(0);
    if (threadState == Stopped) {
        ioData->mBuffers[0].mDataByteSize = 0;
        d->audioDeviceStop();
    }
    else {
        const UInt32 bytesPerFrame = d->m_streamFormat.mBytesPerFrame;
        qint64 framesRead;

        framesRead = d->m_audioBuffer->readFrames((char*)ioData->mBuffers[0].mData,
                                                 ioData->mBuffers[0].mDataByteSize / bytesPerFrame);

        if (framesRead > 0) {
            ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame;
            d->m_totalFrames += framesRead;

#if defined(Q_OS_MACOS)
            // If playback is already stopped.
            if (threadState != Running) {
                qreal oldVolume = d->m_cachedVolume;
                // Decrease volume smoothly.
                d->setVolume(d->m_volume / 2);
                d->m_cachedVolume = oldVolume;
            }
#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS)
            // on iOS we have to adjust the sound volume ourselves
            if (!qFuzzyCompare(d->m_cachedVolume, qreal(1.0f))) {
                QAudioHelperInternal::qMultiplySamples(d->m_cachedVolume,
                                                       d->m_audioFormat,
                                                       ioData->mBuffers[0].mData, /* input */
                                                       ioData->mBuffers[0].mData, /* output */
                                                       ioData->mBuffers[0].mDataByteSize);
            }
#endif

        }
        else {
            ioData->mBuffers[0].mDataByteSize = 0;
            if (framesRead == 0) {
                if (threadState == Draining)
                    d->audioDeviceStop();
                else
                    d->audioDeviceIdle();
            }
            else
                d->audioDeviceError();
        }
    }

    return noErr;
}

bool CoreAudioOutput::open()
{
#if defined(Q_OS_IOS)
    // Set default category to Ambient (implies MixWithOthers). This makes sure audio stops playing
    // if the screen is locked or if the Silent switch is toggled.
    CoreAudioSessionManager::instance().setCategory(CoreAudioSessionManager::Ambient, CoreAudioSessionManager::None);
    CoreAudioSessionManager::instance().setActive(true);
#endif

    if (m_errorCode != QAudio::NoError)
        return false;

    if (m_isOpen) {
        setVolume(m_cachedVolume);
        return true;
    }

    AudioComponentDescription componentDescription;
    componentDescription.componentType = kAudioUnitType_Output;
#if defined(Q_OS_OSX)
    componentDescription.componentSubType = kAudioUnitSubType_HALOutput;
#else
    componentDescription.componentSubType = kAudioUnitSubType_RemoteIO;
#endif
    componentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
    componentDescription.componentFlags = 0;
    componentDescription.componentFlagsMask = 0;

    AudioComponent component = AudioComponentFindNext(0, &componentDescription);
    if (component == 0) {
        qWarning() << "QAudioOutput: Failed to find Output component";
        return false;
    }

    if (AudioComponentInstanceNew(component, &m_audioUnit) != noErr) {
        qWarning() << "QAudioOutput: Unable to Open Output Component";
        return false;
    }

    // register callback
    AURenderCallbackStruct callback;
    callback.inputProc = renderCallback;
    callback.inputProcRefCon = this;

    if (AudioUnitSetProperty(m_audioUnit,
                             kAudioUnitProperty_SetRenderCallback,
                             kAudioUnitScope_Global,
                             0,
                             &callback,
                             sizeof(callback)) != noErr) {
        qWarning() << "QAudioOutput: Failed to set AudioUnit callback";
        return false;
    }

#if defined(Q_OS_OSX)
    //Set Audio Device
    if (AudioUnitSetProperty(m_audioUnit,
                             kAudioOutputUnitProperty_CurrentDevice,
                             kAudioUnitScope_Global,
                             0,
                             &m_audioDeviceId,
                             sizeof(m_audioDeviceId)) != noErr) {
        qWarning() << "QAudioOutput: Unable to use configured device";
        return false;
    }
#endif

    // Set stream format
    m_streamFormat = CoreAudioUtils::toAudioStreamBasicDescription(m_audioFormat);

    UInt32 size = sizeof(m_streamFormat);
    if (AudioUnitSetProperty(m_audioUnit,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Input,
                                0,
                                &m_streamFormat,
                                size) != noErr) {
        qWarning() << "QAudioOutput: Unable to Set Stream information";
        return false;
    }

    // Allocate buffer
    UInt32 numberOfFrames = 0;
#if defined(Q_OS_OSX)
    size = sizeof(UInt32);
    if (AudioUnitGetProperty(m_audioUnit,
                             kAudioDevicePropertyBufferFrameSize,
                             kAudioUnitScope_Global,
                             0,
                             &numberOfFrames,
                             &size) != noErr) {
        qWarning() << "QAudioInput: Failed to get audio period size";
        return false;
    }
#else //iOS
    Float32 bufferSize = CoreAudioSessionManager::instance().currentIOBufferDuration();
    bufferSize *= m_streamFormat.mSampleRate;
    numberOfFrames = bufferSize;
#endif

    m_periodSizeBytes = numberOfFrames * m_streamFormat.mBytesPerFrame;
    if (m_internalBufferSize < m_periodSizeBytes * 2)
        m_internalBufferSize = m_periodSizeBytes * 2;
    else
        m_internalBufferSize -= m_internalBufferSize % m_streamFormat.mBytesPerFrame;

    m_audioBuffer = new CoreAudioOutputBuffer(m_internalBufferSize, m_periodSizeBytes, m_audioFormat);
    connect(m_audioBuffer, SIGNAL(readyRead()), SLOT(inputReady())); //Pull

    m_audioIO = new CoreAudioOutputDevice(m_audioBuffer, this);

    //Init
    if (AudioUnitInitialize(m_audioUnit)) {
        qWarning() << "QAudioOutput: Failed to initialize AudioUnit";
        return false;
    }

    m_isOpen = true;

    setVolume(m_cachedVolume);

    return true;
}

void CoreAudioOutput::close()
{
    if (m_audioUnit != 0) {
        AudioOutputUnitStop(m_audioUnit);
        AudioUnitUninitialize(m_audioUnit);
        AudioComponentInstanceDispose(m_audioUnit);
    }

    delete m_audioBuffer;
}

void CoreAudioOutput::audioThreadStart()
{
    startTimers();
    m_audioThreadState.store(Running);
    AudioOutputUnitStart(m_audioUnit);
}

void CoreAudioOutput::audioThreadStop()
{
    stopTimers();
    if (m_audioThreadState.testAndSetAcquire(Running, Stopped))
        m_threadFinished.wait(&m_mutex, 500);
}

void CoreAudioOutput::audioThreadDrain()
{
    stopTimers();
    if (m_audioThreadState.testAndSetAcquire(Running, Draining))
        m_threadFinished.wait(&m_mutex, 500);
}

void CoreAudioOutput::audioDeviceStop()
{
    AudioOutputUnitStop(m_audioUnit);
    m_audioThreadState.store(Stopped);
    m_threadFinished.wakeOne();
}

void CoreAudioOutput::audioDeviceIdle()
{
    if (m_stateCode == QAudio::ActiveState) {
        QMutexLocker lock(&m_mutex);
        audioDeviceStop();

        m_errorCode = QAudio::UnderrunError;
        m_stateCode = QAudio::IdleState;
        QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
    }
}

void CoreAudioOutput::audioDeviceError()
{
    if (m_stateCode == QAudio::ActiveState) {
        QMutexLocker lock(&m_mutex);
        audioDeviceStop();

        m_errorCode = QAudio::IOError;
        m_stateCode = QAudio::StoppedState;
        QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
    }
}

void CoreAudioOutput::startTimers()
{
    m_audioBuffer->startFillTimer();
    if (m_intervalTimer->interval() > 0)
        m_intervalTimer->start();
}

void CoreAudioOutput::stopTimers()
{
    m_audioBuffer->stopFillTimer();
    m_intervalTimer->stop();
}

QT_END_NAMESPACE

#include "moc_coreaudiooutput.cpp"
