diff options
author | Eric Laurent <elaurent@google.com> | 2009-07-17 12:17:14 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2009-07-23 06:03:39 -0700 |
commit | a553c25b33c99b345cf1c8688f8df0ed8df14e5a (patch) | |
tree | 025c461b13e66ad0ceac8d0f8d9b13fd88ae168a /core/jni | |
parent | ebd7bc54028949619bbf3fa5ed6c1188f588c230 (diff) | |
download | frameworks_base-a553c25b33c99b345cf1c8688f8df0ed8df14e5a.zip frameworks_base-a553c25b33c99b345cf1c8688f8df0ed8df14e5a.tar.gz frameworks_base-a553c25b33c99b345cf1c8688f8df0ed8df14e5a.tar.bz2 |
Fix issue 1795088 Improve audio routing code
Initial commit for review.
Integrated comments after patch set 1 review.
Fixed lockup in AudioFlinger::ThreadBase::exit()
Fixed lockup when playing tone with AudioPlocyService startTone()
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/android_media_AudioRecord.cpp | 26 | ||||
-rw-r--r-- | core/jni/android_media_AudioSystem.cpp | 166 | ||||
-rw-r--r-- | core/jni/android_media_AudioTrack.cpp | 29 |
3 files changed, 125 insertions, 96 deletions
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index 44a9e8c..0be996d 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -28,8 +28,8 @@ #include "android_runtime/AndroidRuntime.h" #include "utils/Log.h" -#include "media/AudioSystem.h" #include "media/AudioRecord.h" +#include "media/mediarecorder.h" // ---------------------------------------------------------------------------- @@ -62,7 +62,7 @@ struct audiorecord_callback_cookie { #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_INVALIDCHANNELMASK -17 #define AUDIORECORD_ERROR_SETUP_INVALIDFORMAT -18 #define AUDIORECORD_ERROR_SETUP_INVALIDSOURCE -19 #define AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED -20 @@ -122,17 +122,18 @@ static void recorderCallback(int event, void* user, void *info) { // ---------------------------------------------------------------------------- static int android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this, - jint source, jint sampleRateInHertz, jint nbChannels, + jint source, jint sampleRateInHertz, jint channels, jint audioFormat, jint buffSizeInBytes) { //LOGV(">> Entering android_media_AudioRecord_setup"); - //LOGV("sampleRate=%d, audioFormat=%d, nbChannels=%d, buffSizeInBytes=%d", - // sampleRateInHertz, audioFormat, nbChannels, buffSizeInBytes); + //LOGV("sampleRate=%d, audioFormat=%d, channels=%x, buffSizeInBytes=%d", + // sampleRateInHertz, audioFormat, channels, buffSizeInBytes); - if ((nbChannels == 0) || (nbChannels > 2)) { + if (!AudioSystem::isInputChannel(channels)) { LOGE("Error creating AudioRecord: channel count is not 1 or 2."); - return AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT; + return AUDIORECORD_ERROR_SETUP_INVALIDCHANNELMASK; } + uint32_t nbChannels = AudioSystem::popCount(channels); // compare the format against the Java constants if ((audioFormat != javaAudioRecordFields.PCM16) @@ -152,12 +153,7 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this, int frameSize = nbChannels * bytesPerSample; size_t frameCount = buffSizeInBytes / frameSize; - // convert and check input source value - // input_source values defined in AudioRecord.h are equal to - // JAVA MediaRecord.AudioSource values minus 1. - AudioRecord::input_source arSource = (AudioRecord::input_source)(source - 1); - if (arSource < AudioRecord::DEFAULT_INPUT || - arSource >= AudioRecord::NUM_INPUT_SOURCES) { + if (source >= AUDIO_SOURCE_LIST_END) { LOGE("Error creating AudioRecord: unknown source."); return AUDIORECORD_ERROR_SETUP_INVALIDSOURCE; } @@ -184,10 +180,10 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this, // we use a weak reference so the AudioRecord object can be garbage collected. lpCallbackData->audioRecord_ref = env->NewGlobalRef(weak_this); - lpRecorder->set(arSource, + lpRecorder->set(source, sampleRateInHertz, format, // word length, PCM - nbChannels, + channels, frameCount, 0, // flags recorderCallback,// callback_t diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 692610e..3d8d296 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -50,25 +50,6 @@ static int check_AudioSystem_Command(status_t status) } static int -android_media_AudioSystem_setVolume(JNIEnv *env, jobject clazz, jint type, jint volume) -{ - LOGV("setVolume(%d)", int(volume)); - - return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, AudioSystem::linearToLog(volume))); -} - -static int -android_media_AudioSystem_getVolume(JNIEnv *env, jobject clazz, jint type) -{ - float v; - int v_int = -1; - if (AudioSystem::getStreamVolume(int(type), &v) == NO_ERROR) { - v_int = AudioSystem::logToLinear(v); - } - return v_int; -} - -static int android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on) { return check_AudioSystem_Command(AudioSystem::muteMicrophone(on)); @@ -82,34 +63,6 @@ android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz) return state; } -static int -android_media_AudioSystem_setRouting(JNIEnv *env, jobject clazz, jint mode, jint routes, jint mask) -{ - return check_AudioSystem_Command(AudioSystem::setRouting(mode, uint32_t(routes), uint32_t(mask))); -} - -static jint -android_media_AudioSystem_getRouting(JNIEnv *env, jobject clazz, jint mode) -{ - uint32_t routes = -1; - AudioSystem::getRouting(mode, &routes); - return jint(routes); -} - -static int -android_media_AudioSystem_setMode(JNIEnv *env, jobject clazz, jint mode) -{ - return check_AudioSystem_Command(AudioSystem::setMode(mode)); -} - -static jint -android_media_AudioSystem_getMode(JNIEnv *env, jobject clazz) -{ - int mode = AudioSystem::MODE_INVALID; - AudioSystem::getMode(&mode); - return jint(mode); -} - static jboolean android_media_AudioSystem_isMusicActive(JNIEnv *env, jobject thiz) { @@ -118,16 +71,29 @@ android_media_AudioSystem_isMusicActive(JNIEnv *env, jobject thiz) return state; } -// Temporary interface, do not use -// TODO: Replace with a more generic key:value get/set mechanism -static void -android_media_AudioSystem_setParameter(JNIEnv *env, jobject thiz, jstring key, jstring value) +static int +android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs) { - const char *c_key = env->GetStringUTFChars(key, NULL); - const char *c_value = env->GetStringUTFChars(value, NULL); - AudioSystem::setParameter(c_key, c_value); - env->ReleaseStringUTFChars(key, c_key); - env->ReleaseStringUTFChars(value, c_value); + const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0); + String8 c_keyValuePairs8; + if (keyValuePairs) { + c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs)); + env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs); + } + int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8)); + return status; +} + +static jstring +android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys) +{ + const jchar* c_keys = env->GetStringCritical(keys, 0); + String8 c_keys8; + if (keys) { + c_keys8 = String8(c_keys, env->GetStringLength(keys)); + env->ReleaseStringCritical(keys, c_keys); + } + return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string()); } void android_media_AudioSystem_error_callback(status_t err) @@ -152,19 +118,93 @@ void android_media_AudioSystem_error_callback(status_t err) env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error); } +static int +android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address) +{ + const char *c_address = env->GetStringUTFChars(device_address, NULL); + int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <AudioSystem::audio_devices>(device), + static_cast <AudioSystem::device_connection_state>(state), + c_address)); + env->ReleaseStringUTFChars(device_address, c_address); + return status; +} + +static int +android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address) +{ + const char *c_address = env->GetStringUTFChars(device_address, NULL); + int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <AudioSystem::audio_devices>(device), + c_address)); + env->ReleaseStringUTFChars(device_address, c_address); + return state; +} + +static int +android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state) +{ + return check_AudioSystem_Command(AudioSystem::setPhoneState(state)); +} + +static int +android_media_AudioSystem_setRingerMode(JNIEnv *env, jobject thiz, jint mode, jint mask) +{ + return check_AudioSystem_Command(AudioSystem::setRingerMode(mode, mask)); +} + +static int +android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config) +{ + return check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <AudioSystem::force_use>(usage), + static_cast <AudioSystem::forced_config>(config))); +} + +static int +android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage) +{ + return static_cast <int>(AudioSystem::getForceUse(static_cast <AudioSystem::force_use>(usage))); +} + +static int +android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax) +{ + return check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <AudioSystem::stream_type>(stream), + indexMin, + indexMax)); +} + +static int +android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream, jint index) +{ + return check_AudioSystem_Command(AudioSystem::setStreamVolumeIndex(static_cast <AudioSystem::stream_type>(stream), index)); +} + +static int +android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream) +{ + int index; + if (AudioSystem::getStreamVolumeIndex(static_cast <AudioSystem::stream_type>(stream), &index) != NO_ERROR) { + index = -1; + } + return index; +} + // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { - {"setVolume", "(II)I", (void *)android_media_AudioSystem_setVolume}, - {"getVolume", "(I)I", (void *)android_media_AudioSystem_getVolume}, - {"setParameter", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)android_media_AudioSystem_setParameter}, + {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters}, + {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters}, {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone}, {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted}, - {"setRouting", "(III)I", (void *)android_media_AudioSystem_setRouting}, - {"getRouting", "(I)I", (void *)android_media_AudioSystem_getRouting}, - {"setMode", "(I)I", (void *)android_media_AudioSystem_setMode}, - {"getMode", "()I", (void *)android_media_AudioSystem_getMode}, {"isMusicActive", "()Z", (void *)android_media_AudioSystem_isMusicActive}, + {"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState}, + {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState}, + {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState}, + {"setRingerMode", "(II)I", (void *)android_media_AudioSystem_setRingerMode}, + {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse}, + {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse}, + {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume}, + {"setStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_setStreamVolumeIndex}, + {"getStreamVolumeIndex","(I)I", (void *)android_media_AudioSystem_getStreamVolumeIndex} }; const char* const kClassPathName = "android/media/AudioSystem"; diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index bc7f3f5..6449147 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -103,7 +103,7 @@ class AudioTrackJniStorage { #define AUDIOTRACK_ERROR_BAD_VALUE -2 #define AUDIOTRACK_ERROR_INVALID_OPERATION -3 #define AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM -16 -#define AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELCOUNT -17 +#define AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK -17 #define AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT -18 #define AUDIOTRACK_ERROR_SETUP_INVALIDSTREAMTYPE -19 #define AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED -20 @@ -164,11 +164,11 @@ static void audioCallback(int event, void* user, void *info) { // ---------------------------------------------------------------------------- static int android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, - jint streamType, jint sampleRateInHertz, jint nbChannels, + jint streamType, jint sampleRateInHertz, jint channels, jint audioFormat, jint buffSizeInBytes, jint memoryMode) { - LOGV("sampleRate=%d, audioFormat(from Java)=%d, nbChannels=%d, buffSize=%d", - sampleRateInHertz, audioFormat, nbChannels, buffSizeInBytes); + LOGV("sampleRate=%d, audioFormat(from Java)=%d, channels=%x, buffSize=%d", + sampleRateInHertz, audioFormat, channels, buffSizeInBytes); int afSampleRate; int afFrameCount; @@ -181,10 +181,11 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th return AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM; } - if ((nbChannels == 0) || (nbChannels > 2)) { - LOGE("Error creating AudioTrack: channel count is not 1 or 2."); - return AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELCOUNT; + if (!AudioSystem::isOutputChannel(channels)) { + LOGE("Error creating AudioTrack: invalid channel mask."); + return AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK; } + int nbChannels = AudioSystem::popCount(channels); // check the stream type AudioSystem::stream_type atStreamType; @@ -231,15 +232,7 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th int bytesPerSample = audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1; int format = audioFormat == javaAudioTrackFields.PCM16 ? AudioSystem::PCM_16_BIT : AudioSystem::PCM_8_BIT; - int frameCount; - if (buffSizeInBytes == -1) { - // compute the frame count based on the system's output frame count - // and the native sample rate - frameCount = (sampleRateInHertz*afFrameCount)/afSampleRate; - } else { - // compute the frame count based on the specified buffer size - frameCount = buffSizeInBytes / (nbChannels * bytesPerSample); - } + int frameCount = buffSizeInBytes / (nbChannels * bytesPerSample); AudioTrackJniStorage* lpJniStorage = new AudioTrackJniStorage(); @@ -271,7 +264,7 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th atStreamType,// stream type sampleRateInHertz, format,// word length, PCM - nbChannels, + channels, frameCount, 0,// flags audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user) @@ -291,7 +284,7 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th atStreamType,// stream type sampleRateInHertz, format,// word length, PCM - nbChannels, + channels, frameCount, 0,// flags audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)); |