/*
**
** Copyright 2010, 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 "Visualizer"
#include <utils/Log.h>

#include <stdint.h>
#include <sys/types.h>
#include <limits.h>

#include <media/Visualizer.h>

extern void fixed_fft_real(int n, int32_t *v);

namespace android {

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

Visualizer::Visualizer (int32_t priority,
         effect_callback_t cbf,
         void* user,
         int sessionId)
    :   AudioEffect(SL_IID_VISUALIZATION, NULL, priority, cbf, user, sessionId),
        mCaptureRate(CAPTURE_RATE_DEF),
        mCaptureSize(CAPTURE_SIZE_DEF),
        mSampleRate(44100000),
        mCaptureCallBack(NULL),
        mCaptureCbkUser(NULL)
{
    initCaptureSize();
}

Visualizer::~Visualizer()
{
}

status_t Visualizer::setEnabled(bool enabled)
{
    Mutex::Autolock _l(mLock);

    sp<CaptureThread> t = mCaptureThread;
    if (t != 0) {
        if (enabled) {
            if (t->exitPending()) {
                if (t->requestExitAndWait() == WOULD_BLOCK) {
                    LOGE("Visualizer::enable() called from thread");
                    return INVALID_OPERATION;
                }
            }
        }
        t->mLock.lock();
     }

    status_t status = AudioEffect::setEnabled(enabled);

    if (status == NO_ERROR) {
        if (t != 0) {
            if (enabled) {
                t->run("AudioTrackThread");
            } else {
                t->requestExit();
            }
        }
    }

    if (t != 0) {
        t->mLock.unlock();
    }

    return status;
}

status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate)
{
    if (rate > CAPTURE_RATE_MAX) {
        return BAD_VALUE;
    }
    Mutex::Autolock _l(mLock);

    if (mEnabled) {
        return INVALID_OPERATION;
    }

    sp<CaptureThread> t = mCaptureThread;
    if (t != 0) {
        t->mLock.lock();
    }
    mCaptureThread.clear();
    mCaptureCallBack = cbk;
    mCaptureCbkUser = user;
    mCaptureFlags = flags;
    mCaptureRate = rate;

    if (t != 0) {
        t->mLock.unlock();
    }

    if (cbk != NULL) {
        mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0));
        if (mCaptureThread == 0) {
            LOGE("Could not create callback thread");
            return NO_INIT;
        }
    }
    LOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x",
            rate, mCaptureThread.get(), mCaptureFlags);
    return NO_ERROR;
}

status_t Visualizer::setCaptureSize(uint32_t size)
{
    if (size > VISUALIZER_CAPTURE_SIZE_MAX ||
        size < VISUALIZER_CAPTURE_SIZE_MIN ||
        AudioSystem::popCount(size) != 1) {
        return BAD_VALUE;
    }

    Mutex::Autolock _l(mLock);
    if (mEnabled) {
        return INVALID_OPERATION;
    }

    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
    effect_param_t *p = (effect_param_t *)buf32;

    p->psize = sizeof(uint32_t);
    p->vsize = sizeof(uint32_t);
    *(int32_t *)p->data = VISU_PARAM_CAPTURE_SIZE;
    *((int32_t *)p->data + 1)= size;
    status_t status = setParameter(p);

    LOGV("setCaptureSize size %d  status %d p->status %d", size, status, p->status);

    if (status == NO_ERROR) {
        status = p->status;
    }
    if (status == NO_ERROR) {
        mCaptureSize = size;
    }

    return status;
}

status_t Visualizer::getWaveForm(uint8_t *waveform)
{
    if (waveform == NULL) {
        return BAD_VALUE;
    }
    if (mCaptureSize == 0) {
        return NO_INIT;
    }

    status_t status = NO_ERROR;
    if (mEnabled) {
        uint32_t replySize = mCaptureSize;
        status = command(VISU_CMD_CAPTURE, 0, NULL, &replySize, waveform);
        LOGV("getWaveForm() command returned %d", status);
        if (replySize == 0) {
            status = NOT_ENOUGH_DATA;
        }
    } else {
        LOGV("getWaveForm() disabled");
        memset(waveform, 0x80, mCaptureSize);
    }
    return status;
}

status_t Visualizer::getFft(uint8_t *fft)
{
    if (fft == NULL) {
        return BAD_VALUE;
    }
    if (mCaptureSize == 0) {
        return NO_INIT;
    }

    status_t status = NO_ERROR;
    if (mEnabled) {
        uint8_t buf[mCaptureSize];
        status = getWaveForm(buf);
        if (status == NO_ERROR) {
            status = doFft(fft, buf);
        }
    } else {
        memset(fft, 0, mCaptureSize);
    }
    return status;
}

status_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform)
{
    int32_t workspace[mCaptureSize >> 1];
    int32_t nonzero = 0;

    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
        workspace[i >> 1] = (waveform[i] ^ 0x80) << 23;
        workspace[i >> 1] |= (waveform[i + 1] ^ 0x80) << 7;
        nonzero |= workspace[i >> 1];
    }

    if (nonzero) {
        fixed_fft_real(mCaptureSize >> 1, workspace);
    }

    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
        fft[i] = workspace[i >> 1] >> 23;
        fft[i + 1] = workspace[i >> 1] >> 7;
    }

    return NO_ERROR;
}

void Visualizer::periodicCapture()
{
    Mutex::Autolock _l(mLock);
    LOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x",
            this, mCaptureCallBack, mCaptureFlags);
    if (mCaptureCallBack != NULL &&
        (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) &&
        mCaptureSize != 0) {
        uint8_t waveform[mCaptureSize];
        status_t status = getWaveForm(waveform);
        if (status != NO_ERROR) {
            return;
        }
        uint8_t fft[mCaptureSize];
        if (mCaptureFlags & CAPTURE_FFT) {
            status = doFft(fft, waveform);
        }
        if (status != NO_ERROR) {
            return;
        }
        uint8_t *wavePtr = NULL;
        uint8_t *fftPtr = NULL;
        uint32_t waveSize = 0;
        uint32_t fftSize = 0;
        if (mCaptureFlags & CAPTURE_WAVEFORM) {
            wavePtr = waveform;
            waveSize = mCaptureSize;
        }
        if (mCaptureFlags & CAPTURE_FFT) {
            fftPtr = fft;
            fftSize = mCaptureSize;
        }
        mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate);
    }
}

uint32_t Visualizer::initCaptureSize()
{
    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
    effect_param_t *p = (effect_param_t *)buf32;

    p->psize = sizeof(uint32_t);
    p->vsize = sizeof(uint32_t);
    *(int32_t *)p->data = VISU_PARAM_CAPTURE_SIZE;
    status_t status = getParameter(p);

    if (status == NO_ERROR) {
        status = p->status;
    }

    uint32_t size = 0;
    if (status == NO_ERROR) {
        size = *((int32_t *)p->data + 1);
    }
    mCaptureSize = size;

    LOGV("initCaptureSize size %d status %d", mCaptureSize, status);

    return size;
}

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

Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava)
    : Thread(bCanCallJava), mReceiver(receiver)
{
    mSleepTimeUs = 1000000000 / captureRate;
    LOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs);
}

bool Visualizer::CaptureThread::threadLoop()
{
    LOGV("CaptureThread %p enter", this);
    while (!exitPending())
    {
        usleep(mSleepTimeUs);
        mReceiver.periodicCapture();
    }
    LOGV("CaptureThread %p exiting", this);
    return false;
}

status_t Visualizer::CaptureThread::readyToRun()
{
    return NO_ERROR;
}

void Visualizer::CaptureThread::onFirstRef()
{
}

}; // namespace android

