1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.exoplayer2.audio; 17 18 import androidx.annotation.Nullable; 19 import androidx.annotation.RequiresApi; 20 import com.google.android.exoplayer2.C; 21 import com.google.android.exoplayer2.util.Util; 22 23 /** 24 * Attributes for audio playback, which configure the underlying platform 25 * {@link android.media.AudioTrack}. 26 * <p> 27 * To set the audio attributes, create an instance using the {@link Builder} and either pass it to 28 * {@link com.google.android.exoplayer2.SimpleExoPlayer#setAudioAttributes(AudioAttributes)} or 29 * send a message of type {@link C#MSG_SET_AUDIO_ATTRIBUTES} to the audio renderers. 30 * <p> 31 * This class is based on {@link android.media.AudioAttributes}, but can be used on all supported 32 * API versions. 33 */ 34 public final class AudioAttributes { 35 36 public static final AudioAttributes DEFAULT = new Builder().build(); 37 38 /** 39 * Builder for {@link AudioAttributes}. 40 */ 41 public static final class Builder { 42 43 private @C.AudioContentType int contentType; 44 private @C.AudioFlags int flags; 45 private @C.AudioUsage int usage; 46 private @C.AudioAllowedCapturePolicy int allowedCapturePolicy; 47 48 /** 49 * Creates a new builder for {@link AudioAttributes}. 50 * 51 * <p>By default the content type is {@link C#CONTENT_TYPE_UNKNOWN}, usage is {@link 52 * C#USAGE_MEDIA}, capture policy is {@link C#ALLOW_CAPTURE_BY_ALL} and no flags are set. 53 */ Builder()54 public Builder() { 55 contentType = C.CONTENT_TYPE_UNKNOWN; 56 flags = 0; 57 usage = C.USAGE_MEDIA; 58 allowedCapturePolicy = C.ALLOW_CAPTURE_BY_ALL; 59 } 60 61 /** 62 * @see android.media.AudioAttributes.Builder#setContentType(int) 63 */ setContentType(@.AudioContentType int contentType)64 public Builder setContentType(@C.AudioContentType int contentType) { 65 this.contentType = contentType; 66 return this; 67 } 68 69 /** 70 * @see android.media.AudioAttributes.Builder#setFlags(int) 71 */ setFlags(@.AudioFlags int flags)72 public Builder setFlags(@C.AudioFlags int flags) { 73 this.flags = flags; 74 return this; 75 } 76 77 /** 78 * @see android.media.AudioAttributes.Builder#setUsage(int) 79 */ setUsage(@.AudioUsage int usage)80 public Builder setUsage(@C.AudioUsage int usage) { 81 this.usage = usage; 82 return this; 83 } 84 85 /** See {@link android.media.AudioAttributes.Builder#setAllowedCapturePolicy(int)}. */ setAllowedCapturePolicy(@.AudioAllowedCapturePolicy int allowedCapturePolicy)86 public Builder setAllowedCapturePolicy(@C.AudioAllowedCapturePolicy int allowedCapturePolicy) { 87 this.allowedCapturePolicy = allowedCapturePolicy; 88 return this; 89 } 90 91 /** Creates an {@link AudioAttributes} instance from this builder. */ build()92 public AudioAttributes build() { 93 return new AudioAttributes(contentType, flags, usage, allowedCapturePolicy); 94 } 95 96 } 97 98 public final @C.AudioContentType int contentType; 99 public final @C.AudioFlags int flags; 100 public final @C.AudioUsage int usage; 101 public final @C.AudioAllowedCapturePolicy int allowedCapturePolicy; 102 103 @Nullable private android.media.AudioAttributes audioAttributesV21; 104 AudioAttributes( @.AudioContentType int contentType, @C.AudioFlags int flags, @C.AudioUsage int usage, @C.AudioAllowedCapturePolicy int allowedCapturePolicy)105 private AudioAttributes( 106 @C.AudioContentType int contentType, 107 @C.AudioFlags int flags, 108 @C.AudioUsage int usage, 109 @C.AudioAllowedCapturePolicy int allowedCapturePolicy) { 110 this.contentType = contentType; 111 this.flags = flags; 112 this.usage = usage; 113 this.allowedCapturePolicy = allowedCapturePolicy; 114 } 115 116 /** 117 * Returns a {@link android.media.AudioAttributes} from this instance. 118 * 119 * <p>Field {@link AudioAttributes#allowedCapturePolicy} is ignored for API levels prior to 29. 120 */ 121 @RequiresApi(21) getAudioAttributesV21()122 public android.media.AudioAttributes getAudioAttributesV21() { 123 if (audioAttributesV21 == null) { 124 android.media.AudioAttributes.Builder builder = 125 new android.media.AudioAttributes.Builder() 126 .setContentType(contentType) 127 .setFlags(flags) 128 .setUsage(usage); 129 if (Util.SDK_INT >= 29) { 130 builder.setAllowedCapturePolicy(allowedCapturePolicy); 131 } 132 audioAttributesV21 = builder.build(); 133 } 134 return audioAttributesV21; 135 } 136 137 @Override equals(@ullable Object obj)138 public boolean equals(@Nullable Object obj) { 139 if (this == obj) { 140 return true; 141 } 142 if (obj == null || getClass() != obj.getClass()) { 143 return false; 144 } 145 AudioAttributes other = (AudioAttributes) obj; 146 return this.contentType == other.contentType 147 && this.flags == other.flags 148 && this.usage == other.usage 149 && this.allowedCapturePolicy == other.allowedCapturePolicy; 150 } 151 152 @Override hashCode()153 public int hashCode() { 154 int result = 17; 155 result = 31 * result + contentType; 156 result = 31 * result + flags; 157 result = 31 * result + usage; 158 result = 31 * result + allowedCapturePolicy; 159 return result; 160 } 161 162 } 163