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_MP3 = 9; // 0x9
|
||||||
field public static final int ENCODING_OPUS = 20; // 0x14
|
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_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_8BIT = 3; // 0x3
|
||||||
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
||||||
field public static final int SAMPLE_RATE_UNSPECIFIED = 0; // 0x0
|
field public static final int SAMPLE_RATE_UNSPECIFIED = 0; // 0x0
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
#define ENCODING_E_AC3_JOC 18
|
#define ENCODING_E_AC3_JOC 18
|
||||||
#define ENCODING_DOLBY_MAT 19
|
#define ENCODING_DOLBY_MAT 19
|
||||||
#define ENCODING_OPUS 20
|
#define ENCODING_OPUS 20
|
||||||
|
#define ENCODING_PCM_24BIT_PACKED 21
|
||||||
|
#define ENCODING_PCM_32BIT 22
|
||||||
|
|
||||||
#define ENCODING_INVALID 0
|
#define ENCODING_INVALID 0
|
||||||
#define ENCODING_DEFAULT 1
|
#define ENCODING_DEFAULT 1
|
||||||
@@ -92,6 +94,10 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
|
|||||||
return AUDIO_FORMAT_MAT;
|
return AUDIO_FORMAT_MAT;
|
||||||
case ENCODING_OPUS:
|
case ENCODING_OPUS:
|
||||||
return AUDIO_FORMAT_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:
|
default:
|
||||||
return AUDIO_FORMAT_INVALID;
|
return AUDIO_FORMAT_INVALID;
|
||||||
}
|
}
|
||||||
@@ -107,10 +113,15 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
|
|||||||
case AUDIO_FORMAT_PCM_FLOAT:
|
case AUDIO_FORMAT_PCM_FLOAT:
|
||||||
return ENCODING_PCM_FLOAT;
|
return ENCODING_PCM_FLOAT;
|
||||||
|
|
||||||
// map these to ENCODING_PCM_FLOAT
|
// As of S, these extend integer precision formats now return more specific values
|
||||||
case AUDIO_FORMAT_PCM_8_24_BIT:
|
// than ENCODING_PCM_FLOAT.
|
||||||
case AUDIO_FORMAT_PCM_24_BIT_PACKED:
|
case AUDIO_FORMAT_PCM_24_BIT_PACKED:
|
||||||
|
return ENCODING_PCM_24BIT_PACKED;
|
||||||
case AUDIO_FORMAT_PCM_32_BIT:
|
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;
|
return ENCODING_PCM_FLOAT;
|
||||||
|
|
||||||
case AUDIO_FORMAT_AC3:
|
case AUDIO_FORMAT_AC3:
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.util.SparseIntArray;
|
|||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
@@ -467,9 +468,32 @@ public final class AudioDeviceInfo {
|
|||||||
* @see AudioFormat
|
* @see AudioFormat
|
||||||
*
|
*
|
||||||
* Note: an empty array indicates that the device supports arbitrary encodings.
|
* 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() {
|
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}
|
* <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP}
|
||||||
* support <code>ENCODING_PCM_FLOAT</code>.
|
* support <code>ENCODING_PCM_FLOAT</code>.
|
||||||
* </li>
|
* </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>
|
* </ul>
|
||||||
* <p>For compressed audio, the encoding specifies the method of compression,
|
* <p>For compressed audio, the encoding specifies the method of compression,
|
||||||
* for example {@link #ENCODING_AC3} and {@link #ENCODING_DTS}. The compressed
|
* 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. */
|
/** Audio data format: OPUS compressed. */
|
||||||
public static final int ENCODING_OPUS = 20;
|
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 */
|
/** @hide */
|
||||||
public static String toLogFriendlyEncoding(int enc) {
|
public static String toLogFriendlyEncoding(int enc) {
|
||||||
switch(enc) {
|
switch(enc) {
|
||||||
@@ -328,6 +359,10 @@ public final class AudioFormat implements Parcelable {
|
|||||||
return "ENCODING_DOLBY_MAT";
|
return "ENCODING_DOLBY_MAT";
|
||||||
case ENCODING_OPUS:
|
case ENCODING_OPUS:
|
||||||
return "ENCODING_OPUS";
|
return "ENCODING_OPUS";
|
||||||
|
case ENCODING_PCM_24BIT_PACKED:
|
||||||
|
return "ENCODING_PCM_24BIT_PACKED";
|
||||||
|
case ENCODING_PCM_32BIT:
|
||||||
|
return "ENCODING_PCM_32BIT";
|
||||||
default :
|
default :
|
||||||
return "invalid encoding " + enc;
|
return "invalid encoding " + enc;
|
||||||
}
|
}
|
||||||
@@ -561,17 +596,20 @@ public final class AudioFormat implements Parcelable {
|
|||||||
public static int getBytesPerSample(int audioFormat)
|
public static int getBytesPerSample(int audioFormat)
|
||||||
{
|
{
|
||||||
switch (audioFormat) {
|
switch (audioFormat) {
|
||||||
case ENCODING_PCM_8BIT:
|
case ENCODING_PCM_8BIT:
|
||||||
return 1;
|
return 1;
|
||||||
case ENCODING_PCM_16BIT:
|
case ENCODING_PCM_16BIT:
|
||||||
case ENCODING_IEC61937:
|
case ENCODING_IEC61937:
|
||||||
case ENCODING_DEFAULT:
|
case ENCODING_DEFAULT:
|
||||||
return 2;
|
return 2;
|
||||||
case ENCODING_PCM_FLOAT:
|
case ENCODING_PCM_24BIT_PACKED:
|
||||||
return 4;
|
return 3;
|
||||||
case ENCODING_INVALID:
|
case ENCODING_PCM_FLOAT:
|
||||||
default:
|
case ENCODING_PCM_32BIT:
|
||||||
throw new IllegalArgumentException("Bad audio format " + audioFormat);
|
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_E_AC3_JOC:
|
||||||
case ENCODING_DOLBY_MAT:
|
case ENCODING_DOLBY_MAT:
|
||||||
case ENCODING_OPUS:
|
case ENCODING_OPUS:
|
||||||
|
case ENCODING_PCM_24BIT_PACKED:
|
||||||
|
case ENCODING_PCM_32BIT:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -627,6 +667,8 @@ public final class AudioFormat implements Parcelable {
|
|||||||
case ENCODING_E_AC3_JOC:
|
case ENCODING_E_AC3_JOC:
|
||||||
case ENCODING_DOLBY_MAT:
|
case ENCODING_DOLBY_MAT:
|
||||||
case ENCODING_OPUS:
|
case ENCODING_OPUS:
|
||||||
|
case ENCODING_PCM_24BIT_PACKED:
|
||||||
|
case ENCODING_PCM_32BIT:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -641,6 +683,8 @@ public final class AudioFormat implements Parcelable {
|
|||||||
case ENCODING_PCM_16BIT:
|
case ENCODING_PCM_16BIT:
|
||||||
case ENCODING_PCM_8BIT:
|
case ENCODING_PCM_8BIT:
|
||||||
case ENCODING_PCM_FLOAT:
|
case ENCODING_PCM_FLOAT:
|
||||||
|
case ENCODING_PCM_24BIT_PACKED:
|
||||||
|
case ENCODING_PCM_32BIT:
|
||||||
case ENCODING_DEFAULT:
|
case ENCODING_DEFAULT:
|
||||||
return true;
|
return true;
|
||||||
case ENCODING_AC3:
|
case ENCODING_AC3:
|
||||||
@@ -674,6 +718,8 @@ public final class AudioFormat implements Parcelable {
|
|||||||
case ENCODING_PCM_8BIT:
|
case ENCODING_PCM_8BIT:
|
||||||
case ENCODING_PCM_FLOAT:
|
case ENCODING_PCM_FLOAT:
|
||||||
case ENCODING_IEC61937: // same size as stereo PCM
|
case ENCODING_IEC61937: // same size as stereo PCM
|
||||||
|
case ENCODING_PCM_24BIT_PACKED:
|
||||||
|
case ENCODING_PCM_32BIT:
|
||||||
case ENCODING_DEFAULT:
|
case ENCODING_DEFAULT:
|
||||||
return true;
|
return true;
|
||||||
case ENCODING_AC3:
|
case ENCODING_AC3:
|
||||||
@@ -971,6 +1017,8 @@ public final class AudioFormat implements Parcelable {
|
|||||||
case ENCODING_E_AC3_JOC:
|
case ENCODING_E_AC3_JOC:
|
||||||
case ENCODING_DOLBY_MAT:
|
case ENCODING_DOLBY_MAT:
|
||||||
case ENCODING_OPUS:
|
case ENCODING_OPUS:
|
||||||
|
case ENCODING_PCM_24BIT_PACKED:
|
||||||
|
case ENCODING_PCM_32BIT:
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
break;
|
break;
|
||||||
case ENCODING_INVALID:
|
case ENCODING_INVALID:
|
||||||
@@ -1191,7 +1239,9 @@ public final class AudioFormat implements Parcelable {
|
|||||||
ENCODING_AC4,
|
ENCODING_AC4,
|
||||||
ENCODING_E_AC3_JOC,
|
ENCODING_E_AC3_JOC,
|
||||||
ENCODING_DOLBY_MAT,
|
ENCODING_DOLBY_MAT,
|
||||||
ENCODING_OPUS }
|
ENCODING_OPUS,
|
||||||
|
ENCODING_PCM_24BIT_PACKED,
|
||||||
|
ENCODING_PCM_32BIT }
|
||||||
)
|
)
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface Encoding {}
|
public @interface Encoding {}
|
||||||
|
|||||||
@@ -845,17 +845,21 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
|||||||
//--------------
|
//--------------
|
||||||
// audio format
|
// audio format
|
||||||
switch (audioFormat) {
|
switch (audioFormat) {
|
||||||
case AudioFormat.ENCODING_DEFAULT:
|
case AudioFormat.ENCODING_DEFAULT:
|
||||||
mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
||||||
break;
|
break;
|
||||||
case AudioFormat.ENCODING_PCM_FLOAT:
|
case AudioFormat.ENCODING_PCM_24BIT_PACKED:
|
||||||
case AudioFormat.ENCODING_PCM_16BIT:
|
case AudioFormat.ENCODING_PCM_32BIT:
|
||||||
case AudioFormat.ENCODING_PCM_8BIT:
|
case AudioFormat.ENCODING_PCM_FLOAT:
|
||||||
mAudioFormat = audioFormat;
|
case AudioFormat.ENCODING_PCM_16BIT:
|
||||||
break;
|
case AudioFormat.ENCODING_PCM_8BIT:
|
||||||
default:
|
mAudioFormat = audioFormat;
|
||||||
throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
|
break;
|
||||||
+ ". Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, or ENCODING_PCM_FLOAT.");
|
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,
|
public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
|
||||||
@ReadMode int readMode) {
|
@ReadMode int readMode) {
|
||||||
|
// Note: we allow reads of extended integers into a byte array.
|
||||||
if (mState != STATE_INITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
if (mState != STATE_INITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||||
return ERROR_INVALID_OPERATION;
|
return ERROR_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
@@ -1334,7 +1339,10 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
|||||||
*/
|
*/
|
||||||
public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
|
public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
|
||||||
@ReadMode int readMode) {
|
@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;
|
return ERROR_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2992,7 +2992,7 @@ public class AudioTrack extends PlayerBase
|
|||||||
*/
|
*/
|
||||||
public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
|
public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
|
||||||
@WriteMode int writeMode) {
|
@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) {
|
if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||||
return ERROR_INVALID_OPERATION;
|
return ERROR_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
@@ -3106,7 +3106,10 @@ public class AudioTrack extends PlayerBase
|
|||||||
public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
|
public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
|
||||||
@WriteMode int writeMode) {
|
@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;
|
return ERROR_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user