• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  android_speech_srec_MicrophoneInputStream.cpp                            *
3  *                                                                           *
4  *  Copyright 2007 Nuance Communciations, Inc.                               *
5  *                                                                           *
6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
7  *  you may not use this file except in compliance with the License.         *
8  *                                                                           *
9  *  You may obtain a copy of the License at                                  *
10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
11  *                                                                           *
12  *  Unless required by applicable law or agreed to in writing, software      *
13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15  *  See the License for the specific language governing permissions and      *
16  *  limitations under the License.                                           *
17  *                                                                           *
18  *---------------------------------------------------------------------------*/
19 
20 
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #define LOG_TAG "srec_jni"
26 #include <utils/Log.h>
27 
28 #include <media/AudioRecord.h>
29 #include <media/mediarecorder.h>
30 
31 #include <system/audio.h>
32 
33 #include <jni.h>
34 
35 using namespace android;
36 
37 
38 
39 //
40 // helper function to throw an exception
41 //
throwException(JNIEnv * env,const char * ex,const char * fmt,int data)42 static void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) {
43     if (jclass cls = env->FindClass(ex)) {
44         char msg[1000];
45         sprintf(msg, fmt, data);
46         env->ThrowNew(cls, msg);
47         env->DeleteLocalRef(cls);
48     }
49 }
50 
51 
52 ///////////////////////////////////////////////////////////////////////////////
53 // MicrophoneInputStream JNI implememtations
54 ///////////////////////////////////////////////////////////////////////////////
55 
Java_android_speech_srec_Recognizer_AudioRecordNew(JNIEnv * env,jclass clazz,jint sampleRate,jint fifoFrames)56 static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_AudioRecordNew
57         (JNIEnv *env, jclass clazz, jint sampleRate, jint fifoFrames) {
58 
59     android::AudioRecord* ar = new android::AudioRecord(
60             AUDIO_SOURCE_VOICE_RECOGNITION, sampleRate,
61             AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO,
62             fifoFrames, 0);
63     if (ar == NULL) {
64         LOGE("Error creating AudioRecord");
65     }
66     else {
67         status_t s = ar->initCheck();
68         if (s != NO_ERROR) {
69             delete ar;
70             ar = NULL;
71             LOGE("initCheck error %d ", s);
72         }
73     }
74     return (int)ar;
75 }
76 
Java_android_speech_srec_Recognizer_AudioRecordStart(JNIEnv * env,jclass clazz,jint audioRecord)77 static JNIEXPORT int JNICALL Java_android_speech_srec_Recognizer_AudioRecordStart
78         (JNIEnv *env, jclass clazz, jint audioRecord) {
79     return (int)(((AudioRecord*)audioRecord)->start());
80 }
81 
Java_android_speech_srec_Recognizer_AudioRecordRead(JNIEnv * env,jclass clazz,jint audioRecord,jbyteArray array,jint offset,jint length)82 static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_AudioRecordRead
83         (JNIEnv *env, jclass clazz, jint audioRecord, jbyteArray array, jint offset, jint length) {
84     jbyte buffer[4096];
85     if (length > (int)sizeof(buffer)) length = sizeof(buffer);
86     length = ((AudioRecord*)audioRecord)->read(buffer, length);
87     if (length < 0) {
88         throwException(env, "java/io/IOException", "AudioRecord::read failed %d", length);
89         return -1;
90     }
91     env->SetByteArrayRegion(array, offset, length, buffer);
92     return length;
93 }
94 
Java_android_speech_srec_Recognizer_AudioRecordStop(JNIEnv * env,jclass clazz,jint audioRecord)95 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_AudioRecordStop
96         (JNIEnv *env, jclass clazz, jint audioRecord) {
97     if (int rtn = ((AudioRecord*)audioRecord)->stop()) {
98         throwException(env, "java/io/IOException", "AudioRecord::stop failed %d", rtn);
99     }
100 }
101 
Java_android_speech_srec_Recognizer_AudioRecordDelete(JNIEnv * env,jclass clazz,jint audioRecord)102 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_AudioRecordDelete
103         (JNIEnv *env, jclass clazz, jint audioRecord) {
104     delete (AudioRecord*)audioRecord;
105 }
106 
107 
108 /*
109  * Table of methods associated with a single class.
110  */
111 static JNINativeMethod gMethods[] = {
112     /* name, signature, funcPtr */
113     {"AudioRecordNew",    "(II)I",    (void*)Java_android_speech_srec_Recognizer_AudioRecordNew},
114     {"AudioRecordStart",  "(I)I",     (void*)Java_android_speech_srec_Recognizer_AudioRecordStart},
115     {"AudioRecordRead",   "(I[BII)I", (void*)Java_android_speech_srec_Recognizer_AudioRecordRead},
116     {"AudioRecordStop",   "(I)V",     (void*)Java_android_speech_srec_Recognizer_AudioRecordStop},
117     {"AudioRecordDelete", "(I)V",     (void*)Java_android_speech_srec_Recognizer_AudioRecordDelete},
118 };
119 
120 /*
121  * Set some test stuff up.
122  *
123  * Returns the JNI version on success, -1 on failure.
124  */
register_android_speech_srec_MicrophoneInputStream(JavaVM * vm,void * reserved)125 jint register_android_speech_srec_MicrophoneInputStream(JavaVM* vm, void* reserved)
126 {
127     JNIEnv* env = NULL;
128     jclass clazz = NULL;
129     const char* className = "android/speech/srec/MicrophoneInputStream";
130 
131     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
132         LOGE("ERROR: GetEnv failed\n");
133         return -1;
134     }
135     assert(env != NULL);
136 
137     clazz = env->FindClass(className);
138     if (clazz == NULL) {
139         LOGE("Native registration unable to find class '%s'\n", className);
140         return -1;
141     }
142     if (env->RegisterNatives(clazz, gMethods,
143             sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
144         LOGE("RegisterNatives failed for '%s'\n", className);
145         return -1;
146     }
147 
148     /* success -- return valid version number */
149     return JNI_VERSION_1_4;;
150 }
151