/*---------------------------------------------------------------------------*
 *  android_speech_srec_MicrophoneInputStream.cpp                            *
 *                                                                           *
 *  Copyright 2007 Nuance Communciations, Inc.                               *
 *                                                                           *
 *  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.                                           *
 *                                                                           *
 *---------------------------------------------------------------------------*/


#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define LOG_TAG "srec_jni"
#include <utils/Log.h>

#include <media/AudioRecord.h>
#include <media/mediarecorder.h>

#include <system/audio.h>

#include <jni.h>

using namespace android;



//
// helper function to throw an exception
//
static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) {
    if (jclass cls = env->FindClass(ex)) {
        char msg[1000];
        sprintf(msg, fmt, data);
        env->ThrowNew(cls, msg);
        env->DeleteLocalRef(cls);
    }
}


///////////////////////////////////////////////////////////////////////////////
// MicrophoneInputStream JNI implememtations
///////////////////////////////////////////////////////////////////////////////

static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_AudioRecordNew
        (JNIEnv *env, jclass clazz, jint sampleRate, jint fifoFrames) {

    android::AudioRecord* ar = new android::AudioRecord(
            AUDIO_SOURCE_VOICE_RECOGNITION, sampleRate,
            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO,
            fifoFrames);
    if (ar == NULL) {
        ALOGE("Error creating AudioRecord");
    }
    else {
        status_t s = ar->initCheck();
        if (s != NO_ERROR) {
            delete ar;
            ar = NULL;
            ALOGE("initCheck error %d ", s);
        }
    }
    return (int)ar;
}

static JNIEXPORT int JNICALL Java_android_speech_srec_Recognizer_AudioRecordStart
        (JNIEnv *env, jclass clazz, jint audioRecord) {
    return (int)(((AudioRecord*)audioRecord)->start());
}

static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_AudioRecordRead
        (JNIEnv *env, jclass clazz, jint audioRecord, jbyteArray array, jint offset, jint length) {
    jbyte buffer[4096];
    if (length > (int)sizeof(buffer)) length = sizeof(buffer);
    length = ((AudioRecord*)audioRecord)->read(buffer, length);
    if (length < 0) {
        throwException(env, "java/io/IOException", "AudioRecord::read failed %d", length);
        return -1;
    }
    env->SetByteArrayRegion(array, offset, length, buffer);
    return length;
}

static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_AudioRecordStop
        (JNIEnv *env, jclass clazz, jint audioRecord) {
    ((AudioRecord*)audioRecord)->stop();
}

static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_AudioRecordDelete
        (JNIEnv *env, jclass clazz, jint audioRecord) {
    delete (AudioRecord*)audioRecord;
}


/*
 * Table of methods associated with a single class.
 */
static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    {"AudioRecordNew",    "(II)I",    (void*)Java_android_speech_srec_Recognizer_AudioRecordNew},
    {"AudioRecordStart",  "(I)I",     (void*)Java_android_speech_srec_Recognizer_AudioRecordStart},
    {"AudioRecordRead",   "(I[BII)I", (void*)Java_android_speech_srec_Recognizer_AudioRecordRead},
    {"AudioRecordStop",   "(I)V",     (void*)Java_android_speech_srec_Recognizer_AudioRecordStop},
    {"AudioRecordDelete", "(I)V",     (void*)Java_android_speech_srec_Recognizer_AudioRecordDelete},
};

/*
 * Set some test stuff up.
 *
 * Returns the JNI version on success, -1 on failure.
 */
jint register_android_speech_srec_MicrophoneInputStream(JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;
    jclass clazz = NULL;
    const char* className = "android/speech/srec/MicrophoneInputStream";

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("ERROR: GetEnv failed\n");
        return -1;
    }
    assert(env != NULL);

    clazz = env->FindClass(className);
    if (clazz == NULL) {
        ALOGE("Native registration unable to find class '%s'\n", className);
        return -1;
    }
    if (env->RegisterNatives(clazz, gMethods,
            sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
        ALOGE("RegisterNatives failed for '%s'\n", className);
        return -1;
    }

    /* success -- return valid version number */
    return JNI_VERSION_1_4;;
}
