Loading core/jni/android_media_AudioTrack.cpp +25 −13 Original line number Diff line number Diff line Loading @@ -189,32 +189,44 @@ sp<AudioTrack> android_media_AudioTrack_getAudioTrack(JNIEnv* env, jobject audio return getAudioTrack(env, audioTrackObj); } // This function converts Java channel masks to a native channel mask. // validity should be checked with audio_is_output_channel(). static inline audio_channel_mask_t nativeChannelMaskFromJavaChannelMasks( jint channelPositionMask, jint channelIndexMask) { if (channelIndexMask != 0) { // channel index mask takes priority // To convert to a native channel mask, the Java channel index mask // requires adding the index representation. return audio_channel_mask_from_representation_and_bits( AUDIO_CHANNEL_REPRESENTATION_INDEX, channelIndexMask); } // To convert to a native channel mask, the Java channel position mask // requires a shift by 2 to skip the two deprecated channel // configurations "default" and "mono". return (audio_channel_mask_t)(channelPositionMask >> 2); } // ---------------------------------------------------------------------------- static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this, jobject jaa, jint sampleRateInHertz, jint javaChannelMask, jint sampleRateInHertz, jint channelPositionMask, jint channelIndexMask, jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession) { ALOGV("sampleRate=%d, audioFormat(from Java)=%d, channel mask=%x, buffSize=%d", sampleRateInHertz, audioFormat, javaChannelMask, buffSizeInBytes); ALOGV("sampleRate=%d, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d", sampleRateInHertz, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes); if (jaa == 0) { ALOGE("Error creating AudioTrack: invalid audio attributes"); return (jint) AUDIO_JAVA_ERROR; } // Java channel masks don't map directly to the native definition for positional // channel masks: it's a shift by 2 to skip the two deprecated channel // configurations "default" and "mono". // Invalid channel representations are caught by !audio_is_output_channel() below. audio_channel_mask_t nativeChannelMask = audio_channel_mask_get_representation(javaChannelMask) == AUDIO_CHANNEL_REPRESENTATION_POSITION ? javaChannelMask >> 2 : javaChannelMask; audio_channel_mask_t nativeChannelMask = nativeChannelMaskFromJavaChannelMasks( channelPositionMask, channelIndexMask); if (!audio_is_output_channel(nativeChannelMask)) { ALOGE("Error creating AudioTrack: invalid channel mask %#x.", javaChannelMask); ALOGE("Error creating AudioTrack: invalid native channel mask %#x.", nativeChannelMask); return (jint) AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK; } Loading Loading @@ -982,7 +994,7 @@ static JNINativeMethod gMethods[] = { {"native_stop", "()V", (void *)android_media_AudioTrack_stop}, {"native_pause", "()V", (void *)android_media_AudioTrack_pause}, {"native_flush", "()V", (void *)android_media_AudioTrack_flush}, {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;IIIII[I)I", {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;IIIIII[I)I", (void *)android_media_AudioTrack_setup}, {"native_finalize", "()V", (void *)android_media_AudioTrack_finalize}, {"native_release", "()V", (void *)android_media_AudioTrack_release}, Loading media/java/android/media/AudioTrack.java +2 −49 Original line number Diff line number Diff line Loading @@ -491,7 +491,7 @@ public class AudioTrack session[0] = sessionId; // native initialization int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes, mSampleRate, mChannels, mAudioFormat, mSampleRate, mChannels, mChannelIndexMask, mAudioFormat, mNativeBufferSizeInBytes, mDataLoadMode, session); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); Loading Loading @@ -701,48 +701,6 @@ public class AudioTrack AudioFormat.CHANNEL_OUT_SIDE_LEFT | AudioFormat.CHANNEL_OUT_SIDE_RIGHT; // Java channel mask definitions below match those // in /system/core/include/system/audio.h in the JNI code of AudioTrack. // internal maximum size for bits parameter, not part of public API private static final int AUDIO_CHANNEL_BITS_LOG2 = 30; // log(2) of maximum number of representations, not part of public API private static final int AUDIO_CHANNEL_REPRESENTATION_LOG2 = 2; // used to create a channel index mask or channel position mask // with getChannelMaskFromRepresentationAndBits(); private static final int CHANNEL_OUT_REPRESENTATION_POSITION = 0; private static final int CHANNEL_OUT_REPRESENTATION_INDEX = 2; /** * Return the channel mask from its representation and bits. * * This creates a channel mask for mChannels which combines a * representation field and a bits field. This is for internal * communication to native code, not part of the public API. * * @param representation the type of channel mask, * either CHANNEL_OUT_REPRESENTATION_POSITION * or CHANNEL_OUT_REPRESENTATION_INDEX * @param bits is the channel bits specifying occupancy * @return the channel mask * @throws java.lang.IllegalArgumentException if representation is not recognized or * the bits field is not acceptable for that representation */ private static int getChannelMaskFromRepresentationAndBits(int representation, int bits) { switch (representation) { case CHANNEL_OUT_REPRESENTATION_POSITION: case CHANNEL_OUT_REPRESENTATION_INDEX: if ((bits & ~((1 << AUDIO_CHANNEL_BITS_LOG2) - 1)) != 0) { throw new IllegalArgumentException("invalid bits " + bits); } return representation << AUDIO_CHANNEL_BITS_LOG2 | bits; default: throw new IllegalArgumentException("invalid representation " + representation); } } // Convenience method for the constructor's parameter checks. // This is where constructor IllegalArgumentException-s are thrown // postconditions: Loading Loading @@ -804,11 +762,6 @@ public class AudioTrack } else if (mChannelCount != channelIndexCount) { throw new IllegalArgumentException("Channel count must match"); } // AudioTrack prefers to use the channel index configuration // over the channel position configuration if both are specified. mChannels = getChannelMaskFromRepresentationAndBits( CHANNEL_OUT_REPRESENTATION_INDEX, mChannelIndexMask); } //-------------- Loading Loading @@ -2362,7 +2315,7 @@ public class AudioTrack // AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this, Object /*AudioAttributes*/ attributes, int sampleRate, int channelMask, int audioFormat, int sampleRate, int channelMask, int channelIndexMask, int audioFormat, int buffSizeInBytes, int mode, int[] sessionId); private native final void native_finalize(); Loading Loading
core/jni/android_media_AudioTrack.cpp +25 −13 Original line number Diff line number Diff line Loading @@ -189,32 +189,44 @@ sp<AudioTrack> android_media_AudioTrack_getAudioTrack(JNIEnv* env, jobject audio return getAudioTrack(env, audioTrackObj); } // This function converts Java channel masks to a native channel mask. // validity should be checked with audio_is_output_channel(). static inline audio_channel_mask_t nativeChannelMaskFromJavaChannelMasks( jint channelPositionMask, jint channelIndexMask) { if (channelIndexMask != 0) { // channel index mask takes priority // To convert to a native channel mask, the Java channel index mask // requires adding the index representation. return audio_channel_mask_from_representation_and_bits( AUDIO_CHANNEL_REPRESENTATION_INDEX, channelIndexMask); } // To convert to a native channel mask, the Java channel position mask // requires a shift by 2 to skip the two deprecated channel // configurations "default" and "mono". return (audio_channel_mask_t)(channelPositionMask >> 2); } // ---------------------------------------------------------------------------- static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this, jobject jaa, jint sampleRateInHertz, jint javaChannelMask, jint sampleRateInHertz, jint channelPositionMask, jint channelIndexMask, jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession) { ALOGV("sampleRate=%d, audioFormat(from Java)=%d, channel mask=%x, buffSize=%d", sampleRateInHertz, audioFormat, javaChannelMask, buffSizeInBytes); ALOGV("sampleRate=%d, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d", sampleRateInHertz, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes); if (jaa == 0) { ALOGE("Error creating AudioTrack: invalid audio attributes"); return (jint) AUDIO_JAVA_ERROR; } // Java channel masks don't map directly to the native definition for positional // channel masks: it's a shift by 2 to skip the two deprecated channel // configurations "default" and "mono". // Invalid channel representations are caught by !audio_is_output_channel() below. audio_channel_mask_t nativeChannelMask = audio_channel_mask_get_representation(javaChannelMask) == AUDIO_CHANNEL_REPRESENTATION_POSITION ? javaChannelMask >> 2 : javaChannelMask; audio_channel_mask_t nativeChannelMask = nativeChannelMaskFromJavaChannelMasks( channelPositionMask, channelIndexMask); if (!audio_is_output_channel(nativeChannelMask)) { ALOGE("Error creating AudioTrack: invalid channel mask %#x.", javaChannelMask); ALOGE("Error creating AudioTrack: invalid native channel mask %#x.", nativeChannelMask); return (jint) AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK; } Loading Loading @@ -982,7 +994,7 @@ static JNINativeMethod gMethods[] = { {"native_stop", "()V", (void *)android_media_AudioTrack_stop}, {"native_pause", "()V", (void *)android_media_AudioTrack_pause}, {"native_flush", "()V", (void *)android_media_AudioTrack_flush}, {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;IIIII[I)I", {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;IIIIII[I)I", (void *)android_media_AudioTrack_setup}, {"native_finalize", "()V", (void *)android_media_AudioTrack_finalize}, {"native_release", "()V", (void *)android_media_AudioTrack_release}, Loading
media/java/android/media/AudioTrack.java +2 −49 Original line number Diff line number Diff line Loading @@ -491,7 +491,7 @@ public class AudioTrack session[0] = sessionId; // native initialization int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes, mSampleRate, mChannels, mAudioFormat, mSampleRate, mChannels, mChannelIndexMask, mAudioFormat, mNativeBufferSizeInBytes, mDataLoadMode, session); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); Loading Loading @@ -701,48 +701,6 @@ public class AudioTrack AudioFormat.CHANNEL_OUT_SIDE_LEFT | AudioFormat.CHANNEL_OUT_SIDE_RIGHT; // Java channel mask definitions below match those // in /system/core/include/system/audio.h in the JNI code of AudioTrack. // internal maximum size for bits parameter, not part of public API private static final int AUDIO_CHANNEL_BITS_LOG2 = 30; // log(2) of maximum number of representations, not part of public API private static final int AUDIO_CHANNEL_REPRESENTATION_LOG2 = 2; // used to create a channel index mask or channel position mask // with getChannelMaskFromRepresentationAndBits(); private static final int CHANNEL_OUT_REPRESENTATION_POSITION = 0; private static final int CHANNEL_OUT_REPRESENTATION_INDEX = 2; /** * Return the channel mask from its representation and bits. * * This creates a channel mask for mChannels which combines a * representation field and a bits field. This is for internal * communication to native code, not part of the public API. * * @param representation the type of channel mask, * either CHANNEL_OUT_REPRESENTATION_POSITION * or CHANNEL_OUT_REPRESENTATION_INDEX * @param bits is the channel bits specifying occupancy * @return the channel mask * @throws java.lang.IllegalArgumentException if representation is not recognized or * the bits field is not acceptable for that representation */ private static int getChannelMaskFromRepresentationAndBits(int representation, int bits) { switch (representation) { case CHANNEL_OUT_REPRESENTATION_POSITION: case CHANNEL_OUT_REPRESENTATION_INDEX: if ((bits & ~((1 << AUDIO_CHANNEL_BITS_LOG2) - 1)) != 0) { throw new IllegalArgumentException("invalid bits " + bits); } return representation << AUDIO_CHANNEL_BITS_LOG2 | bits; default: throw new IllegalArgumentException("invalid representation " + representation); } } // Convenience method for the constructor's parameter checks. // This is where constructor IllegalArgumentException-s are thrown // postconditions: Loading Loading @@ -804,11 +762,6 @@ public class AudioTrack } else if (mChannelCount != channelIndexCount) { throw new IllegalArgumentException("Channel count must match"); } // AudioTrack prefers to use the channel index configuration // over the channel position configuration if both are specified. mChannels = getChannelMaskFromRepresentationAndBits( CHANNEL_OUT_REPRESENTATION_INDEX, mChannelIndexMask); } //-------------- Loading Loading @@ -2362,7 +2315,7 @@ public class AudioTrack // AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this, Object /*AudioAttributes*/ attributes, int sampleRate, int channelMask, int audioFormat, int sampleRate, int channelMask, int channelIndexMask, int audioFormat, int buffSizeInBytes, int mode, int[] sessionId); private native final void native_finalize(); Loading