summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt3
-rw-r--r--core/jni/android_media_AudioFormat.h22
-rw-r--r--core/jni/android_media_AudioTrack.cpp27
-rw-r--r--media/java/android/media/AudioFormat.java53
-rw-r--r--media/java/android/media/AudioManager.java4
-rw-r--r--media/java/android/media/AudioTrack.java44
6 files changed, 106 insertions, 47 deletions
diff --git a/api/current.txt b/api/current.txt
index f6ccc67..65589d4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13739,7 +13739,9 @@ package android.media {
field public static final int CHANNEL_OUT_QUAD = 204; // 0xcc
field public static final int CHANNEL_OUT_STEREO = 12; // 0xc
field public static final int CHANNEL_OUT_SURROUND = 1052; // 0x41c
+ field public static final int ENCODING_AC3 = 5; // 0x5
field public static final int ENCODING_DEFAULT = 1; // 0x1
+ field public static final int ENCODING_E_AC3 = 6; // 0x6
field public static final int ENCODING_INVALID = 0; // 0x0
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
@@ -13813,6 +13815,7 @@ package android.media {
field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
field public static final int ERROR = -1; // 0xffffffff
+ field public static final int ERROR_DEAD_OBJECT = -6; // 0xfffffffa
field public static final java.lang.String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE";
field public static final java.lang.String EXTRA_SCO_AUDIO_PREVIOUS_STATE = "android.media.extra.SCO_AUDIO_PREVIOUS_STATE";
field public static final java.lang.String EXTRA_SCO_AUDIO_STATE = "android.media.extra.SCO_AUDIO_STATE";
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index a2b1ed9..807dd32 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -20,11 +20,15 @@
#include <system/audio.h>
// keep these values in sync with AudioFormat.java
-#define ENCODING_PCM_16BIT 2
-#define ENCODING_PCM_8BIT 3
-#define ENCODING_PCM_FLOAT 4
-#define ENCODING_INVALID 0
-#define ENCODING_DEFAULT 1
+#define ENCODING_PCM_16BIT 2
+#define ENCODING_PCM_8BIT 3
+#define ENCODING_PCM_FLOAT 4
+#define ENCODING_AC3 5
+#define ENCODING_E_AC3 6
+#define ENCODING_INVALID 0
+#define ENCODING_DEFAULT 1
+
+
#define CHANNEL_INVALID 0
#define CHANNEL_OUT_DEFAULT 1
@@ -38,6 +42,10 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
return AUDIO_FORMAT_PCM_8_BIT;
case ENCODING_PCM_FLOAT:
return AUDIO_FORMAT_PCM_FLOAT;
+ case ENCODING_AC3:
+ return AUDIO_FORMAT_AC3;
+ case ENCODING_E_AC3:
+ return AUDIO_FORMAT_E_AC3;
case ENCODING_DEFAULT:
return AUDIO_FORMAT_DEFAULT;
default:
@@ -54,6 +62,10 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
return ENCODING_PCM_8BIT;
case AUDIO_FORMAT_PCM_FLOAT:
return ENCODING_PCM_FLOAT;
+ case AUDIO_FORMAT_AC3:
+ return ENCODING_AC3;
+ case AUDIO_FORMAT_E_AC3:
+ return ENCODING_E_AC3;
case AUDIO_FORMAT_DEFAULT:
return ENCODING_DEFAULT;
default:
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index e548e91..264a9ae 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -220,8 +220,13 @@ android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
}
// compute the frame count
- const size_t bytesPerSample = audio_bytes_per_sample(format);
- size_t frameCount = buffSizeInBytes / (channelCount * bytesPerSample);
+ size_t frameCount;
+ if (audio_is_linear_pcm(format)) {
+ const size_t bytesPerSample = audio_bytes_per_sample(format);
+ frameCount = buffSizeInBytes / (channelCount * bytesPerSample);
+ } else {
+ frameCount = buffSizeInBytes;
+ }
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
@@ -266,7 +271,7 @@ android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
format,// word length, PCM
nativeChannelMask,
frameCount,
- AUDIO_OUTPUT_FLAG_NONE,
+ audio_is_linear_pcm(format) ? AUDIO_OUTPUT_FLAG_NONE : AUDIO_OUTPUT_FLAG_DIRECT,
audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
0,// shared mem
@@ -478,14 +483,6 @@ jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, const jbyte* da
switch (format) {
default:
- // TODO Currently the only possible values for format are AUDIO_FORMAT_PCM_16_BIT,
- // AUDIO_FORMAT_PCM_8_BIT, and AUDIO_FORMAT_PCM_FLOAT,
- // due to the limited set of values for audioFormat.
- // The next section of the switch will probably work for more formats, but it has only
- // been tested for AUDIO_FORMAT_PCM_16_BIT and AUDIO_FORMAT_PCM_FLOAT,
- // so that's why the "default" case fails.
- break;
-
case AUDIO_FORMAT_PCM_FLOAT:
case AUDIO_FORMAT_PCM_16_BIT: {
// writing to shared memory, check for capacity
@@ -904,8 +901,12 @@ static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thi
return -1;
}
const audio_format_t format = audioFormatToNative(audioFormat);
- const size_t bytesPerSample = audio_bytes_per_sample(format);
- return frameCount * channelCount * bytesPerSample;
+ if (audio_is_linear_pcm(format)) {
+ const size_t bytesPerSample = audio_bytes_per_sample(format);
+ return frameCount * channelCount * bytesPerSample;
+ } else {
+ return frameCount;
+ }
}
// ----------------------------------------------------------------------------
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index e05aef0..bd2be1b 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -25,10 +25,10 @@ import java.lang.annotation.RetentionPolicy;
* The AudioFormat class is used to access a number of audio format and
* channel configuration constants. They are for instance used
* in {@link AudioTrack} and {@link AudioRecord}.
- *
+ *
*/
public class AudioFormat {
-
+
//---------------------------------------------------------
// Constants
//--------------------
@@ -44,6 +44,10 @@ public class AudioFormat {
public static final int ENCODING_PCM_8BIT = 3;
/** Audio data format: single-precision floating-point per sample */
public static final int ENCODING_PCM_FLOAT = 4;
+ /** Audio data format: AC-3 compressed */
+ public static final int ENCODING_AC3 = 5;
+ /** Audio data format: E-AC-3 compressed */
+ public static final int ENCODING_E_AC3 = 6;
/** Invalid audio channel configuration */
/** @deprecated use CHANNEL_INVALID instead */
@@ -152,11 +156,44 @@ public class AudioFormat {
switch (audioFormat) {
case ENCODING_PCM_8BIT:
return 1;
+ case ENCODING_PCM_16BIT:
+ case ENCODING_DEFAULT:
+ return 2;
case ENCODING_PCM_FLOAT:
return 4;
+ case ENCODING_INVALID:
+ default:
+ throw new IllegalArgumentException("Bad audio format " + audioFormat);
+ }
+ }
+
+ /** @hide */
+ public static boolean isValidEncoding(int audioFormat)
+ {
+ switch (audioFormat) {
+ case ENCODING_PCM_8BIT:
case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_FLOAT:
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /** @hide */
+ public static boolean isEncodingLinearPcm(int audioFormat)
+ {
+ switch (audioFormat) {
+ case ENCODING_PCM_8BIT:
+ case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_FLOAT:
case ENCODING_DEFAULT:
- return 2;
+ return true;
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ return false;
case ENCODING_INVALID:
default:
throw new IllegalArgumentException("Bad audio format " + audioFormat);
@@ -236,7 +273,9 @@ public class AudioFormat {
* @param encoding one of {@link AudioFormat#ENCODING_DEFAULT},
* {@link AudioFormat#ENCODING_PCM_8BIT},
* {@link AudioFormat#ENCODING_PCM_16BIT},
- * {@link AudioFormat#ENCODING_PCM_FLOAT}.
+ * {@link AudioFormat#ENCODING_PCM_FLOAT},
+ * {@link AudioFormat#ENCODING_AC3},
+ * {@link AudioFormat#ENCODING_E_AC3}.
* @return the same Builder instance.
* @throws java.lang.IllegalArgumentException
*/
@@ -248,6 +287,8 @@ public class AudioFormat {
case ENCODING_PCM_8BIT:
case ENCODING_PCM_16BIT:
case ENCODING_PCM_FLOAT:
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
mEncoding = encoding;
break;
case ENCODING_INVALID:
@@ -311,7 +352,9 @@ public class AudioFormat {
ENCODING_DEFAULT,
ENCODING_PCM_8BIT,
ENCODING_PCM_16BIT,
- ENCODING_PCM_FLOAT
+ ENCODING_PCM_FLOAT,
+ ENCODING_AC3,
+ ENCODING_E_AC3
})
@Retention(RetentionPolicy.SOURCE)
public @interface Encoding {}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3238498..cf6d35e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2974,7 +2974,9 @@ public class AudioManager {
/** @hide
*/
public static final int ERROR_NO_INIT = AudioSystem.NO_INIT;
- /** @hide
+ /**
+ * An error code indicating that the object reporting it is no longer valid and needs to
+ * be recreated.
*/
public static final int ERROR_DEAD_OBJECT = AudioSystem.DEAD_OBJECT;
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index cfd9c3b..3a72833 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -457,25 +457,19 @@ public class AudioTrack
//--------------
// audio format
- switch (audioFormat) {
- case AudioFormat.ENCODING_DEFAULT:
- mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
- break;
- case AudioFormat.ENCODING_PCM_16BIT:
- case AudioFormat.ENCODING_PCM_8BIT:
- case AudioFormat.ENCODING_PCM_FLOAT:
- mAudioFormat = audioFormat;
- break;
- default:
- throw new IllegalArgumentException("Unsupported sample encoding."
- + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT"
- + " or ENCODING_PCM_FLOAT"
- + ".");
+ if (audioFormat == AudioFormat.ENCODING_DEFAULT) {
+ audioFormat = AudioFormat.ENCODING_PCM_16BIT;
+ }
+
+ if (!AudioFormat.isValidEncoding(audioFormat)) {
+ throw new IllegalArgumentException("Unsupported audio encoding.");
}
+ mAudioFormat = audioFormat;
//--------------
// audio load mode
- if ( (mode != MODE_STREAM) && (mode != MODE_STATIC) ) {
+ if (((mode != MODE_STREAM) && (mode != MODE_STATIC)) ||
+ ((mode != MODE_STREAM) && !AudioFormat.isEncodingLinearPcm(mAudioFormat))) {
throw new IllegalArgumentException("Invalid mode.");
}
mDataLoadMode = mode;
@@ -522,8 +516,13 @@ public class AudioTrack
private void audioBuffSizeCheck(int audioBufferSize) {
// NB: this section is only valid with PCM data.
// To update when supporting compressed formats
- int frameSizeInBytes = mChannelCount
- * (AudioFormat.getBytesPerSample(mAudioFormat));
+ int frameSizeInBytes;
+ if (AudioFormat.isEncodingLinearPcm(mAudioFormat)) {
+ frameSizeInBytes = mChannelCount
+ * (AudioFormat.getBytesPerSample(mAudioFormat));
+ } else {
+ frameSizeInBytes = 1;
+ }
if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
throw new IllegalArgumentException("Invalid audio buffer size.");
}
@@ -757,9 +756,7 @@ public class AudioTrack
}
}
- if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)
- && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)
- && (audioFormat != AudioFormat.ENCODING_PCM_FLOAT)) {
+ if (!AudioFormat.isValidEncoding(audioFormat)) {
loge("getMinBufferSize(): Invalid audio format.");
return ERROR_BAD_VALUE;
}
@@ -1164,7 +1161,9 @@ public class AudioTrack
* @param sizeInBytes the number of bytes to read in audioData after the offset.
* @return the number of bytes that were written or {@link #ERROR_INVALID_OPERATION}
* if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
- * the parameters don't resolve to valid data and indexes.
+ * the parameters don't resolve to valid data and indexes, or
+ * {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+ * needs to be recreated.
*/
public int write(byte[] audioData, int offsetInBytes, int sizeInBytes) {
@@ -1213,7 +1212,7 @@ public class AudioTrack
public int write(short[] audioData, int offsetInShorts, int sizeInShorts) {
- if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
+ if (mState == STATE_UNINITIALIZED || mAudioFormat != AudioFormat.ENCODING_PCM_16BIT) {
return ERROR_INVALID_OPERATION;
}
@@ -1473,7 +1472,6 @@ public class AudioTrack
void onPeriodicNotification(AudioTrack track);
}
-
//---------------------------------------------------------
// Inner classes
//--------------------