/****************************************************************************
**
** 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 "qopenslesengine.h"

#include "qopenslesaudioinput.h"
#include <qdebug.h>

#ifdef ANDROID
#include <SLES/OpenSLES_Android.h>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
#endif

#define MINIMUM_PERIOD_TIME_MS 5
#define DEFAULT_PERIOD_TIME_MS 50

#define CheckError(message) if (result != SL_RESULT_SUCCESS) { qWarning(message); return; }

Q_GLOBAL_STATIC(QOpenSLESEngine, openslesEngine);

QOpenSLESEngine::QOpenSLESEngine()
    : m_engineObject(0)
    , m_engine(0)
    , m_checkedInputFormats(false)
{
    SLresult result;

    result = slCreateEngine(&m_engineObject, 0, 0, 0, 0, 0);
    CheckError("Failed to create engine");

    result = (*m_engineObject)->Realize(m_engineObject, SL_BOOLEAN_FALSE);
    CheckError("Failed to realize engine");

    result = (*m_engineObject)->GetInterface(m_engineObject, SL_IID_ENGINE, &m_engine);
    CheckError("Failed to get engine interface");
}

QOpenSLESEngine::~QOpenSLESEngine()
{
    if (m_engineObject)
        (*m_engineObject)->Destroy(m_engineObject);
}

QOpenSLESEngine *QOpenSLESEngine::instance()
{
    return openslesEngine();
}

SLDataFormat_PCM QOpenSLESEngine::audioFormatToSLFormatPCM(const QAudioFormat &format)
{
    SLDataFormat_PCM format_pcm;
    format_pcm.formatType = SL_DATAFORMAT_PCM;
    format_pcm.numChannels = format.channelCount();
    format_pcm.samplesPerSec = format.sampleRate() * 1000;
    format_pcm.bitsPerSample = format.sampleSize();
    format_pcm.containerSize = format.sampleSize();
    format_pcm.channelMask = (format.channelCount() == 1 ?
                                  SL_SPEAKER_FRONT_CENTER :
                                  SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
    format_pcm.endianness = (format.byteOrder() == QAudioFormat::LittleEndian ?
                                 SL_BYTEORDER_LITTLEENDIAN :
                                 SL_BYTEORDER_BIGENDIAN);
    return format_pcm;

}

QByteArray QOpenSLESEngine::defaultDevice(QAudio::Mode mode) const
{
    const auto &devices = availableDevices(mode);
    return !devices.isEmpty() ? devices.first() : QByteArray();
}

QList<QByteArray> QOpenSLESEngine::availableDevices(QAudio::Mode mode) const
{
    QList<QByteArray> devices;
    if (mode == QAudio::AudioInput) {
#ifdef ANDROID
        devices << QT_ANDROID_PRESET_MIC
                << QT_ANDROID_PRESET_CAMCORDER
                << QT_ANDROID_PRESET_VOICE_RECOGNITION
                << QT_ANDROID_PRESET_VOICE_COMMUNICATION;
#else
        devices << "default";
#endif
    } else {
        devices << "default";
    }
    return devices;
}

QList<int> QOpenSLESEngine::supportedChannelCounts(QAudio::Mode mode) const
{
    if (mode == QAudio::AudioInput) {
        if (!m_checkedInputFormats)
            const_cast<QOpenSLESEngine *>(this)->checkSupportedInputFormats();
        return m_supportedInputChannelCounts;
    } else {
        return QList<int>() << 1 << 2;
    }
}

QList<int> QOpenSLESEngine::supportedSampleRates(QAudio::Mode mode) const
{
    if (mode == QAudio::AudioInput) {
        if (!m_checkedInputFormats)
            const_cast<QOpenSLESEngine *>(this)->checkSupportedInputFormats();
        return m_supportedInputSampleRates;
    } else {
        return QList<int>() << 8000 << 11025 << 12000 << 16000 << 22050
                            << 24000 << 32000 << 44100 << 48000;
    }
}

int QOpenSLESEngine::getOutputValue(QOpenSLESEngine::OutputValue type, int defaultValue)
{
#if defined(Q_OS_ANDROID)
    static int sampleRate = 0;
    static int framesPerBuffer = 0;
    static const int sdkVersion = QtAndroidPrivate::androidSdkVersion();

    if (sdkVersion < 17) // getProperty() was added in API level 17...
        return defaultValue;

    if (type == FramesPerBuffer && framesPerBuffer != 0)
        return framesPerBuffer;

    if (type == SampleRate && sampleRate != 0)
        return sampleRate;

    QJNIObjectPrivate ctx(QtAndroidPrivate::activity());
    if (!ctx.isValid())
        return defaultValue;


    QJNIObjectPrivate audioServiceString = ctx.getStaticObjectField("android/content/Context",
                                                                    "AUDIO_SERVICE",
                                                                    "Ljava/lang/String;");
    QJNIObjectPrivate am = ctx.callObjectMethod("getSystemService",
                                                "(Ljava/lang/String;)Ljava/lang/Object;",
                                                audioServiceString.object());
    if (!am.isValid())
        return defaultValue;

    QJNIObjectPrivate sampleRateField = QJNIObjectPrivate::getStaticObjectField("android/media/AudioManager",
                                                                                "PROPERTY_OUTPUT_SAMPLE_RATE",
                                                                                "Ljava/lang/String;");
    QJNIObjectPrivate framesPerBufferField = QJNIObjectPrivate::getStaticObjectField("android/media/AudioManager",
                                                                                     "PROPERTY_OUTPUT_FRAMES_PER_BUFFER",
                                                                                     "Ljava/lang/String;");

    QJNIObjectPrivate sampleRateString = am.callObjectMethod("getProperty",
                                                             "(Ljava/lang/String;)Ljava/lang/String;",
                                                             sampleRateField.object());
    QJNIObjectPrivate framesPerBufferString = am.callObjectMethod("getProperty",
                                                                  "(Ljava/lang/String;)Ljava/lang/String;",
                                                                  framesPerBufferField.object());

    if (!sampleRateString.isValid() || !framesPerBufferString.isValid())
        return defaultValue;

    framesPerBuffer = framesPerBufferString.toString().toInt();
    sampleRate = sampleRateString.toString().toInt();

    if (type == FramesPerBuffer)
        return framesPerBuffer;

    if (type == SampleRate)
        return sampleRate;

#endif // Q_OS_ANDROID

    return defaultValue;
}

int QOpenSLESEngine::getDefaultBufferSize(const QAudioFormat &format)
{
#if defined(Q_OS_ANDROID)
    if (!format.isValid())
        return 0;

    const int channelConfig = [&format]() -> int
    {
        if (format.channelCount() == 1)
            return 4; /* MONO */
        else if (format.channelCount() == 2)
            return 12; /* STEREO */
        else if (format.channelCount() > 2)
            return 1052; /* SURROUND */
        else
            return 1; /* DEFAULT */
    }();

    const int audioFormat = [&format]() -> int
    {
        if (format.sampleType() == QAudioFormat::Float && QtAndroidPrivate::androidSdkVersion() >= 21)
            return 4; /* PCM_FLOAT */
        else if (format.sampleSize() == 8)
            return 3; /* PCM_8BIT */
        else if (format.sampleSize() == 16)
            return 2; /* PCM_16BIT*/
        else
            return 1; /* DEFAULT */
    }();

    const int sampleRate = format.sampleRate();
    const int minBufferSize = QJNIObjectPrivate::callStaticMethod<jint>("android/media/AudioTrack",
                                                                        "getMinBufferSize",
                                                                        "(III)I",
                                                                        sampleRate,
                                                                        channelConfig,
                                                                        audioFormat);
    return minBufferSize > 0 ? minBufferSize : format.bytesForDuration(DEFAULT_PERIOD_TIME_MS);
