/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** 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 "qaudiobuffer.h"
#include "qaudiobuffer_p.h"

#include <QObject>
#include <QDebug>

QT_BEGIN_NAMESPACE


static void qRegisterAudioBufferMetaTypes()
{
    qRegisterMetaType<QAudioBuffer>();
}

Q_CONSTRUCTOR_FUNCTION(qRegisterAudioBufferMetaTypes)


class QAudioBufferPrivate : public QSharedData
{
public:
    QAudioBufferPrivate(QAbstractAudioBuffer *provider)
        : mProvider(provider)
        , mCount(1)
    {
    }

    ~QAudioBufferPrivate()
    {
        if (mProvider)
            mProvider->release();
    }

    void ref()
    {
        mCount.ref();
    }

    void deref()
    {
        if (!mCount.deref())
            delete this;
    }

    QAudioBufferPrivate *clone();

    static QAudioBufferPrivate *acquire(QAudioBufferPrivate *other)
    {
        if (!other)
            return nullptr;

        // Ref the other (if there are extant data() pointers, they will
        // also point here - it's a feature, not a bug, like QByteArray)
        other->ref();
        return other;
    }

    QAbstractAudioBuffer *mProvider;
    QAtomicInt mCount;
};

// Private class to go in .cpp file
class QMemoryAudioBufferProvider : public QAbstractAudioBuffer {
public:
    QMemoryAudioBufferProvider(const void *data, int frameCount, const QAudioFormat &format, qint64 startTime)
        : mStartTime(startTime)
        , mFrameCount(frameCount)
        , mFormat(format)
    {
        int numBytes = format.bytesForFrames(frameCount);
        if (numBytes > 0) {
            mBuffer = malloc(numBytes);
            if (!mBuffer) {
                // OOM, if that's likely
                mStartTime = -1;
                mFrameCount = 0;
                mFormat = QAudioFormat();
            } else {
                // Allocated, see if we have data to copy
                if (data) {
                    memcpy(mBuffer, data, numBytes);
                } else {
                    // We have to fill with the zero value..
                    switch (format.sampleType()) {
                        case QAudioFormat::SignedInt:
                            // Signed int means 0x80, 0x8000 is zero
                            // XXX this is not right for > 8 bits(0x8080 vs 0x8000)
                            memset(mBuffer, 0x80, numBytes);
                            break;
                        default:
                            memset(mBuffer, 0x0, numBytes);
                    }
                }
            }
        } else
            mBuffer = nullptr;
    }

    ~QMemoryAudioBufferProvider()
    {
        if (mBuffer)
            free(mBuffer);
    }

    void release() override {delete this;}
    QAudioFormat format() const override {return mFormat;}
    qint64 startTime() const override {return mStartTime;}
    int frameCount() const override {return mFrameCount;}

    void *constData() const override {return mBuffer;}

    void *writableData() override {return mBuffer;}
    QAbstractAudioBuffer *clone() const override
    {
        return new QMemoryAudioBufferProvider(mBuffer, mFrameCount, mFormat, mStartTime);
    }

    void *mBuffer;
    qint64 mStartTime;
    int mFrameCount;
    QAudioFormat mFormat;
};

QAudioBufferPrivate *QAudioBufferPrivate::clone()
{
    // We want to create a single bufferprivate with a
    // single qaab
    // This should only be called when the count is > 1
    Q_ASSERT(mCount.loadRelaxed() > 1);

    if (mProvider) {
        QAbstractAudioBuffer *abuf = mProvider->clone();

        if (!abuf) {
            abuf = new QMemoryAudioBufferProvider(mProvider->constData(), mProvider->frameCount(), mProvider->format(), mProvider->startTime());
        }

        if (abuf) {
            return new QAudioBufferPrivate(abuf);
        }
    }

    return nullptr;
}

/*!
    \class QAbstractAudioBuffer
    \internal
*/

/*!
    \class QAudioBuffer
    \inmodule QtMultimedia
    \ingroup multimedia
    \ingroup multimedia_audio
    \brief The QAudioBuffer class represents a collection of audio samples with a specific format and sample rate.
*/
// ^ Mostly useful with probe or decoder

/*!
    Create a new, empty, invalid buffer.
 */
QAudioBuffer::QAudioBuffer()
    : d(nullptr)
{
}

/*!
    \internal
    Create a new audio buffer from the supplied \a provider.  This
    constructor is typically only used when handling certain hardware
    or media framework specific buffers, and generally isn't useful
    in application code.
 */
QAudioBuffer::QAudioBuffer(QAbstractAudioBuffer *provider)
    : d(new QAudioBufferPrivate(provider))
{
}
/*!
    Creates a new audio buffer from \a other.  Generally
    this will have copy-on-write semantics - a copy will
    only be made when it has to be.
 */
QAudioBuffer::QAudioBuffer(const QAudioBuffer &other)
{
    d = QAudioBufferPrivate::acquire(other.d);
}

