Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f81f606e authored by Andy Hung's avatar Andy Hung Committed by jiabin
Browse files

AudioFormat: Add ENCODING_PCM_32BIT ENCODING_PCM_24BIT_PACKED

Add extended high definition integer formats to support direct
audio data delivery to the HAL.

Test: atest AudioRecordTest
Test: atest AudioTrackTest
Test: Clarity AudioManager
Bug: 152481314
Bug: 157671580
Merged-In: I92a099e98dd20ef900765928cbacea5e8a940c3c
Change-Id: I92a099e98dd20ef900765928cbacea5e8a940c3c
parent 1f82f476
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -19383,6 +19383,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
+13 −2
Original line number Original line Diff line number Diff line
@@ -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:
+25 −1
Original line number Original line Diff line number Diff line
@@ -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;
    }
    }


    /**
    /**
+62 −12
Original line number Original line Diff line number Diff line
@@ -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;
        }
        }
@@ -523,7 +558,10 @@ public final class AudioFormat implements Parcelable {
            case ENCODING_IEC61937:
            case ENCODING_IEC61937:
            case ENCODING_DEFAULT:
            case ENCODING_DEFAULT:
                return 2;
                return 2;
            case ENCODING_PCM_24BIT_PACKED:
                return 3;
            case ENCODING_PCM_FLOAT:
            case ENCODING_PCM_FLOAT:
            case ENCODING_PCM_32BIT:
                return 4;
                return 4;
            case ENCODING_INVALID:
            case ENCODING_INVALID:
            default:
            default:
@@ -554,6 +592,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;
@@ -583,6 +623,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;
@@ -597,6 +639,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:
@@ -630,6 +674,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:
@@ -927,6 +973,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:
@@ -1147,7 +1195,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 {}
+20 −12
Original line number Original line Diff line number Diff line
@@ -848,6 +848,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
            case AudioFormat.ENCODING_DEFAULT:
            case AudioFormat.ENCODING_DEFAULT:
                mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
                mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
                break;
                break;
            case AudioFormat.ENCODING_PCM_24BIT_PACKED:
            case AudioFormat.ENCODING_PCM_32BIT:
            case AudioFormat.ENCODING_PCM_FLOAT:
            case AudioFormat.ENCODING_PCM_FLOAT:
            case AudioFormat.ENCODING_PCM_16BIT:
            case AudioFormat.ENCODING_PCM_16BIT:
            case AudioFormat.ENCODING_PCM_8BIT:
            case AudioFormat.ENCODING_PCM_8BIT:
@@ -855,7 +857,9 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
                break;
                break;
            default:
            default:
                throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
                throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
                    + ". Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, or ENCODING_PCM_FLOAT.");
                        + ". 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;
        }
        }


Loading