/* MidiFile.cpp
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "MidiFile"
#include "utils/Log.h"

#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <utils/threads.h>
#include <libsonivox/eas_reverb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <system/audio.h>

#include "MidiFile.h"

// ----------------------------------------------------------------------------

namespace android {

// ----------------------------------------------------------------------------

// The midi engine buffers are a bit small (128 frames), so we batch them up
static const int NUM_BUFFERS = 4;

// TODO: Determine appropriate return codes
static status_t ERROR_NOT_OPEN = -1;
static status_t ERROR_OPEN_FAILED = -2;
static status_t ERROR_EAS_FAILURE = -3;
static status_t ERROR_ALLOCATE_FAILED = -4;

static const S_EAS_LIB_CONFIG* pLibConfig = NULL;

MidiFile::MidiFile() :
    mEasData(NULL), mEasHandle(NULL), mAudioBuffer(NULL),
    mPlayTime(-1), mDuration(-1), mState(EAS_STATE_ERROR),
    mStreamType(AUDIO_STREAM_MUSIC), mLoop(false), mExit(false),
    mPaused(false), mRender(false), mTid(-1)
{
    ALOGV("constructor");

    mFileLocator.path = NULL;
    mFileLocator.fd = -1;
    mFileLocator.offset = 0;
    mFileLocator.length = 0;

    // get the library configuration and do sanity check
    if (pLibConfig == NULL)
        pLibConfig = EAS_Config();
    if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) {
        ALOGE("EAS library/header mismatch");
        goto Failed;
    }

    // initialize EAS library
    if (EAS_Init(&mEasData) != EAS_SUCCESS) {
        ALOGE("EAS_Init failed");
        goto Failed;
    }

    // select reverb preset and enable
    EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER);
    EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, EAS_FALSE);

    // create playback thread
    {
        Mutex::Autolock l(mMutex);
        mThread = new MidiFileThread(this);
        mThread->run("midithread", ANDROID_PRIORITY_AUDIO);
        mCondition.wait(mMutex);
        ALOGV("thread started");
    }

    // indicate success
    if (mTid > 0) {
        ALOGV(" render thread(%d) started", mTid);
        mState = EAS_STATE_READY;
    }

Failed:
    return;
}

status_t MidiFile::initCheck()
{
    if (mState == EAS_STATE_ERROR) return ERROR_EAS_FAILURE;
    return NO_ERROR;
}

MidiFile::~MidiFile() {
    ALOGV("MidiFile destructor");
    release();
}

status_t MidiFile::setDataSource(
        const sp<IMediaHTTPService> &httpService,
        const char* path,
        const KeyedVector<String8, String8> *) {
    ALOGV("MidiFile::setDataSource url=%s", path);
    Mutex::Autolock lock(mMutex);

    // file still open?
    if (mEasHandle) {
        reset_nosync();
    }

    // open file and set paused state
    mFileLocator.path = strdup(path);
    mFileLocator.fd = -1;
    mFileLocator.offset = 0;
    mFileLocator.length = 0;
    EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle);
    if (result == EAS_SUCCESS) {
        updateState();
    }

    if (result != EAS_SUCCESS) {
        ALOGE("EAS_OpenFile failed: [%d]", (int)result);
        mState = EAS_STATE_ERROR;
        return ERROR_OPEN_FAILED;
    }

    mState = EAS_STATE_OPEN;
    mPlayTime = 0;
    return NO_ERROR;
}

status_t MidiFile::setDataSource(int fd, int64_t offset, int64_t length)
{
    ALOGV("MidiFile::setDataSource fd=%d", fd);
    Mutex::Autolock lock(mMutex);

    // file still open?
    if (mEasHandle) {
        reset_nosync();
    }

    // open file and set paused state
    mFileLocator.fd = dup(fd);
    mFileLocator.offset = offset;
    mFileLocator.length = length;
    EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle);
    updateState();

    if (result != EAS_SUCCESS) {
        ALOGE("EAS_OpenFile failed: [%d]", (int)result);
        mState = EAS_STATE_ERROR;
        return ERROR_OPEN_FAILED;
    }

    mState = EAS_STATE_OPEN;
    mPlayTime = 0;
    return NO_ERROR;
}

status_t MidiFile::prepare()
{
    ALOGV("MidiFile::prepare");
    Mutex::Autolock lock(mMutex);
    if (!mEasHandle) {
        return ERROR_NOT_OPEN;
    }
    EAS_RESULT result;
    if ((result = EAS_Prepare(mEasData, mEasHandle)) != EAS_SUCCESS) {
        ALOGE("EAS_Prepare failed: [%ld]", result);
        return ERROR_EAS_FAILURE;
    }
    updateState();
    return NO_ERROR;
}

status_t MidiFile::prepareAsync()
{
    ALOGV("MidiFile::prepareAsync");
    status_t ret = prepare();

    // don't hold lock during callback
    if (ret == NO_ERROR) {
        sendEvent(MEDIA_PREPARED);
    } else {
        sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ret);
    }
    return ret;
}

status_t MidiFile::start()
{
    ALOGV("MidiFile::start");
    Mutex::Autolock lock(mMutex);
    if (!mEasHandle) {
        return ERROR_NOT_OPEN;
    }

    // resuming after pause?
    if (mPaused) {
        if (EAS_Resume(mEasData, mEasHandle) != EAS_SUCCESS) {
            return ERROR_EAS_FAILURE;
        }
        mPaused = false;
        updateState();
    }

    mRender = true;
    if (mState == EAS_STATE_PLAY) {
        sendEvent(MEDIA_STARTED);
    }

    // wake up render thread
    ALOGV("  wakeup render thread");
    mCondition.signal();
    return NO_ERROR;
}

status_t MidiFile::stop()
{
    ALOGV("MidiFile::stop");
    Mutex::Autolock lock(mMutex);
    if (!mEasHandle) {
        return ERROR_NOT_OPEN;
    }
    if (!mPaused && (mState != EAS_STATE_STOPPED)) {
        EAS_RESULT result = EAS_Pause(mEasData, mEasHandle);
        if (result != EAS_SUCCESS) {
            ALOGE("EAS_Pause returned error %ld", result);
            return ERROR_EAS_FAILURE;
        }
    }
    mPaused = false;
    sendEvent(MEDIA_STOPPED);
    return NO_ERROR;
}

status_t MidiFile::seekTo(int position)
{
    ALOGV("MidiFile::seekTo %d", position);
    // hold lock during EAS calls
    {
        Mutex::Autolock lock(mMutex);
        if (!mEasHandle) {
            return ERROR_NOT_OPEN;
        }
        EAS_RESULT result;
        if ((result = EAS_Locate(mEasData, mEasHandle, position, false))
                != EAS_SUCCESS)
        {
            ALOGE("EAS_Locate returned %ld", result);
            return ERROR_EAS_FAILURE;
        }
        EAS_GetLocation(mEasData, mEasHandle, &mPlayTime);
    }
    sendEvent(MEDIA_SEEK_COMPLETE);
    return NO_ERROR;
}

status_t MidiFile::pause()
{
    ALOGV("MidiFile::pause");
    Mutex::Autolock lock(mMutex);
    if (!mEasHandle) {
        return ERROR_NOT_OPEN;
    }
    if ((mState == EAS_STATE_PAUSING) || (mState == EAS_STATE_PAUSED)) return NO_ERROR;
    if (EAS_Pause(mEasData, mEasHandle) != EAS_SUCCESS) {
        return ERROR_EAS_FAILURE;
    }
    mPaused = true;
    sendEvent(MEDIA_PAUSED);
    return NO_ERROR;
}

bool MidiFile::isPlaying()
{
    ALOGV("MidiFile::isPlaying, mState=%d", int(mState));
    if (!mEasHandle || mPaused) return false;
    return (mState == EAS_STATE_PLAY);
}

status_t MidiFile::getCurrentPosition(int* position)
{
    ALOGV("MidiFile::getCurrentPosition");
    if (!mEasHandle) {
        ALOGE("getCurrentPosition(): file not open");
        return ERROR_NOT_OPEN;
    }
    if (mPlayTime < 0) {
        ALOGE("getCurrentPosition(): mPlayTime = %ld", mPlayTime);
        return ERROR_EAS_FAILURE;
    }
    *position = mPlayTime;
    return NO_ERROR;
}

status_t MidiFile::getDuration(int* duration)
{

    ALOGV("MidiFile::getDuration");
    {
        Mutex::Autolock lock(mMutex);
        if (!mEasHandle) return ERROR_NOT_OPEN;
        *duration = mDuration;
    }

    // if no duration cached, get the duration
    // don't need a lock here because we spin up a new engine
    if (*duration < 0) {
        EAS_I32 temp;
        EAS_DATA_HANDLE easData = NULL;
        EAS_HANDLE easHandle = NULL;
        EAS_RESULT result = EAS_Init(&easData);
        if (result == EAS_SUCCESS) {
            result = EAS_OpenFile(easData, &mFileLocator, &easHandle);
        }
        if (result == EAS_SUCCESS) {
            result = EAS_Prepare(easData, easHandle);
        }
        if (result == EAS_SUCCESS) {
            result = EAS_ParseMetaData(easData, easHandle, &temp);
        }
        if (easHandle) {
            EAS_CloseFile(easData, easHandle);
        }
        if (easData) {
            EAS_Shutdown(easData);
        }

        if (result != EAS_SUCCESS) {
            return ERROR_EAS_FAILURE;
        }

        // cache successful result
        mDuration = *duration = int(temp);
    }

    return NO_ERROR;
}

status_t MidiFile::release()
{
    ALOGV("MidiFile::release");
    Mutex::Autolock l(mMutex);
    reset_nosync();

    // wait for render thread to exit
    mExit = true;
    mCondition.signal();

    // wait for thread to exit
    if (mAudioBuffer) {
        mCondition.wait(mMutex);
    }

    // release resources
    if (mEasData) {
        EAS_Shutdown(mEasData);
        mEasData = NULL;
    }
    return NO_ERROR;
}

status_t MidiFile::reset()
{
    ALOGV("MidiFile::reset");
    Mutex::Autolock lock(mMutex);
    return reset_nosync();
}

// call only with mutex held
status_t MidiFile::reset_nosync()
{
    ALOGV("MidiFile::reset_nosync");
    sendEvent(MEDIA_STOPPED);
    // close file
    if (mEasHandle) {
        EAS_CloseFile(mEasData, mEasHandle);
        mEasHandle = NULL;
    }
    if (mFileLocator.path) {
        free((void*)mFileLocator.path);
        mFileLocator.path = NULL;
    }
    if (mFileLocator.fd >= 0) {
        close(mFileLocator.fd);
    }
    mFileLocator.fd = -1;
    mFileLocator.offset = 0;
    mFileLocator.length = 0;

    mPlayTime = -1;
    mDuration = -1;
    mLoop = false;
    mPaused = false;
    mRender = false;
    return NO_ERROR;
}

status_t MidiFile::setLooping(int loop)
{
    ALOGV("MidiFile::setLooping");
    Mutex::Autolock lock(mMutex);
    if (!mEasHandle) {
        return ERROR_NOT_OPEN;
    }
    loop = loop ? -1 : 0;
    if (EAS_SetRepeat(mEasData, mEasHandle, loop) != EAS_SUCCESS) {
        return ERROR_EAS_FAILURE;
    }
    return NO_ERROR;
}

status_t MidiFile::createOutputTrack() {
    if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels,
            CHANNEL_MASK_USE_CHANNEL_ORDER, AUDIO_FORMAT_PCM_16_BIT, 2 /*bufferCount*/) != NO_ERROR) {
        ALOGE("mAudioSink open failed");
        return ERROR_OPEN_FAILED;
    }
    return NO_ERROR;
}

