summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/audio/LoudnessCodecHelper.java70
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java122
2 files changed, 184 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
index 3c67e9dd116b..c306e3c07ac0 100644
--- a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
+++ b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
@@ -21,6 +21,11 @@ import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEARING_AID;
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_WATCH;
import static android.media.AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID;
+import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4;
+import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D;
+import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
+import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION;
+import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -41,6 +46,7 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -70,10 +76,14 @@ public class LoudnessCodecHelper {
private static final String SYSTEM_PROPERTY_SPEAKER_SPL_RANGE_SIZE =
"audio.loudness.builtin-speaker-spl-range-size";
- private static final int SPL_RANGE_UNKNOWN = 0;
- private static final int SPL_RANGE_SMALL = 1;
- private static final int SPL_RANGE_MEDIUM = 2;
- private static final int SPL_RANGE_LARGE = 3;
+ @VisibleForTesting
+ static final int SPL_RANGE_UNKNOWN = 0;
+ @VisibleForTesting
+ static final int SPL_RANGE_SMALL = 1;
+ @VisibleForTesting
+ static final int SPL_RANGE_MEDIUM = 2;
+ @VisibleForTesting
+ static final int SPL_RANGE_LARGE = 3;
/** The possible transducer SPL ranges as defined in CTA2075 */
@IntDef({
@@ -125,7 +135,8 @@ public class LoudnessCodecHelper {
private final AudioService mAudioService;
/** Contains the properties necessary to compute the codec loudness related parameters. */
- private static final class LoudnessCodecInputProperties {
+ @VisibleForTesting
+ static final class LoudnessCodecInputProperties {
private final int mMetadataType;
private final boolean mIsDownmixing;
@@ -200,10 +211,53 @@ public class LoudnessCodecHelper {
}
PersistableBundle createLoudnessParameters() {
- // TODO: create bundle with new parameters
- return new PersistableBundle();
- }
+ PersistableBundle loudnessParams = new PersistableBundle();
+
+ switch (mDeviceSplRange) {
+ case SPL_RANGE_LARGE:
+ // corresponds to -31dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 124);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 0);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // general compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+ }
+ break;
+ case SPL_RANGE_MEDIUM:
+ // corresponds to -24dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // general compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+ }
+ break;
+ case SPL_RANGE_SMALL:
+ // corresponds to -16dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 64);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 1);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // limited playback range compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 3);
+ }
+ break;
+ default:
+ // corresponds to -24dB attenuation
+ loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96);
+ if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+ loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0);
+ } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+ // general compression
+ loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+ }
+ break;
+ }
+ return loudnessParams;
+ }
}
@GuardedBy("mLock")
diff --git a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
index 749b07d16ebe..42c5205455ca 100644
--- a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
@@ -19,6 +19,16 @@ import static android.media.AudioManager.GET_DEVICES_OUTPUTS;
import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_DEVICE_ID;
import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4;
import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D;
+import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
+import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION;
+import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
+
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_LARGE;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_MEDIUM;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_SMALL;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_UNKNOWN;
+
+import static junit.framework.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -34,11 +44,15 @@ import android.media.ILoudnessCodecUpdatesDispatcher;
import android.media.LoudnessCodecInfo;
import android.media.PlayerBase;
import android.os.IBinder;
+import android.os.PersistableBundle;
import android.platform.test.annotations.Presubmit;
import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.server.audio.LoudnessCodecHelper.DeviceSplRange;
+import com.android.server.audio.LoudnessCodecHelper.LoudnessCodecInputProperties;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -200,6 +214,108 @@ public class LoudnessCodecHelperTest {
any());
}
+ @Test
+ public void checkParcelableBundle_forMpeg4CodecInputProperties() {
+ PersistableBundle loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+ }
+
+ @Test
+ public void checkParcelableBundle_forMpegDCodecInputProperties() {
+ PersistableBundle loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_SMALL).createLoudnessParameters();
+ assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_MEDIUM).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_LARGE).createLoudnessParameters();
+ assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+ loudnessParameters = createInputProperties(
+ CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+ SPL_RANGE_UNKNOWN).createLoudnessParameters();
+ assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+ assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+ }
+
private List<AudioPlaybackConfiguration> getApcListForPiids(int... piids) {
final ArrayList<AudioPlaybackConfiguration> apcList = new ArrayList<>();
@@ -220,6 +336,12 @@ public class LoudnessCodecHelperTest {
return apcList;
}
+ private static LoudnessCodecInputProperties createInputProperties(
+ int metadataType, boolean isDownmixing, @DeviceSplRange int splRange) {
+ return new LoudnessCodecInputProperties.Builder().setMetadataType(
+ metadataType).setIsDownmixing(isDownmixing).setDeviceSplRange(splRange).build();
+ }
+
private static LoudnessCodecInfo getLoudnessInfo(int mediaCodecHash, boolean isDownmixing,
int metadataType) {
LoudnessCodecInfo info = new LoudnessCodecInfo();