/*!
    Creates a new audio buffer from the supplied \a data, in the
    given \a format.  The format will determine how the number
    and sizes of the samples are interpreted from the \a data.

    If the supplied \a data is not an integer multiple of the
    calculated frame size, the excess data will not be used.

    This audio buffer will copy the contents of \a data.

    \a startTime (in microseconds) indicates when this buffer
    starts in the stream.
    If this buffer is not part of a stream, set it to -1.
 */
QAudioBuffer::QAudioBuffer(const QByteArray &data, const QAudioFormat &format, qint64 startTime)
{
    if (format.isValid()) {
        int frameCount = format.framesForBytes(data.size());
        d = new QAudioBufferPrivate(new QMemoryAudioBufferProvider(data.constData(), frameCount, format, startTime));
    } else
        d = nullptr;
}

/*!
    Creates a new audio buffer with space for \a numFrames frames of
    the given \a format.  The individual samples will be initialized
    to the default for the format.

    \a startTime (in microseconds) indicates when this buffer
    starts in the stream.
    If this buffer is not part of a stream, set it to -1.
 */
QAudioBuffer::QAudioBuffer(int numFrames, const QAudioFormat &format, qint64 startTime)
{
    if (format.isValid())
        d = new QAudioBufferPrivate(new QMemoryAudioBufferProvider(nullptr, numFrames, format, startTime));
    else
        d = nullptr;
}

/*!
    Assigns the \a other buffer to this.
 */
QAudioBuffer &QAudioBuffer::operator =(const QAudioBuffer &other)
{
    if (this->d != other.d) {
        if (d)
            d->deref();
        d = QAudioBufferPrivate::acquire(other.d);
    }
    return *this;
}

/*!
    Destroys this audio buffer.
 */
QAudioBuffer::~QAudioBuffer()
{
    if (d)
        d->deref();
}

/*!
    Returns true if this is a valid buffer.  A valid buffer
    has more than zero frames in it and a valid format.
 */
bool QAudioBuffer::isValid() const
{
    if (!d || !d->mProvider)
        return false;
    return d->mProvider->format().isValid() && (d->mProvider->frameCount() > 0);
}

/*!
    Returns the \l {QAudioFormat}{format} of this buffer.

    Several properties of this format influence how
    the \l duration() or \l byteCount() are calculated
    from the \l frameCount().
 */
QAudioFormat QAudioBuffer::format() const
{
    if (!isValid())
        return QAudioFormat();
    return d->mProvider->format();
}

/*!
    Returns the number of complete audio frames in this buffer.

    An audio frame is an interleaved set of one sample per channel
    for the same instant in time.
*/
int QAudioBuffer::frameCount() const
{
    if (!isValid())
        return 0;
    return d->mProvider->frameCount();
}

/*!
    Returns the number of samples in this buffer.

    If the format of this buffer has multiple channels,
    then this count includes all channels.  This means
    that a stereo buffer with 1000 samples in total will
    have 500 left samples and 500 right samples (interleaved),
    and this function will return 1000.

    \sa frameCount()
*/
int QAudioBuffer::sampleCount() const
{
    if (!isValid())
        return 0;

    return frameCount() * format().channelCount();
}

/*!
    Returns the size of this buffer, in bytes.
 */
int QAudioBuffer::byteCount() const
{
    const QAudioFormat f(format());
    return format().bytesForFrames(frameCount());
}

/*!
    Returns the duration of audio in this buffer, in microseconds.

    This depends on the \l format(), and the \l frameCount().
*/
qint64 QAudioBuffer::duration() const
{
    return format().durationForFrames(frameCount());
}

/*!
    Returns the time in a stream that this buffer starts at (in microseconds).

    If this buffer is not part of a stream, this will return -1.
 */
qint64 QAudioBuffer::startTime() const
{
    if (!isValid())
        return -1;
    return d->mProvider->startTime();
}

/*!
    Returns a pointer to this buffer's data.  You can only read it.

    This method is preferred over the const version of \l data() to
    prevent unnecessary copying.

    There is also a templatized version of this constData() function that
    allows you to retrieve a specific type of read-only pointer to
    the data.  Note that there is no checking done on the format of
    the audio buffer - this is simply a convenience function.

    \code
    // With a 16bit sample buffer:
    const quint16 *data = buffer->constData<quint16>();
    \endcode

*/
const void* QAudioBuffer::constData() const
{
    if (!isValid())
        return nullptr;
    return d->mProvider->constData();
}

/*!
    Returns a pointer to this buffer's data.  You can only read it.

    You should use the \l constData() function rather than this
    to prevent accidental deep copying.

    There is also a templatized version of this data() function that
    allows you to retrieve a specific type of read-only pointer to
    the data.  Note that there is no checking done on the format of
    the audio buffer - this is simply a convenience function.

    \code
    // With a 16bit sample const buffer:
    const quint16 *data = buffer->data<quint16>();
    \endcode
*/
const void* QAudioBuffer::data() const
{
    if (!isValid())
        return nullptr;
    return d->mProvider->constData();
}


/*
    Template data/constData functions caused override problems with qdoc,
    so moved their docs into the non template versions.
*/