#else
    return format.bytesForDuration(DEFAULT_PERIOD_TIME_MS);
#endif // Q_OS_ANDROID
}

int QOpenSLESEngine::getLowLatencyBufferSize(const QAudioFormat &format)
{
    return format.bytesForFrames(QOpenSLESEngine::getOutputValue(QOpenSLESEngine::FramesPerBuffer,
                                                                 format.framesForDuration(MINIMUM_PERIOD_TIME_MS)));
}

bool QOpenSLESEngine::supportsLowLatency()
{
#if defined(Q_OS_ANDROID)
    static int isSupported = -1;

    if (isSupported != -1)
        return (isSupported == 1);

    QJNIObjectPrivate ctx(QtAndroidPrivate::activity());
    if (!ctx.isValid())
        return false;

    QJNIObjectPrivate pm = ctx.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;");
    if (!pm.isValid())
        return false;

    QJNIObjectPrivate audioFeatureField = QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager",
                                                                                  "FEATURE_AUDIO_LOW_LATENCY",
                                                                                  "Ljava/lang/String;");
    if (!audioFeatureField.isValid())
        return false;

    isSupported = pm.callMethod<jboolean>("hasSystemFeature",
                                          "(Ljava/lang/String;)Z",
                                          audioFeatureField.object());
    return (isSupported == 1);
