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