Merge "AudioFormat: Add ENCODING_PCM_32BIT ENCODING_PCM_24BIT_PACKED" am: e468f6c151 am: 32010fbba7
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1670486 Change-Id: I1b3354768d9ed8539459c48f5bb1a051cc9ebf24
This commit is contained in:
@@ -19386,6 +19386,8 @@ package android.media {
|
||||
field public static final int ENCODING_MP3 = 9; // 0x9
|
||||
field public static final int ENCODING_OPUS = 20; // 0x14
|
||||
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
|
||||
field public static final int ENCODING_PCM_24BIT_PACKED = 21; // 0x15
|
||||
field public static final int ENCODING_PCM_32BIT = 22; // 0x16
|
||||
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
|
||||
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
||||
field public static final int SAMPLE_RATE_UNSPECIFIED = 0; // 0x0
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#define ENCODING_E_AC3_JOC 18
|
||||
#define ENCODING_DOLBY_MAT 19
|
||||
#define ENCODING_OPUS 20
|
||||
#define ENCODING_PCM_24BIT_PACKED 21
|
||||
#define ENCODING_PCM_32BIT 22
|
||||
|
||||
#define ENCODING_INVALID 0
|
||||
#define ENCODING_DEFAULT 1
|
||||
@@ -92,6 +94,10 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
|
||||
return AUDIO_FORMAT_MAT;
|
||||
case ENCODING_OPUS:
|
||||
return AUDIO_FORMAT_OPUS;
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
return AUDIO_FORMAT_PCM_24_BIT_PACKED;
|
||||
case ENCODING_PCM_32BIT:
|
||||
return AUDIO_FORMAT_PCM_32_BIT;
|
||||
default:
|
||||
return AUDIO_FORMAT_INVALID;
|
||||
}
|
||||
@@ -107,10 +113,15 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
|
||||
case AUDIO_FORMAT_PCM_FLOAT:
|
||||
return ENCODING_PCM_FLOAT;
|
||||
|
||||
// map these to ENCODING_PCM_FLOAT
|
||||
case AUDIO_FORMAT_PCM_8_24_BIT:
|
||||
// As of S, these extend integer precision formats now return more specific values
|
||||
// than ENCODING_PCM_FLOAT.
|
||||
case AUDIO_FORMAT_PCM_24_BIT_PACKED:
|
||||
return ENCODING_PCM_24BIT_PACKED;
|
||||
case AUDIO_FORMAT_PCM_32_BIT:
|
||||
return ENCODING_PCM_32BIT;
|
||||
|
||||
// map this to ENCODING_PCM_FLOAT
|
||||
case AUDIO_FORMAT_PCM_8_24_BIT:
|
||||
return ENCODING_PCM_FLOAT;
|
||||
|
||||
case AUDIO_FORMAT_AC3:
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.util.SparseIntArray;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@@ -467,9 +468,32 @@ public final class AudioDeviceInfo {
|
||||
* @see AudioFormat
|
||||
*
|
||||
* Note: an empty array indicates that the device supports arbitrary encodings.
|
||||
* For forward compatibility, applications should ignore entries it does not recognize.
|
||||
*/
|
||||
public @NonNull int[] getEncodings() {
|
||||
return AudioFormat.filterPublicFormats(mPort.formats());
|
||||
final int[] encodings = AudioFormat.filterPublicFormats(mPort.formats());
|
||||
boolean hasFloat = false;
|
||||
boolean hasExtendedIntegerPrecision = false;
|
||||
|
||||
for (int encoding : encodings) {
|
||||
if (AudioFormat.isEncodingLinearPcm(encoding)) {
|
||||
if (encoding == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||
hasFloat = true;
|
||||
} else if (AudioFormat.getBytesPerSample(encoding) > 2) {
|
||||
hasExtendedIntegerPrecision = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasExtendedIntegerPrecision && !hasFloat) {
|
||||
// R and earlier compatibility - add ENCODING_PCM_FLOAT to the end
|
||||
// (replacing the zero pad). This ensures pre-S apps that look
|
||||
// for ENCODING_PCM_FLOAT continue to see that encoding if the device supports
|
||||
// extended precision integers.
|
||||
int[] encodingsPlusFloat = Arrays.copyOf(encodings, encodings.length + 1);
|
||||
encodingsPlusFloat[encodings.length] = AudioFormat.ENCODING_PCM_FLOAT;
|
||||
return encodingsPlusFloat;
|
||||
}
|
||||
return encodings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,6 +110,24 @@ import java.util.Objects;
|
||||
* <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP}
|
||||
* support <code>ENCODING_PCM_FLOAT</code>.
|
||||
* </li>
|
||||
* <li> {@link #ENCODING_PCM_24BIT_PACKED}: Introduced in
|
||||
* API {@link android.os.Build.VERSION_CODES#S},
|
||||
* this encoding specifies the audio sample is an
|
||||
* extended precision 24 bit signed integer
|
||||
* stored as a 3 Java bytes in a {@code ByteBuffer} or byte array in native endian
|
||||
* (see {@link java.nio.ByteOrder#nativeOrder()}).
|
||||
* Each sample has full range from [-8388608, 8388607],
|
||||
* and can be interpreted as fixed point Q.23 data.
|
||||
* </li>
|
||||
* <li> {@link #ENCODING_PCM_32BIT}: Introduced in
|
||||
* API {@link android.os.Build.VERSION_CODES#S},
|
||||
* this encoding specifies the audio sample is an
|
||||
* extended precision 32 bit signed integer
|
||||
* stored as a 4 Java bytes in a {@code ByteBuffer} or byte array in native endian
|
||||
* (see {@link java.nio.ByteOrder#nativeOrder()}).
|
||||
* Each sample has full range from [-2147483648, 2147483647],
|
||||
* and can be interpreted as fixed point Q.31 data.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>For compressed audio, the encoding specifies the method of compression,
|
||||
* for example {@link #ENCODING_AC3} and {@link #ENCODING_DTS}. The compressed
|
||||
@@ -285,6 +303,19 @@ public final class AudioFormat implements Parcelable {
|
||||
/** Audio data format: OPUS compressed. */
|
||||
public static final int ENCODING_OPUS = 20;
|
||||
|
||||
/** @hide
|
||||
* We do not permit legacy short array reads or writes for encodings
|
||||
* introduced after this threshold.
|
||||
*/
|
||||
public static final int ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD = ENCODING_OPUS;
|
||||
|
||||
/** Audio data format: PCM 24 bit per sample packed as 3 bytes.
|
||||
* Not guaranteed to be supported by devices, may be emulated if not supported. */
|
||||
public static final int ENCODING_PCM_24BIT_PACKED = 21;
|
||||
/** Audio data format: PCM 32 bit per sample.
|
||||
* Not guaranteed to be supported by devices, may be emulated if not supported. */
|
||||
public static final int ENCODING_PCM_32BIT = 22;
|
||||
|
||||
/** @hide */
|
||||
public static String toLogFriendlyEncoding(int enc) {
|
||||
switch(enc) {
|
||||
@@ -328,6 +359,10 @@ public final class AudioFormat implements Parcelable {
|
||||
return "ENCODING_DOLBY_MAT";
|
||||
case ENCODING_OPUS:
|
||||
return "ENCODING_OPUS";
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
return "ENCODING_PCM_24BIT_PACKED";
|
||||
case ENCODING_PCM_32BIT:
|
||||
return "ENCODING_PCM_32BIT";
|
||||
default :
|
||||
return "invalid encoding " + enc;
|
||||
}
|
||||
@@ -561,17 +596,20 @@ public final class AudioFormat implements Parcelable {
|
||||
public static int getBytesPerSample(int audioFormat)
|
||||
{
|
||||
switch (audioFormat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
return 1;
|
||||
case ENCODING_PCM_16BIT:
|
||||
case ENCODING_IEC61937:
|
||||
case ENCODING_DEFAULT:
|
||||
return 2;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
return 4;
|
||||
case ENCODING_INVALID:
|
||||
default:
|
||||
throw new IllegalArgumentException("Bad audio format " + audioFormat);
|
||||
case ENCODING_PCM_8BIT:
|
||||
return 1;
|
||||
case ENCODING_PCM_16BIT:
|
||||
case ENCODING_IEC61937:
|
||||
case ENCODING_DEFAULT:
|
||||
return 2;
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
return 3;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
case ENCODING_PCM_32BIT:
|
||||
return 4;
|
||||
case ENCODING_INVALID:
|
||||
default:
|
||||
throw new IllegalArgumentException("Bad audio format " + audioFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,6 +636,8 @@ public final class AudioFormat implements Parcelable {
|
||||
case ENCODING_E_AC3_JOC:
|
||||
case ENCODING_DOLBY_MAT:
|
||||
case ENCODING_OPUS:
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
case ENCODING_PCM_32BIT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -627,6 +667,8 @@ public final class AudioFormat implements Parcelable {
|
||||
case ENCODING_E_AC3_JOC:
|
||||
case ENCODING_DOLBY_MAT:
|
||||
case ENCODING_OPUS:
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
case ENCODING_PCM_32BIT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -641,6 +683,8 @@ public final class AudioFormat implements Parcelable {
|
||||
case ENCODING_PCM_16BIT:
|
||||
case ENCODING_PCM_8BIT:
|
||||
case ENCODING_PCM_FLOAT:
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
case ENCODING_PCM_32BIT:
|
||||
case ENCODING_DEFAULT:
|
||||
return true;
|
||||
case ENCODING_AC3:
|
||||
@@ -674,6 +718,8 @@ public final class AudioFormat implements Parcelable {
|
||||
case ENCODING_PCM_8BIT:
|
||||
case ENCODING_PCM_FLOAT:
|
||||
case ENCODING_IEC61937: // same size as stereo PCM
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
case ENCODING_PCM_32BIT:
|
||||
case ENCODING_DEFAULT:
|
||||
return true;
|
||||
case ENCODING_AC3:
|
||||
@@ -971,6 +1017,8 @@ public final class AudioFormat implements Parcelable {
|
||||
case ENCODING_E_AC3_JOC:
|
||||
case ENCODING_DOLBY_MAT:
|
||||
case ENCODING_OPUS:
|
||||
case ENCODING_PCM_24BIT_PACKED:
|
||||
case ENCODING_PCM_32BIT:
|
||||
mEncoding = encoding;
|
||||
break;
|
||||
case ENCODING_INVALID:
|
||||
@@ -1191,7 +1239,9 @@ public final class AudioFormat implements Parcelable {
|
||||
ENCODING_AC4,
|
||||
ENCODING_E_AC3_JOC,
|
||||
ENCODING_DOLBY_MAT,
|
||||
ENCODING_OPUS }
|
||||
ENCODING_OPUS,
|
||||
ENCODING_PCM_24BIT_PACKED,
|
||||
ENCODING_PCM_32BIT }
|
||||
)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Encoding {}
|
||||
|
||||
@@ -845,17 +845,21 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
//--------------
|
||||
// audio format
|
||||
switch (audioFormat) {
|
||||
case AudioFormat.ENCODING_DEFAULT:
|
||||
mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
||||
break;
|
||||
case AudioFormat.ENCODING_PCM_FLOAT:
|
||||
case AudioFormat.ENCODING_PCM_16BIT:
|
||||
case AudioFormat.ENCODING_PCM_8BIT:
|
||||
mAudioFormat = audioFormat;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
|
||||
+ ". Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, or ENCODING_PCM_FLOAT.");
|
||||
case AudioFormat.ENCODING_DEFAULT:
|
||||
mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
||||
break;
|
||||
case AudioFormat.ENCODING_PCM_24BIT_PACKED:
|
||||
case AudioFormat.ENCODING_PCM_32BIT:
|
||||
case AudioFormat.ENCODING_PCM_FLOAT:
|
||||
case AudioFormat.ENCODING_PCM_16BIT:
|
||||
case AudioFormat.ENCODING_PCM_8BIT:
|
||||
mAudioFormat = audioFormat;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
|
||||
+ ". Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT,"
|
||||
+ " ENCODING_PCM_24BIT_PACKED, ENCODING_PCM_32BIT,"
|
||||
+ " or ENCODING_PCM_FLOAT.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1262,6 +1266,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
*/
|
||||
public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
|
||||
@ReadMode int readMode) {
|
||||
// Note: we allow reads of extended integers into a byte array.
|
||||
if (mState != STATE_INITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||
return ERROR_INVALID_OPERATION;
|
||||
}
|
||||
@@ -1334,7 +1339,10 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
*/
|
||||
public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
|
||||
@ReadMode int readMode) {
|
||||
if (mState != STATE_INITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||
if (mState != STATE_INITIALIZED
|
||||
|| mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT
|
||||
// use ByteBuffer instead for later encodings
|
||||
|| mAudioFormat > AudioFormat.ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD) {
|
||||
return ERROR_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
|
||||
@@ -2992,7 +2992,7 @@ public class AudioTrack extends PlayerBase
|
||||
*/
|
||||
public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
|
||||
@WriteMode int writeMode) {
|
||||
|
||||
// Note: we allow writes of extended integers and compressed formats from a byte array.
|
||||
if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||
return ERROR_INVALID_OPERATION;
|
||||
}
|
||||
@@ -3106,7 +3106,10 @@ public class AudioTrack extends PlayerBase
|
||||
public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
|
||||
@WriteMode int writeMode) {
|
||||
|
||||
if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||
if (mState == STATE_UNINITIALIZED
|
||||
|| mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT
|
||||
// use ByteBuffer or byte[] instead for later encodings
|
||||
|| mAudioFormat > AudioFormat.ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD) {
|
||||
return ERROR_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user