1 /* 2 * Copyright 2015 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 17 package android.media; 18 19 import android.annotation.IntDef; 20 import android.annotation.TestApi; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 27 /** 28 * Structure for common playback params. 29 * 30 * Used by {@link AudioTrack} {@link AudioTrack#getPlaybackParams()} and 31 * {@link AudioTrack#setPlaybackParams(PlaybackParams)} 32 * to control playback behavior. 33 * <p> <strong>audio fallback mode:</strong> 34 * select out-of-range parameter handling. 35 * <ul> 36 * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_DEFAULT}: 37 * System will determine best handling. </li> 38 * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_MUTE}: 39 * Play silence for params normally out of range.</li> 40 * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_FAIL}: 41 * Return {@link java.lang.IllegalArgumentException} from 42 * <code>AudioTrack.setPlaybackParams(PlaybackParams)</code>.</li> 43 * </ul> 44 * <p> <strong>pitch:</strong> increases or decreases the tonal frequency of the audio content. 45 * It is expressed as a multiplicative factor, where normal pitch is 1.0f. 46 * <p> <strong>speed:</strong> increases or decreases the time to 47 * play back a set of audio or video frames. 48 * It is expressed as a multiplicative factor, where normal speed is 1.0f. 49 * <p> Different combinations of speed and pitch may be used for audio playback; 50 * some common ones: 51 * <ul> 52 * <li> <em>Pitch equals 1.0f.</em> Speed change will be done with pitch preserved, 53 * often called <em>timestretching</em>.</li> 54 * <li> <em>Pitch equals speed.</em> Speed change will be done by <em>resampling</em>, 55 * similar to {@link AudioTrack#setPlaybackRate(int)}.</li> 56 * </ul> 57 */ 58 public final class PlaybackParams implements Parcelable { 59 /** @hide */ 60 @IntDef( 61 value = { 62 AUDIO_FALLBACK_MODE_DEFAULT, 63 AUDIO_FALLBACK_MODE_MUTE, 64 AUDIO_FALLBACK_MODE_FAIL, 65 } 66 ) 67 @Retention(RetentionPolicy.SOURCE) 68 public @interface AudioFallbackMode {} 69 public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0; 70 public static final int AUDIO_FALLBACK_MODE_MUTE = 1; 71 public static final int AUDIO_FALLBACK_MODE_FAIL = 2; 72 73 /** @hide */ 74 @IntDef( 75 value = { 76 AUDIO_STRETCH_MODE_DEFAULT, 77 AUDIO_STRETCH_MODE_VOICE, 78 } 79 ) 80 @Retention(RetentionPolicy.SOURCE) 81 public @interface AudioStretchMode {} 82 /** @hide */ 83 public static final int AUDIO_STRETCH_MODE_DEFAULT = 0; 84 /** @hide */ 85 public static final int AUDIO_STRETCH_MODE_VOICE = 1; 86 87 // flags to indicate which params are actually set 88 private static final int SET_SPEED = 1 << 0; 89 private static final int SET_PITCH = 1 << 1; 90 private static final int SET_AUDIO_FALLBACK_MODE = 1 << 2; 91 private static final int SET_AUDIO_STRETCH_MODE = 1 << 3; 92 private int mSet = 0; 93 94 // params 95 private int mAudioFallbackMode = AUDIO_FALLBACK_MODE_DEFAULT; 96 private int mAudioStretchMode = AUDIO_STRETCH_MODE_DEFAULT; 97 private float mPitch = 1.0f; 98 private float mSpeed = 1.0f; 99 100 public PlaybackParams() { 101 } 102 103 private PlaybackParams(Parcel in) { 104 mSet = in.readInt(); 105 mAudioFallbackMode = in.readInt(); 106 mAudioStretchMode = in.readInt(); 107 mPitch = in.readFloat(); 108 if (mPitch < 0.f) { 109 mPitch = 0.f; 110 } 111 mSpeed = in.readFloat(); 112 } 113 114 /** 115 * Allows defaults to be returned for properties not set. 116 * Otherwise a {@link java.lang.IllegalArgumentException} exception 117 * is raised when getting those properties 118 * which have defaults but have never been set. 119 * @return this <code>PlaybackParams</code> instance. 120 */ 121 public PlaybackParams allowDefaults() { 122 mSet |= SET_AUDIO_FALLBACK_MODE | SET_AUDIO_STRETCH_MODE | SET_PITCH | SET_SPEED; 123 return this; 124 } 125 126 /** 127 * Sets the audio fallback mode. 128 * @param audioFallbackMode 129 * @return this <code>PlaybackParams</code> instance. 130 */ 131 public PlaybackParams setAudioFallbackMode(@AudioFallbackMode int audioFallbackMode) { 132 mAudioFallbackMode = audioFallbackMode; 133 mSet |= SET_AUDIO_FALLBACK_MODE; 134 return this; 135 } 136 137 /** 138 * Retrieves the audio fallback mode. 139 * @return audio fallback mode 140 * @throws IllegalStateException if the audio fallback mode is not set. 141 */ 142 public @AudioFallbackMode int getAudioFallbackMode() { 143 if ((mSet & SET_AUDIO_FALLBACK_MODE) == 0) { 144 throw new IllegalStateException("audio fallback mode not set"); 145 } 146 return mAudioFallbackMode; 147 } 148 149 /** 150 * @hide 151 * Sets the audio stretch mode. 152 * @param audioStretchMode 153 * @return this <code>PlaybackParams</code> instance. 154 */ 155 @TestApi 156 public PlaybackParams setAudioStretchMode(@AudioStretchMode int audioStretchMode) { 157 mAudioStretchMode = audioStretchMode; 158 mSet |= SET_AUDIO_STRETCH_MODE; 159 return this; 160 } 161 162 /** 163 * @hide 164 * Retrieves the audio stretch mode. 165 * @return audio stretch mode 166 * @throws IllegalStateException if the audio stretch mode is not set. 167 */ 168 @TestApi 169 public @AudioStretchMode int getAudioStretchMode() { 170 if ((mSet & SET_AUDIO_STRETCH_MODE) == 0) { 171 throw new IllegalStateException("audio stretch mode not set"); 172 } 173 return mAudioStretchMode; 174 } 175 176 /** 177 * Sets the pitch factor. 178 * @param pitch 179 * @return this <code>PlaybackParams</code> instance. 180 * @throws IllegalArgumentException if the pitch is negative. 181 */ 182 public PlaybackParams setPitch(float pitch) { 183 if (pitch < 0.f) { 184 throw new IllegalArgumentException("pitch must not be negative"); 185 } 186 mPitch = pitch; 187 mSet |= SET_PITCH; 188 return this; 189 } 190 191 /** 192 * Retrieves the pitch factor. 193 * @return pitch 194 * @throws IllegalStateException if pitch is not set. 195 */ 196 public float getPitch() { 197 if ((mSet & SET_PITCH) == 0) { 198 throw new IllegalStateException("pitch not set"); 199 } 200 return mPitch; 201 } 202 203 /** 204 * Sets the speed factor. 205 * @param speed 206 * @return this <code>PlaybackParams</code> instance. 207 */ 208 public PlaybackParams setSpeed(float speed) { 209 mSpeed = speed; 210 mSet |= SET_SPEED; 211 return this; 212 } 213 214 /** 215 * Retrieves the speed factor. 216 * @return speed 217 * @throws IllegalStateException if speed is not set. 218 */ 219 public float getSpeed() { 220 if ((mSet & SET_SPEED) == 0) { 221 throw new IllegalStateException("speed not set"); 222 } 223 return mSpeed; 224 } 225 226 public static final Parcelable.Creator<PlaybackParams> CREATOR = 227 new Parcelable.Creator<PlaybackParams>() { 228 @Override 229 public PlaybackParams createFromParcel(Parcel in) { 230 return new PlaybackParams(in); 231 } 232 233 @Override 234 public PlaybackParams[] newArray(int size) { 235 return new PlaybackParams[size]; 236 } 237 }; 238 239 240 @Override 241 public int describeContents() { 242 return 0; 243 } 244 245 @Override 246 public void writeToParcel(Parcel dest, int flags) { 247 dest.writeInt(mSet); 248 dest.writeInt(mAudioFallbackMode); 249 dest.writeInt(mAudioStretchMode); 250 dest.writeFloat(mPitch); 251 dest.writeFloat(mSpeed); 252 } 253 } 254