Loading core/jni/android_media_AudioRecord.cpp +39 −6 Original line number Diff line number Diff line Loading @@ -399,13 +399,46 @@ static jint android_media_AudioRecord_readInShortArray(JNIEnv *env, jobject thi jshortArray javaAudioData, jint offsetInShorts, jint sizeInShorts) { jint read = android_media_AudioRecord_readInByteArray(env, thiz, (jbyteArray) javaAudioData, offsetInShorts*2, sizeInShorts*2); if (read > 0) { read /= 2; jshort* recordBuff = NULL; // get the audio recorder from which we'll read new audio samples sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { ALOGE("Unable to retrieve AudioRecord object, can't record"); return 0; } return read; if (!javaAudioData) { ALOGE("Invalid Java array to store recorded audio, can't record"); return 0; } // get the pointer to where we'll record the audio // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such // a way that it becomes much more efficient. When doing so, we will have to prevent the // AudioSystem callback to be called while in critical section (in case of media server // process crash for instance) recordBuff = (jshort *)env->GetShortArrayElements(javaAudioData, NULL); if (recordBuff == NULL) { ALOGE("Error retrieving destination for recorded audio data, can't record"); return 0; } // read the new audio data from the native AudioRecord object const size_t recorderBuffSize = lpRecorder->frameCount()*lpRecorder->frameSize(); const size_t sizeInBytes = sizeInShorts * sizeof(short); ssize_t readSize = lpRecorder->read(recordBuff + offsetInShorts * sizeof(short), sizeInBytes > recorderBuffSize ? recorderBuffSize : sizeInBytes); env->ReleaseShortArrayElements(javaAudioData, recordBuff, 0); if (readSize < 0) { readSize = AUDIORECORD_ERROR_INVALID_OPERATION; } else { readSize /= sizeof(short); } return (jint) readSize; } // ---------------------------------------------------------------------------- Loading core/jni/android_media_AudioTrack.cpp +31 −5 Original line number Diff line number Diff line Loading @@ -595,13 +595,39 @@ static jint android_media_AudioTrack_native_write_short(JNIEnv *env, jobject th jshortArray javaAudioData, jint offsetInShorts, jint sizeInShorts, jint javaAudioFormat) { jint written = android_media_AudioTrack_native_write_byte(env, thiz, (jbyteArray) javaAudioData, offsetInShorts*2, sizeInShorts*2, javaAudioFormat); sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioTrack pointer for write()"); return 0; } // get the pointer for the audio data from the java array // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such // a way that it becomes much more efficient. When doing so, we will have to prevent the // AudioSystem callback to be called while in critical section (in case of media server // process crash for instance) jshort* cAudioData = NULL; if (javaAudioData) { cAudioData = (jshort *)env->GetShortArrayElements(javaAudioData, NULL); if (cAudioData == NULL) { ALOGE("Error retrieving source of audio data to play, can't play"); return 0; // out of memory or no data to load } } else { ALOGE("NULL java array of audio data to play, can't play"); return 0; } jint written = writeToTrack(lpTrack, javaAudioFormat, (jbyte *)cAudioData, offsetInShorts * sizeof(short), sizeInShorts * sizeof(short)); env->ReleaseShortArrayElements(javaAudioData, cAudioData, 0); if (written > 0) { written /= 2; written /= sizeof(short); } //ALOGV("write wrote %d (tried %d) shorts in the native AudioTrack with offset %d", // (int)written, (int)(sizeInShorts), (int)offsetInShorts); return written; } Loading Loading
core/jni/android_media_AudioRecord.cpp +39 −6 Original line number Diff line number Diff line Loading @@ -399,13 +399,46 @@ static jint android_media_AudioRecord_readInShortArray(JNIEnv *env, jobject thi jshortArray javaAudioData, jint offsetInShorts, jint sizeInShorts) { jint read = android_media_AudioRecord_readInByteArray(env, thiz, (jbyteArray) javaAudioData, offsetInShorts*2, sizeInShorts*2); if (read > 0) { read /= 2; jshort* recordBuff = NULL; // get the audio recorder from which we'll read new audio samples sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { ALOGE("Unable to retrieve AudioRecord object, can't record"); return 0; } return read; if (!javaAudioData) { ALOGE("Invalid Java array to store recorded audio, can't record"); return 0; } // get the pointer to where we'll record the audio // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such // a way that it becomes much more efficient. When doing so, we will have to prevent the // AudioSystem callback to be called while in critical section (in case of media server // process crash for instance) recordBuff = (jshort *)env->GetShortArrayElements(javaAudioData, NULL); if (recordBuff == NULL) { ALOGE("Error retrieving destination for recorded audio data, can't record"); return 0; } // read the new audio data from the native AudioRecord object const size_t recorderBuffSize = lpRecorder->frameCount()*lpRecorder->frameSize(); const size_t sizeInBytes = sizeInShorts * sizeof(short); ssize_t readSize = lpRecorder->read(recordBuff + offsetInShorts * sizeof(short), sizeInBytes > recorderBuffSize ? recorderBuffSize : sizeInBytes); env->ReleaseShortArrayElements(javaAudioData, recordBuff, 0); if (readSize < 0) { readSize = AUDIORECORD_ERROR_INVALID_OPERATION; } else { readSize /= sizeof(short); } return (jint) readSize; } // ---------------------------------------------------------------------------- Loading
core/jni/android_media_AudioTrack.cpp +31 −5 Original line number Diff line number Diff line Loading @@ -595,13 +595,39 @@ static jint android_media_AudioTrack_native_write_short(JNIEnv *env, jobject th jshortArray javaAudioData, jint offsetInShorts, jint sizeInShorts, jint javaAudioFormat) { jint written = android_media_AudioTrack_native_write_byte(env, thiz, (jbyteArray) javaAudioData, offsetInShorts*2, sizeInShorts*2, javaAudioFormat); sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioTrack pointer for write()"); return 0; } // get the pointer for the audio data from the java array // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such // a way that it becomes much more efficient. When doing so, we will have to prevent the // AudioSystem callback to be called while in critical section (in case of media server // process crash for instance) jshort* cAudioData = NULL; if (javaAudioData) { cAudioData = (jshort *)env->GetShortArrayElements(javaAudioData, NULL); if (cAudioData == NULL) { ALOGE("Error retrieving source of audio data to play, can't play"); return 0; // out of memory or no data to load } } else { ALOGE("NULL java array of audio data to play, can't play"); return 0; } jint written = writeToTrack(lpTrack, javaAudioFormat, (jbyte *)cAudioData, offsetInShorts * sizeof(short), sizeInShorts * sizeof(short)); env->ReleaseShortArrayElements(javaAudioData, cAudioData, 0); if (written > 0) { written /= 2; written /= sizeof(short); } //ALOGV("write wrote %d (tried %d) shorts in the native AudioTrack with offset %d", // (int)written, (int)(sizeInShorts), (int)offsetInShorts); return written; } Loading