/*!
    Returns a pointer to this buffer's data.  You can modify the
    data through the returned pointer.

    Since QAudioBuffers can share the actual sample data, calling
    this function will result in a deep copy being made if there
    are any other buffers using the sample.  You should avoid calling
    this unless you really need to modify the data.

    This pointer will remain valid until the underlying storage is
    detached.  In particular, if you obtain a pointer, and then
    copy this audio buffer, changing data through this pointer may
    change both buffer instances.  Calling \l data() on either instance
    will again cause a deep copy to be made, which may invalidate
    the pointers returned from this function previously.

    There is also a templatized version of data() allows you to retrieve
    a specific type of pointer to the data.  Note that there is no
    checking done on the format of the audio buffer - this is
    simply a convenience function.

    \code
    // With a 16bit sample buffer:
    quint16 *data = buffer->data<quint16>(); // May cause deep copy
    \endcode
*/
void *QAudioBuffer::data()
{
    if (!isValid())
        return nullptr;

    if (d->mCount.loadRelaxed() != 1) {
        // Can't share a writable buffer
        // so we need to detach
        QAudioBufferPrivate *newd = d->clone();

        // This shouldn't happen
        if (!newd)
            return nullptr;

        d->deref();
        d = newd;
    }

    // We're (now) the only user of this qaab, so
    // see if it's writable directly
    void *buffer = d->mProvider->writableData();
    if (buffer) {
        return buffer;
    }

    // Wasn't writable, so turn it into a memory provider
    QAbstractAudioBuffer *memBuffer = new QMemoryAudioBufferProvider(constData(), frameCount(), format(), startTime());

    if (memBuffer) {
        d->mProvider->release();
        d->mCount.storeRelaxed(1);
        d->mProvider = memBuffer;

        return memBuffer->writableData();
    }

    return nullptr;
}

// Template helper classes worth documenting

/*!
    \class QAudioBuffer::StereoFrameDefault
    \internal

    Just a trait class for the default value.
*/

/*!
    \class QAudioBuffer::StereoFrame
    \brief The StereoFrame class provides a simple wrapper for a stereo audio frame.
    \inmodule QtMultimedia
    \ingroup multimedia
    \ingroup multimedia_audio

    This templatized structure lets you treat a block of individual samples as an
    interleaved stereo stream frame.  This is most useful when used with the templatized
    \l {QAudioBuffer::data()}{data()} functions of QAudioBuffer.  Generally the data
    is accessed as a pointer, so no copying should occur.

    There are some predefined instantiations of this template for working with common
    stereo sample depths in a convenient way.

    This frame structure has \e left and \e right members for accessing individual channel data.

    For example:
    \code
    // Assuming 'buffer' is an unsigned 16 bit stereo buffer..
    QAudioBuffer::S16U *frames = buffer->data<QAudioBuffer::S16U>();
    for (int i=0; i < buffer->frameCount(); i++) {
        qSwap(frames[i].left, frames[i].right);
    }
    \endcode

    \sa QAudioBuffer::S8U, QAudioBuffer::S8S, QAudioBuffer::S16S, QAudioBuffer::S16U, QAudioBuffer::S32F
*/

/*!
    \fn template <typename T> QAudioBuffer::StereoFrame<T>::StereoFrame()

    Constructs a new frame with the "silent" value for this
    sample format (0 for signed formats and floats, 0x8* for unsigned formats).
*/

/*!
    \fn template <typename T> QAudioBuffer::StereoFrame<T>::StereoFrame(T leftSample, T rightSample)

    Constructs a new frame with the supplied \a leftSample and \a rightSample values.
*/

/*!
    \fn template <typename T> QAudioBuffer::StereoFrame<T>::operator=(const StereoFrame &other)

    Assigns \a other to this frame.
 */


/*!
    \fn template <typename T> QAudioBuffer::StereoFrame<T>::average() const

    Returns the arithmetic average of the left and right samples.
 */

/*! \fn template <typename T> QAudioBuffer::StereoFrame<T>::clear()

    Sets the values of this frame to the "silent" value.
*/

/*!
    \variable QAudioBuffer::StereoFrame::left
    \brief the left sample
*/

/*!
    \variable QAudioBuffer::StereoFrame::right
    \brief the right sample
*/

/*!
    \typedef QAudioBuffer::S8U

    This is a predefined specialization for an unsigned stereo 8 bit sample.  Each
    channel is an \e {unsigned char}.
*/
/*!
    \typedef QAudioBuffer::S8S

    This is a predefined specialization for a signed stereo 8 bit sample.  Each
    channel is a \e {signed char}.
*/
/*!
    \typedef QAudioBuffer::S16U

    This is a predefined specialization for an unsigned stereo 16 bit sample.  Each
    channel is an \e {unsigned short}.
*/
/*!
    \typedef QAudioBuffer::S16S

    This is a predefined specialization for a signed stereo 16 bit sample.  Each
    channel is a \e {signed short}.
*/
/*!
    \typedef QAudioBuffer::S32F

    This is a predefined specialization for an 32 bit float sample.  Each
    channel is a \e float.
*/

QT_END_NAMESPACE
