AudioTrack.java revision c73305cfd7bad91f654dfa818c44b640594d7aad
1/* 2 * Copyright (C) 2010 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 17package android.media.videoeditor; 18 19import java.io.IOException; 20 21/** 22 * This class allows to handle an audio track. This audio file is mixed with the 23 * audio samples of the MediaItems. 24 * {@hide} 25 */ 26public class AudioTrack { 27 // Instance variables 28 private final String mUniqueId; 29 private final String mFilename; 30 private final long mDurationMs; 31 private long mStartTimeMs; 32 private long mTimelineDurationMs; 33 private int mVolumePercent; 34 private long mBeginBoundaryTimeMs; 35 private long mEndBoundaryTimeMs; 36 private boolean mLoop; 37 38 private final int mAudioChannels; 39 private final int mAudioType; 40 private final int mAudioBitrate; 41 private final int mAudioSamplingFrequency; 42 43 // Ducking variables 44 private int mDuckingThreshold; 45 private int mDuckingLowVolume; 46 private boolean mIsDuckingEnabled; 47 48 // The audio waveform filename 49 private String mAudioWaveformFilename; 50 51 /** 52 * An object of this type cannot be instantiated by using the default 53 * constructor 54 */ 55 @SuppressWarnings("unused") 56 private AudioTrack() throws IOException { 57 this(null, null); 58 } 59 60 /** 61 * Constructor 62 * @param audioTrackId The AudioTrack id 63 * @param filename The absolute file name 64 * 65 * @throws IOException if file is not found 66 * @throws IllegalArgumentException if file format is not supported or if 67 * the codec is not supported 68 */ 69 public AudioTrack(String audioTrackId, String filename) throws IOException { 70 mUniqueId = audioTrackId; 71 mFilename = filename; 72 mStartTimeMs = 0; 73 // TODO: This value represents to the duration of the audio file 74 mDurationMs = 300000; 75 // TODO: This value needs to be read from the audio track of the source 76 // file 77 mAudioChannels = 2; 78 mAudioType = MediaProperties.ACODEC_AAC_LC; 79 mAudioBitrate = 128000; 80 mAudioSamplingFrequency = 44100; 81 82 mTimelineDurationMs = mDurationMs; 83 mVolumePercent = 100; 84 85 // Play the entire audio track 86 mBeginBoundaryTimeMs = 0; 87 mEndBoundaryTimeMs = mDurationMs; 88 89 // By default loop is disabled 90 mLoop = false; 91 92 // Ducking is enabled by default 93 mDuckingThreshold = 0; 94 mDuckingLowVolume = 0; 95 mIsDuckingEnabled = true; 96 97 // The audio waveform file is generated later 98 mAudioWaveformFilename = null; 99 } 100 101 /** 102 * @return The id of the media item 103 */ 104 public String getId() { 105 return mUniqueId; 106 } 107 108 /** 109 * Get the filename source for this audio track. 110 * 111 * @return The filename as an absolute file name 112 */ 113 public String getFilename() { 114 return mFilename; 115 } 116 117 /** 118 * @return The number of audio channels in the source of this audio track 119 */ 120 public int getAudioChannels() { 121 return mAudioChannels; 122 } 123 124 /** 125 * @return The audio codec of the source of this audio track 126 */ 127 public int getAudioType() { 128 return mAudioType; 129 } 130 131 /** 132 * @return The audio sample frequency of the audio track 133 */ 134 public int getAudioSamplingFrequency() { 135 return mAudioSamplingFrequency; 136 } 137 138 /** 139 * @return The audio bitrate of the audio track 140 */ 141 public int getAudioBitrate() { 142 return mAudioBitrate; 143 } 144 145 /** 146 * Set the volume of this audio track as percentage of the volume in the 147 * original audio source file. 148 * 149 * @param volumePercent Percentage of the volume to apply. If it is set to 150 * 0, then volume becomes mute. It it is set to 100, then volume 151 * is same as original volume. It it is set to 200, then volume 152 * is doubled (provided that volume amplification is supported) 153 * 154 * @throws UnsupportedOperationException if volume amplification is 155 * requested and is not supported. 156 */ 157 public void setVolume(int volumePercent) { 158 mVolumePercent = volumePercent; 159 } 160 161 /** 162 * Get the volume of the audio track as percentage of the volume in the 163 * original audio source file. 164 * 165 * @return The volume in percentage 166 */ 167 public int getVolume() { 168 return mVolumePercent; 169 } 170 171 /** 172 * Set the start time of this audio track relative to the storyboard 173 * timeline. Default value is 0. 174 * 175 * @param startTimeMs the start time in milliseconds 176 */ 177 public void setStartTime(long startTimeMs) { 178 mStartTimeMs = startTimeMs; 179 } 180 181 /** 182 * Get the start time of this audio track relative to the storyboard 183 * timeline. 184 * 185 * @return The start time in milliseconds 186 */ 187 public long getStartTime() { 188 return mStartTimeMs; 189 } 190 191 /** 192 * @return The duration in milliseconds. This value represents the audio 193 * track duration (not looped) 194 */ 195 public long getDuration() { 196 return mDurationMs; 197 } 198 199 /** 200 * @return The timeline duration. If looping is enabled this value 201 * represents the duration of the looped audio track, otherwise it 202 * is the duration of the audio track (mDurationMs). 203 */ 204 public long getTimelineDuration() { 205 return mTimelineDurationMs; 206 } 207 208 /** 209 * Sets the start and end marks for trimming an audio track 210 * 211 * @param beginMs start time in the audio track in milliseconds (relative to 212 * the beginning of the audio track) 213 * @param endMs end time in the audio track in milliseconds (relative to the 214 * beginning of the audio track) 215 */ 216 public void setExtractBoundaries(long beginMs, long endMs) { 217 if (beginMs > mDurationMs) { 218 throw new IllegalArgumentException("Invalid start time"); 219 } 220 if (endMs > mDurationMs) { 221 throw new IllegalArgumentException("Invalid end time"); 222 } 223 224 mBeginBoundaryTimeMs = beginMs; 225 mEndBoundaryTimeMs = endMs; 226 if (mLoop) { 227 // TODO: Compute mDurationMs (from the beginning of the loop until 228 // the end of all the loops. 229 mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs; 230 } else { 231 mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs; 232 } 233 } 234 235 /** 236 * @return The boundary begin time 237 */ 238 public long getBoundaryBeginTime() { 239 return mBeginBoundaryTimeMs; 240 } 241 242 /** 243 * @return The boundary end time 244 */ 245 public long getBoundaryEndTime() { 246 return mEndBoundaryTimeMs; 247 } 248 249 /** 250 * Enable the loop mode for this audio track. Note that only one of the 251 * audio tracks in the timeline can have the loop mode enabled. When looping 252 * is enabled the samples between mBeginBoundaryTimeMs and 253 * mEndBoundaryTimeMs are looped. 254 */ 255 public void enableLoop() { 256 mLoop = true; 257 } 258 259 /** 260 * Disable the loop mode 261 */ 262 public void disableLoop() { 263 mLoop = false; 264 } 265 266 /** 267 * @return true if looping is enabled 268 */ 269 public boolean isLooping() { 270 return mLoop; 271 } 272 273 /** 274 * Disable the audio duck effect 275 */ 276 public void disableDucking() { 277 mIsDuckingEnabled = false; 278 } 279 280 /** 281 * TODO DEFINE 282 * 283 * @param threshold 284 * @param lowVolume 285 * @param volume 286 */ 287 public void enableDucking(int threshold, int lowVolume, int volume) { 288 mDuckingThreshold = threshold; 289 mDuckingLowVolume = lowVolume; 290 mIsDuckingEnabled = true; 291 } 292 293 /** 294 * @return true if ducking is enabled 295 */ 296 public boolean isDuckingEnabled() { 297 return mIsDuckingEnabled; 298 } 299 300 /** 301 * @return The ducking threshold 302 */ 303 public int getDuckingThreshhold() { 304 return mDuckingThreshold; 305 } 306 307 /** 308 * @return The ducking low level 309 */ 310 public int getDuckingLowVolume() { 311 return mDuckingLowVolume; 312 } 313 314 /** 315 * This API allows to generate a file containing the sample volume levels of 316 * this audio track object. This function may take significant time and is 317 * blocking. The filename can be retrieved using getAudioWaveformFilename(). 318 * 319 * @param listener The progress listener 320 * 321 * @throws IOException if the output file cannot be created 322 * @throws IllegalArgumentException if the audio file does not have a valid 323 * audio track 324 */ 325 public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener) 326 throws IOException { 327 // TODO: Set mAudioWaveformFilename at the end once the extract is 328 // complete 329 } 330 331 /** 332 * Get the audio waveform file name if extractAudioWaveform was successful. 333 * The file format is as following: 334 * <ul> 335 * <li>first 4 bytes provide the number of samples for each value, as 336 * big-endian signed</li> 337 * <li>4 following bytes is the total number of values in the file, as 338 * big-endian signed</li> 339 * <li>then, all values follow as bytes</li> 340 * </ul> 341 * 342 * @return the name of the file, null if the file does not exist 343 */ 344 public String getAudioWaveformFilename() { 345 return mAudioWaveformFilename; 346 } 347 348 /* 349 * {@inheritDoc} 350 */ 351 @Override 352 public boolean equals(Object object) { 353 if (!(object instanceof AudioTrack)) { 354 return false; 355 } 356 return mUniqueId.equals(((AudioTrack)object).mUniqueId); 357 } 358 359 /* 360 * {@inheritDoc} 361 */ 362 @Override 363 public int hashCode() { 364 return mUniqueId.hashCode(); 365 } 366} 367