android_speech_srec_MicrophoneInputStream.cpp revision 570be96f35b570ee31c86a602cc6c050e03a1f3d
14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  android_speech_srec_MicrophoneInputStream.cpp                            *
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007 Nuance Communciations, Inc.                               *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string.h>
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdio.h>
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdlib.h>
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define LOG_TAG "srec_jni"
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <utils/Log.h>
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <media/AudioRecord.h>
2985d4a2a8fe7c306f0e0cfd30f51e9015566c021dEric Laurent#include <media/mediarecorder.h>
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
31570be96f35b570ee31c86a602cc6c050e03a1f3dDima Zavin#include <system/audio.h>
321b229941e91e25f6fa787b20cd6f53c818b2eb7fDima Zavin
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <jni.h>
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectusing namespace android;
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// helper function to throw an exception
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) {
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (jclass cls = env->FindClass(ex)) {
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        char msg[1000];
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        sprintf(msg, fmt, data);
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        env->ThrowNew(cls, msg);
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        env->DeleteLocalRef(cls);
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// MicrophoneInputStream JNI implememtations
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_AudioRecordNew
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        (JNIEnv *env, jclass clazz, jint sampleRate, jint fifoFrames) {
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    android::AudioRecord* ar = new android::AudioRecord(
601b229941e91e25f6fa787b20cd6f53c818b2eb7fDima Zavin            AUDIO_SOURCE_VOICE_RECOGNITION, sampleRate,
611b229941e91e25f6fa787b20cd6f53c818b2eb7fDima Zavin            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO,
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fifoFrames, 0);
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (ar == NULL) {
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LOGE("Error creating AudioRecord");
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else {
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        status_t s = ar->initCheck();
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (s != NO_ERROR) {
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            delete ar;
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            ar = NULL;
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            LOGE("initCheck error %d ", s);
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return (int)ar;
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic JNIEXPORT int JNICALL Java_android_speech_srec_Recognizer_AudioRecordStart
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        (JNIEnv *env, jclass clazz, jint audioRecord) {
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return (int)(((AudioRecord*)audioRecord)->start());
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_AudioRecordRead
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        (JNIEnv *env, jclass clazz, jint audioRecord, jbyteArray array, jint offset, jint length) {
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    jbyte buffer[4096];
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (length > (int)sizeof(buffer)) length = sizeof(buffer);
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    length = ((AudioRecord*)audioRecord)->read(buffer, length);
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (length < 0) {
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        throwException(env, "java/io/IOException", "AudioRecord::read failed %d", length);
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return -1;
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    env->SetByteArrayRegion(array, offset, length, buffer);
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return length;
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_AudioRecordStop
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        (JNIEnv *env, jclass clazz, jint audioRecord) {
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (int rtn = ((AudioRecord*)audioRecord)->stop()) {
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        throwException(env, "java/io/IOException", "AudioRecord::stop failed %d", rtn);
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_AudioRecordDelete
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        (JNIEnv *env, jclass clazz, jint audioRecord) {
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    delete (AudioRecord*)audioRecord;
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Table of methods associated with a single class.
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic JNINativeMethod gMethods[] = {
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* name, signature, funcPtr */
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {"AudioRecordNew",    "(II)I",    (void*)Java_android_speech_srec_Recognizer_AudioRecordNew},
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {"AudioRecordStart",  "(I)I",     (void*)Java_android_speech_srec_Recognizer_AudioRecordStart},
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {"AudioRecordRead",   "(I[BII)I", (void*)Java_android_speech_srec_Recognizer_AudioRecordRead},
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {"AudioRecordStop",   "(I)V",     (void*)Java_android_speech_srec_Recognizer_AudioRecordStop},
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {"AudioRecordDelete", "(I)V",     (void*)Java_android_speech_srec_Recognizer_AudioRecordDelete},
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Set some test stuff up.
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Returns the JNI version on success, -1 on failure.
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectjint register_android_speech_srec_MicrophoneInputStream(JavaVM* vm, void* reserved)
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    JNIEnv* env = NULL;
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    jclass clazz = NULL;
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const char* className = "android/speech/srec/MicrophoneInputStream";
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LOGE("ERROR: GetEnv failed\n");
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return -1;
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    assert(env != NULL);
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    clazz = env->FindClass(className);
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (clazz == NULL) {
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LOGE("Native registration unable to find class '%s'\n", className);
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return -1;
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (env->RegisterNatives(clazz, gMethods,
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LOGE("RegisterNatives failed for '%s'\n", className);
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return -1;
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* success -- return valid version number */
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return JNI_VERSION_1_4;;
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
151