auto import from //depot/cupcake/@135843
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
new file mode 100644
index 0000000..288433a
--- /dev/null
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2008 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 "AudioRecord-JNI"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include "utils/Log.h"
+#include "media/AudioSystem.h"
+#include "media/AudioRecord.h"
+
+
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+static const char* const kClassPathName = "android/media/AudioRecord";
+
+struct fields_t {
+ // these fields provide access from C++ to the...
+ jclass audioRecordClass; //... AudioRecord class
+ jmethodID postNativeEventInJava; //... event post callback method
+ int PCM16; //... format constants
+ int PCM8; //... format constants
+ int SOURCE_DEFAULT; //... record source constants
+ int SOURCE_MIC; //... record source constants
+ jfieldID nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object
+ jfieldID nativeCallbackCookie; // provides access to the AudioRecord callback data
+};
+static fields_t javaAudioRecordFields;
+
+struct audiorecord_callback_cookie {
+ jclass audioRecord_class;
+ jobject audioRecord_ref;
+ };
+
+// ----------------------------------------------------------------------------
+
+#define AUDIORECORD_SUCCESS 0
+#define AUDIORECORD_ERROR -1
+#define AUDIORECORD_ERROR_BAD_VALUE -2
+#define AUDIORECORD_ERROR_INVALID_OPERATION -3
+#define AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT -16
+#define AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT -17
+#define AUDIORECORD_ERROR_SETUP_INVALIDFORMAT -18
+#define AUDIORECORD_ERROR_SETUP_INVALIDSTREAMTYPE -19
+#define AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED -20
+
+jint android_media_translateRecorderErrorCode(int code) {
+ switch(code) {
+ case NO_ERROR:
+ return AUDIORECORD_SUCCESS;
+ case BAD_VALUE:
+ return AUDIORECORD_ERROR_BAD_VALUE;
+ case INVALID_OPERATION:
+ return AUDIORECORD_ERROR_INVALID_OPERATION;
+ default:
+ return AUDIORECORD_ERROR;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+static void recorderCallback(int event, void* user, void *info) {
+ if (event == AudioRecord::EVENT_MORE_DATA) {
+ // set size to 0 to signal we're not using the callback to read more data
+ AudioRecord::Buffer* pBuff = (AudioRecord::Buffer*)info;
+ pBuff->size = 0;
+
+ } else if (event == AudioRecord::EVENT_MARKER) {
+ audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ if (user && env) {
+ env->CallStaticVoidMethod(
+ callbackInfo->audioRecord_class,
+ javaAudioRecordFields.postNativeEventInJava,
+ callbackInfo->audioRecord_ref, event, 0,0, NULL);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ }
+
+ } else if (event == AudioRecord::EVENT_NEW_POS) {
+ audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ if (user && env) {
+ env->CallStaticVoidMethod(
+ callbackInfo->audioRecord_class,
+ javaAudioRecordFields.postNativeEventInJava,
+ callbackInfo->audioRecord_ref, event, 0,0, NULL);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+static int
+android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+ jint source, jint sampleRateInHertz, jint nbChannels,
+ jint audioFormat, jint buffSizeInBytes)
+{
+ //LOGV(">> Entering android_media_AudioRecord_setup");
+ //LOGV("sampleRate=%d, audioFormat=%d, nbChannels=%d, buffSizeInBytes=%d",
+ // sampleRateInHertz, audioFormat, nbChannels, buffSizeInBytes);
+
+ if ((nbChannels == 0) || (nbChannels > 2)) {
+ LOGE("Error creating AudioRecord: channel count is not 1 or 2.");
+ return AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT;
+ }
+
+ // compare the format against the Java constants
+ if ((audioFormat != javaAudioRecordFields.PCM16)
+ && (audioFormat != javaAudioRecordFields.PCM8)) {
+ LOGE("Error creating AudioRecord: unsupported audio format.");
+ return AUDIORECORD_ERROR_SETUP_INVALIDFORMAT;
+ }
+
+ int bytesPerSample = audioFormat==javaAudioRecordFields.PCM16 ? 2 : 1;
+ int format = audioFormat==javaAudioRecordFields.PCM16 ?
+ AudioSystem::PCM_16_BIT : AudioSystem::PCM_8_BIT;
+
+ if (buffSizeInBytes == 0) {
+ LOGE("Error creating AudioRecord: frameCount is 0.");
+ return AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT;
+ }
+ int frameSize = nbChannels * bytesPerSample;
+ size_t frameCount = buffSizeInBytes / frameSize;
+
+ // compare the source against the Java constants
+ AudioRecord::stream_type arSource;
+ if (source == javaAudioRecordFields.SOURCE_DEFAULT) {
+ arSource = AudioRecord::DEFAULT_INPUT;
+ } else if (source == javaAudioRecordFields.SOURCE_MIC) {
+ arSource = AudioRecord::MIC_INPUT;
+ } else {
+ LOGE("Error creating AudioRecord: unknown source.");
+ return AUDIORECORD_ERROR_SETUP_INVALIDSTREAMTYPE;
+ }
+
+ audiorecord_callback_cookie *lpCallbackData = NULL;
+ AudioRecord* lpRecorder = NULL;
+
+ // create an uninitialized AudioRecord object
+ lpRecorder = new AudioRecord();
+ if(lpRecorder == NULL) {
+ LOGE("Error creating AudioRecord instance.");
+ return AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
+ }
+
+ // create the callback information:
+ // this data will be passed with every AudioRecord callback
+ jclass clazz = env->GetObjectClass(thiz);
+ if (clazz == NULL) {
+ LOGE("Can't find %s when setting up callback.", kClassPathName);
+ goto native_track_failure;
+ }
+ lpCallbackData = new audiorecord_callback_cookie;
+ lpCallbackData->audioRecord_class = (jclass)env->NewGlobalRef(clazz);
+ // we use a weak reference so the AudioRecord object can be garbage collected.
+ lpCallbackData->audioRecord_ref = env->NewGlobalRef(weak_this);
+
+ lpRecorder->set(arSource,
+ sampleRateInHertz,
+ format, // word length, PCM
+ nbChannels,
+ frameCount,
+ 0, // flags
+ recorderCallback,// callback_t
+ lpCallbackData,// void* user
+ 0, // notificationFrames,
+ true); // threadCanCallJava)
+
+ if(lpRecorder->initCheck() != NO_ERROR) {
+ LOGE("Error creating AudioRecord instance: initialization check failed.");
+ goto native_init_failure;
+ }
+
+ // save our newly created C++ AudioRecord in the "nativeRecorderInJavaObj" field
+ // of the Java object
+ env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (int)lpRecorder);
+
+ // save our newly created callback information in the "nativeCallbackCookie" field
+ // of the Java object (in mNativeCallbackCookie) so we can free the memory in finalize()
+ env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, (int)lpCallbackData);
+
+ return AUDIORECORD_SUCCESS;
+
+ // failure:
+native_init_failure:
+ delete lpCallbackData;
+
+native_track_failure:
+ delete lpRecorder;
+
+ env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
+ env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
+
+ return AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
+}
+
+
+
+// ----------------------------------------------------------------------------
+static void
+android_media_AudioRecord_start(JNIEnv *env, jobject thiz)
+{
+ AudioRecord *lpRecorder =
+ (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ if (lpRecorder == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ lpRecorder->start();
+}
+
+
+// ----------------------------------------------------------------------------
+static void
+android_media_AudioRecord_stop(JNIEnv *env, jobject thiz)
+{
+ AudioRecord *lpRecorder =
+ (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ if (lpRecorder == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ lpRecorder->stop();
+ //LOGV("Called lpRecorder->stop()");
+}
+
+
+// ----------------------------------------------------------------------------
+static void android_media_AudioRecord_finalize(JNIEnv *env, jobject thiz) {
+
+ // delete the AudioRecord object
+ AudioRecord *lpRecorder =
+ (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+
+ if (lpRecorder) {
+ LOGV("About to delete lpRecorder: %x\n", (int)lpRecorder);
+ lpRecorder->stop();
+ delete lpRecorder;
+ }
+
+ // delete the callback information
+ audiorecord_callback_cookie *lpCookie = (audiorecord_callback_cookie *)env->GetIntField(
+ thiz, javaAudioRecordFields.nativeCallbackCookie);
+ if (lpCookie) {
+ LOGV("deleting lpCookie: %x\n", (int)lpCookie);
+ delete lpCookie;
+ }
+
+}
+
+
+// ----------------------------------------------------------------------------
+static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) {
+
+ // do everything a call to finalize would
+ android_media_AudioRecord_finalize(env, thiz);
+ // + reset the native resources in the Java object so any attempt to access
+ // them after a call to release fails.
+ env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
+ env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_readInByteArray(JNIEnv *env, jobject thiz,
+ jbyteArray javaAudioData,
+ jint offsetInBytes, jint sizeInBytes) {
+ jbyte* recordBuff = NULL;
+ AudioRecord *lpRecorder = NULL;
+
+ // get the audio recorder from which we'll read new audio samples
+ lpRecorder =
+ (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ if (lpRecorder == NULL) {
+ LOGE("Unable to retrieve AudioRecord object, can't record");
+ return 0;
+ }
+
+ if (!javaAudioData) {
+ LOGE("Invalid Java array to store recorded audio, can't record");
+ return 0;
+ }
+
+ // get the pointer to where we'll record the audio
+ recordBuff = (jbyte *)env->GetPrimitiveArrayCritical(javaAudioData, NULL);
+
+ if (recordBuff == NULL) {
+ LOGE("Error retrieving destination for recorded audio data, can't record");
+ return 0;
+ }
+
+ // read the new audio data from the native AudioRecord object
+ ssize_t recorderBuffSize = lpRecorder->frameCount()*lpRecorder->frameSize();
+ ssize_t readSize = lpRecorder->read(recordBuff + offsetInBytes,
+ sizeInBytes > (jint)recorderBuffSize ?
+ (jint)recorderBuffSize : sizeInBytes );
+ env->ReleasePrimitiveArrayCritical(javaAudioData, recordBuff, 0);
+
+ return (jint) readSize;
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_readInShortArray(JNIEnv *env, jobject thiz,
+ jshortArray javaAudioData,
+ jint offsetInShorts, jint sizeInShorts) {
+
+ return (android_media_AudioRecord_readInByteArray(env, thiz,
+ (jbyteArray) javaAudioData,
+ offsetInShorts*2, sizeInShorts*2)
+ / 2);
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_readInDirectBuffer(JNIEnv *env, jobject thiz,
+ jobject jBuffer, jint sizeInBytes) {
+ AudioRecord *lpRecorder = NULL;
+ //LOGV("Entering android_media_AudioRecord_readInBuffer");
+
+ // get the audio recorder from which we'll read new audio samples
+ lpRecorder =
+ (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ if(lpRecorder==NULL)
+ return 0;
+
+ // direct buffer and direct access supported?
+ long capacity = env->GetDirectBufferCapacity(jBuffer);
+ if(capacity == -1) {
+ // buffer direct access is not supported
+ LOGE("Buffer direct access is not supported, can't record");
+ return 0;
+ }
+ //LOGV("capacity = %ld", capacity);
+ jbyte* nativeFromJavaBuf = (jbyte*) env->GetDirectBufferAddress(jBuffer);
+ if(nativeFromJavaBuf==NULL) {
+ LOGE("Buffer direct access is not supported, can't record");
+ return 0;
+ }
+
+ // read new data from the recorder
+ return (jint) lpRecorder->read(nativeFromJavaBuf,
+ capacity < sizeInBytes ? capacity : sizeInBytes);
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_set_marker_pos(JNIEnv *env, jobject thiz,
+ jint markerPos) {
+
+ AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+ thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+
+ if (lpRecorder) {
+ return
+ android_media_translateRecorderErrorCode( lpRecorder->setMarkerPosition(markerPos) );
+ } else {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioRecord pointer for setMarkerPosition()");
+ return AUDIORECORD_ERROR;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_get_marker_pos(JNIEnv *env, jobject thiz) {
+
+ AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+ thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ uint32_t markerPos = 0;
+
+ if (lpRecorder) {
+ lpRecorder->getMarkerPosition(&markerPos);
+ return (jint)markerPos;
+ } else {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioRecord pointer for getMarkerPosition()");
+ return AUDIORECORD_ERROR;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_set_pos_update_period(JNIEnv *env, jobject thiz,
+ jint period) {
+
+ AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+ thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+
+ if (lpRecorder) {
+ return
+ android_media_translateRecorderErrorCode( lpRecorder->setPositionUpdatePeriod(period) );
+ } else {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioRecord pointer for setPositionUpdatePeriod()");
+ return AUDIORECORD_ERROR;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_get_pos_update_period(JNIEnv *env, jobject thiz) {
+
+ AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+ thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ uint32_t period = 0;
+
+ if (lpRecorder) {
+ lpRecorder->getPositionUpdatePeriod(&period);
+ return (jint)period;
+ } else {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioRecord pointer for getPositionUpdatePeriod()");
+ return AUDIORECORD_ERROR;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// returns the minimum required size for the successful creation of an AudioRecord instance.
+// returns 0 if the parameter combination is not supported.
+// return -1 if there was an error querying the buffer size.
+static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject thiz,
+ jint sampleRateInHertz, jint nbChannels, jint audioFormat) {
+
+ size_t inputBuffSize = 0;
+ LOGV(">> android_media_AudioRecord_get_min_buff_size(%d, %d, %d)", sampleRateInHertz, nbChannels, audioFormat);
+
+ status_t result = AudioSystem::getInputBufferSize(
+ sampleRateInHertz,
+ (audioFormat == javaAudioRecordFields.PCM16 ?
+ AudioSystem::PCM_16_BIT : AudioSystem::PCM_8_BIT),
+ nbChannels, &inputBuffSize);
+ switch(result) {
+ case(NO_ERROR):
+ if(inputBuffSize == 0) {
+ LOGV("Recording parameters are not supported: %dHz, %d channel(s), (java) format %d",
+ sampleRateInHertz, nbChannels, audioFormat);
+ return 0;
+ } else {
+ // the minimum buffer size is twice the hardware input buffer size
+ return 2*inputBuffSize;
+ }
+ break;
+ case(PERMISSION_DENIED):
+ default:
+ return -1;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+static JNINativeMethod gMethods[] = {
+ // name, signature, funcPtr
+ {"native_start", "()V", (void *)android_media_AudioRecord_start},
+ {"native_stop", "()V", (void *)android_media_AudioRecord_stop},
+ {"native_setup", "(Ljava/lang/Object;IIIII)I",
+ (void *)android_media_AudioRecord_setup},
+ {"native_finalize", "()V", (void *)android_media_AudioRecord_finalize},
+ {"native_release", "()V", (void *)android_media_AudioRecord_release},
+ {"native_read_in_byte_array",
+ "([BII)I", (void *)android_media_AudioRecord_readInByteArray},
+ {"native_read_in_short_array",
+ "([SII)I", (void *)android_media_AudioRecord_readInShortArray},
+ {"native_read_in_direct_buffer","(Ljava/lang/Object;I)I",
+ (void *)android_media_AudioRecord_readInDirectBuffer},
+ {"native_set_marker_pos","(I)I", (void *)android_media_AudioRecord_set_marker_pos},
+ {"native_get_marker_pos","()I", (void *)android_media_AudioRecord_get_marker_pos},
+ {"native_set_pos_update_period",
+ "(I)I", (void *)android_media_AudioRecord_set_pos_update_period},
+ {"native_get_pos_update_period",
+ "()I", (void *)android_media_AudioRecord_get_pos_update_period},
+ {"native_get_min_buff_size",
+ "(III)I", (void *)android_media_AudioRecord_get_min_buff_size},
+};
+
+// field names found in android/media/AudioRecord.java
+#define JAVA_POSTEVENT_CALLBACK_NAME "postEventFromNative"
+#define JAVA_CONST_PCM16_NAME "ENCODING_PCM_16BIT"
+#define JAVA_CONST_PCM8_NAME "ENCODING_PCM_8BIT"
+#define JAVA_CONST_SOURCEDEFAULT_NAME "SOURCE_DEFAULT"
+#define JAVA_CONST_SOURCEMIC_NAME "SOURCE_MIC"
+#define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME "mNativeRecorderInJavaObj"
+#define JAVA_NATIVECALLBACKINFO_FIELD_NAME "mNativeCallbackCookie"
+
+#define JAVA_AUDIOFORMAT_CLASS_NAME "android/media/AudioFormat"
+
+// ----------------------------------------------------------------------------
+
+extern bool android_media_getIntConstantFromClass(JNIEnv* pEnv,
+ jclass theClass, const char* className, const char* constName, int* constVal);
+
+// ----------------------------------------------------------------------------
+int register_android_media_AudioRecord(JNIEnv *env)
+{
+ javaAudioRecordFields.audioRecordClass = NULL;
+ javaAudioRecordFields.postNativeEventInJava = NULL;
+ javaAudioRecordFields.nativeRecorderInJavaObj = NULL;
+ javaAudioRecordFields.nativeCallbackCookie = NULL;
+
+
+ // Get the AudioRecord class
+ javaAudioRecordFields.audioRecordClass = env->FindClass(kClassPathName);
+ if (javaAudioRecordFields.audioRecordClass == NULL) {
+ LOGE("Can't find %s", kClassPathName);
+ return -1;
+ }
+
+ // Get the postEvent method
+ javaAudioRecordFields.postNativeEventInJava = env->GetStaticMethodID(
+ javaAudioRecordFields.audioRecordClass,
+ JAVA_POSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+ if (javaAudioRecordFields.postNativeEventInJava == NULL) {
+ LOGE("Can't find AudioRecord.%s", JAVA_POSTEVENT_CALLBACK_NAME);
+ return -1;
+ }
+
+ // Get the variables
+ // mNativeRecorderInJavaObj
+ javaAudioRecordFields.nativeRecorderInJavaObj =
+ env->GetFieldID(javaAudioRecordFields.audioRecordClass,
+ JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME, "I");
+ if (javaAudioRecordFields.nativeRecorderInJavaObj == NULL) {
+ LOGE("Can't find AudioRecord.%s", JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME);
+ return -1;
+ }
+ // mNativeCallbackCookie
+ javaAudioRecordFields.nativeCallbackCookie = env->GetFieldID(
+ javaAudioRecordFields.audioRecordClass,
+ JAVA_NATIVECALLBACKINFO_FIELD_NAME, "I");
+ if (javaAudioRecordFields.nativeCallbackCookie == NULL) {
+ LOGE("Can't find AudioRecord.%s", JAVA_NATIVECALLBACKINFO_FIELD_NAME);
+ return -1;
+ }
+
+ // Get the format constants from the AudioFormat class
+ jclass audioFormatClass = NULL;
+ audioFormatClass = env->FindClass(JAVA_AUDIOFORMAT_CLASS_NAME);
+ if (audioFormatClass == NULL) {
+ LOGE("Can't find %s", JAVA_AUDIOFORMAT_CLASS_NAME);
+ return -1;
+ }
+ if ( !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_PCM16_NAME, &(javaAudioRecordFields.PCM16))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_PCM8_NAME, &(javaAudioRecordFields.PCM8)) ) {
+ // error log performed in getIntConstantFromClass()
+ return -1;
+ }
+
+ // Get the recording source constants from the AudioRecord class
+ if ( !android_media_getIntConstantFromClass(env, javaAudioRecordFields.audioRecordClass,
+ kClassPathName,
+ JAVA_CONST_SOURCEDEFAULT_NAME, &(javaAudioRecordFields.SOURCE_DEFAULT))
+ || !android_media_getIntConstantFromClass(env, javaAudioRecordFields.audioRecordClass,
+ kClassPathName,
+ JAVA_CONST_SOURCEMIC_NAME, &(javaAudioRecordFields.SOURCE_MIC)) ) {
+ // error log performed in getIntConstantFromClass()
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env,
+ kClassPathName, gMethods, NELEM(gMethods));
+}
+
+// ----------------------------------------------------------------------------