#else
    return true;
#endif // Q_OS_ANDROID
}

bool QOpenSLESEngine::printDebugInfo()
{
    return qEnvironmentVariableIsSet("QT_OPENSL_INFO");
}

void QOpenSLESEngine::checkSupportedInputFormats()
{
    m_supportedInputChannelCounts = QList<int>() << 1;
    m_supportedInputSampleRates.clear();

    SLDataFormat_PCM defaultFormat;
    defaultFormat.formatType = SL_DATAFORMAT_PCM;
    defaultFormat.numChannels = 1;
    defaultFormat.samplesPerSec = SL_SAMPLINGRATE_44_1;
    defaultFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
    defaultFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
    defaultFormat.channelMask = SL_SPEAKER_FRONT_CENTER;
    defaultFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

    const SLuint32 rates[9] = { SL_SAMPLINGRATE_8,
                                SL_SAMPLINGRATE_11_025,
                                SL_SAMPLINGRATE_12,
                                SL_SAMPLINGRATE_16,
                                SL_SAMPLINGRATE_22_05,
                                SL_SAMPLINGRATE_24,
                                SL_SAMPLINGRATE_32,
                                SL_SAMPLINGRATE_44_1,
                                SL_SAMPLINGRATE_48 };


    // Test sampling rates
    for (int i = 0 ; i < 9; ++i) {
        SLDataFormat_PCM format = defaultFormat;
        format.samplesPerSec = rates[i];

        if (inputFormatIsSupported(format))
            m_supportedInputSampleRates.append(rates[i] / 1000);

    }

    // Test if stereo is supported
    {
        SLDataFormat_PCM format = defaultFormat;
        format.numChannels = 2;
        format.channelMask = 0;
        if (inputFormatIsSupported(format))
            m_supportedInputChannelCounts.append(2);
    }

    m_checkedInputFormats = true;
}

bool QOpenSLESEngine::inputFormatIsSupported(SLDataFormat_PCM format)
{
    SLresult result;
    SLObjectItf recorder = 0;
    SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
                                       SL_DEFAULTDEVICEID_AUDIOINPUT, NULL };
    SLDataSource audioSrc = { &loc_dev, NULL };

#ifdef ANDROID
    SLDataLocator_AndroidSimpleBufferQueue loc_bq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1 };
#else
    SLDataLocator_BufferQueue loc_bq = { SL_DATALOCATOR_BUFFERQUEUE, 1 };
#endif
    SLDataSink audioSnk = { &loc_bq, &format };

    result = (*m_engine)->CreateAudioRecorder(m_engine, &recorder, &audioSrc, &audioSnk, 0, 0, 0);
    if (result == SL_RESULT_SUCCESS)
        result = (*recorder)->Realize(recorder, false);

    if (result == SL_RESULT_SUCCESS) {
        (*recorder)->Destroy(recorder);
        return true;
    }

    return false;
}