int MidiFile::render() {
    EAS_RESULT result = EAS_FAILURE;
    EAS_I32 count;
    int temp;
    bool audioStarted = false;

    ALOGV("MidiFile::render");

    // allocate render buffer
    mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * NUM_BUFFERS];
    if (!mAudioBuffer) {
        ALOGE("mAudioBuffer allocate failed");
        goto threadExit;
    }

    // signal main thread that we started
    {
        Mutex::Autolock l(mMutex);
        mTid = gettid();
        ALOGV("render thread(%d) signal", mTid);
        mCondition.signal();
    }

    while (1) {
        mMutex.lock();

        // nothing to render, wait for client thread to wake us up
        while (!mRender && !mExit)
        {
            ALOGV("MidiFile::render - signal wait");
            mCondition.wait(mMutex);
            ALOGV("MidiFile::render - signal rx'd");
        }
        if (mExit) {
            mMutex.unlock();
            break;
        }

        // render midi data into the input buffer
        //ALOGV("MidiFile::render - rendering audio");
        int num_output = 0;
        EAS_PCM* p = mAudioBuffer;
        for (int i = 0; i < NUM_BUFFERS; i++) {
            result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count);
            if (result != EAS_SUCCESS) {
                ALOGE("EAS_Render returned %ld", result);
            }
            p += count * pLibConfig->numChannels;
            num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM);
        }

        // update playback state and position
        // ALOGV("MidiFile::render - updating state");
        EAS_GetLocation(mEasData, mEasHandle, &mPlayTime);
        EAS_State(mEasData, mEasHandle, &mState);
        mMutex.unlock();

        // create audio output track if necessary
        if (!mAudioSink->ready()) {
            ALOGV("MidiFile::render - create output track");
            if (createOutputTrack() != NO_ERROR)
                goto threadExit;
        }

        // Write data to the audio hardware
        // ALOGV("MidiFile::render - writing to audio output");
        if ((temp = mAudioSink->write(mAudioBuffer, num_output)) < 0) {
            ALOGE("Error in writing:%d",temp);
            return temp;
        }

        // start audio output if necessary
        if (!audioStarted) {
            //ALOGV("MidiFile::render - starting audio");
            mAudioSink->start();
            audioStarted = true;
        }

        // still playing?
        if ((mState == EAS_STATE_STOPPED) || (mState == EAS_STATE_ERROR) ||
                (mState == EAS_STATE_PAUSED))
        {
            switch(mState) {
            case EAS_STATE_STOPPED:
            {
                ALOGV("MidiFile::render - stopped");
                sendEvent(MEDIA_PLAYBACK_COMPLETE);
                break;
            }
            case EAS_STATE_ERROR:
            {
                ALOGE("MidiFile::render - error");
                sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN);
                break;
            }
            case EAS_STATE_PAUSED:
                ALOGV("MidiFile::render - paused");
                break;
            default:
                break;
            }
            mAudioSink->stop();
            audioStarted = false;
            mRender = false;
        }
    }

threadExit:
    mAudioSink.clear();
    if (mAudioBuffer) {
        delete [] mAudioBuffer;
        mAudioBuffer = NULL;
    }
    mMutex.lock();
    mTid = -1;
    mCondition.signal();
    mMutex.unlock();
    return result;
}

} // end namespace android
