/*
 * Copyright (C) 2011 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 1
#include <audio_utils/primitives.h>
#include <utils/Log.h>
#include "AudioResampler.h"
#include "VideoEditorResampler.h"

namespace android {

struct VideoEditorResampler : public AudioBufferProvider {

    public:

        virtual status_t getNextBuffer(Buffer* buffer, int64_t pts);
        virtual void releaseBuffer(Buffer* buffer);

    enum { //Sampling freq
     kFreq8000Hz = 8000,
     kFreq11025Hz = 11025,
     kFreq12000Hz = 12000,
     kFreq16000Hz = 16000,
     kFreq22050Hz = 22050,
     kFreq24000Hz = 24000,
     kFreq32000Hz = 32000,
     kFreq44100 = 44100,
     kFreq48000 = 48000,
    };

    AudioResampler *mResampler;
    int16_t* mInput;
    int nbChannels;
    int nbSamples;
    M4OSA_Int32 outSamplingRate;
    M4OSA_Int32 inSamplingRate;

    int16_t *mTmpInBuffer;
};

#define MAX_SAMPLEDURATION_FOR_CONVERTION 40 //ms

status_t VideoEditorResampler::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, int64_t pts) {

    uint32_t dataSize = pBuffer->frameCount * this->nbChannels * sizeof(int16_t);
    mTmpInBuffer = (int16_t*)malloc(dataSize);
    memcpy(mTmpInBuffer, this->mInput, dataSize);
    pBuffer->raw = (void*)mTmpInBuffer;

    return OK;
}

void VideoEditorResampler::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {

    if(pBuffer->raw != NULL) {
        free(pBuffer->raw);
        pBuffer->raw = NULL;
        mTmpInBuffer = NULL;
    }
    pBuffer->frameCount = 0;
}

extern "C" {

M4OSA_Context  LVAudioResamplerCreate(M4OSA_Int32 bitDepth, M4OSA_Int32 inChannelCount,
                                     M4OSA_Int32 sampleRate, M4OSA_Int32 quality) {

    VideoEditorResampler *context = new VideoEditorResampler();
    context->mResampler = AudioResampler::create(
        bitDepth, inChannelCount, sampleRate);
    if (context->mResampler == NULL) {
        return NULL;
    }
    context->mResampler->setSampleRate(android::VideoEditorResampler::kFreq32000Hz);
    context->mResampler->setVolume(0x1000, 0x1000);
    context->nbChannels = inChannelCount;
    context->outSamplingRate = sampleRate;
    context->mInput = NULL;
    context->mTmpInBuffer = NULL;

    return ((M4OSA_Context )context);
}


void LVAudiosetSampleRate(M4OSA_Context resamplerContext, M4OSA_Int32 inSampleRate) {

    VideoEditorResampler *context =
      (VideoEditorResampler *)resamplerContext;
    context->mResampler->setSampleRate(inSampleRate);
    /*
     * nbSamples is calculated for 40ms worth of data;hence sample rate
     * is used to calculate the nbSamples
     */
    context->inSamplingRate = inSampleRate;
    // Allocate buffer for maximum allowed number of samples.
    context->mInput = (int16_t*)malloc( (inSampleRate * MAX_SAMPLEDURATION_FOR_CONVERTION *
                                   context->nbChannels * sizeof(int16_t)) / 1000);
}

void LVAudiosetVolume(M4OSA_Context resamplerContext, M4OSA_Int16 left, M4OSA_Int16 right) {

    VideoEditorResampler *context =
       (VideoEditorResampler *)resamplerContext;
    context->mResampler->setVolume(left,right);
}

void LVDestroy(M4OSA_Context resamplerContext) {

    VideoEditorResampler *context =
       (VideoEditorResampler *)resamplerContext;

    if (context->mTmpInBuffer != NULL) {
        free(context->mTmpInBuffer);
        context->mTmpInBuffer = NULL;
    }

    if (context->mInput != NULL) {
        free(context->mInput);
        context->mInput = NULL;
    }

    if (context->mResampler != NULL) {
        delete context->mResampler;
        context->mResampler = NULL;
    }

    if (context != NULL) {
        delete context;
        context = NULL;
    }
}

void LVAudioresample_LowQuality(M4OSA_Int16* out, M4OSA_Int16* input,
                                     M4OSA_Int32 outFrameCount, M4OSA_Context resamplerContext) {

    VideoEditorResampler *context =
      (VideoEditorResampler *)resamplerContext;
    int32_t *pTmpBuffer = NULL;

    context->nbSamples = (context->inSamplingRate * outFrameCount) / context->outSamplingRate;
    memcpy(context->mInput,input,(context->nbSamples * context->nbChannels * sizeof(int16_t)));

    /*
     SRC module always gives stereo output, hence 2 for stereo audio
    */
    pTmpBuffer = (int32_t*)malloc(outFrameCount * 2 * sizeof(int32_t));
    memset(pTmpBuffer, 0x00, outFrameCount * 2 * sizeof(int32_t));

    context->mResampler->resample((int32_t *)pTmpBuffer,
       (size_t)outFrameCount, (VideoEditorResampler *)resamplerContext);
    // Convert back to 16 bits
    ditherAndClamp((int32_t*)out, pTmpBuffer, outFrameCount);
    free(pTmpBuffer);
    pTmpBuffer = NULL;
}

}

} //namespace android
