AudioTrack.java revision 7bfcabbb9e5425985b2f2ffe095949e290a8a4ae
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 media items. 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 mDuckedTrackVolume; 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 mDuckedTrackVolume = 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 threshold Ducking will be activated when the relative energy in 124 * the media items audio signal goes above this value. The valid 125 * range of values is 0 to 100. 126 * @param duckedTrackVolume The relative volume of the audio track when ducking 127 * is active. The valid range of values is 0 to 100. 128 * @param audioWaveformFilename The name of the waveform file 129 * 130 * @throws IOException if file is not found 131 */ 132 AudioTrack(VideoEditor editor, String audioTrackId, String filename, long startTimeMs, 133 long beginMs, long endMs, boolean loop, int volume, boolean muted, 134 boolean duckingEnabled, int duckThreshold, int duckedTrackVolume, 135 String audioWaveformFilename) throws IOException { 136 mUniqueId = audioTrackId; 137 mFilename = filename; 138 mStartTimeMs = startTimeMs; 139 140 // TODO: This value represents to the duration of the audio file 141 mDurationMs = 300000; 142 143 // TODO: This value needs to be read from the audio track of the source 144 // file 145 mAudioChannels = 2; 146 mAudioType = MediaProperties.ACODEC_AAC_LC; 147 mAudioBitrate = 128000; 148 mAudioSamplingFrequency = 44100; 149 150 mTimelineDurationMs = endMs - beginMs; 151 mVolumePercent = volume; 152 153 mBeginBoundaryTimeMs = beginMs; 154 mEndBoundaryTimeMs = endMs; 155 156 mLoop = loop; 157 mMuted = muted; 158 159 mIsDuckingEnabled = duckingEnabled; 160 mDuckingThreshold = duckThreshold; 161 mDuckedTrackVolume = duckedTrackVolume; 162 163 mAudioWaveformFilename = audioWaveformFilename; 164 } 165 166 /** 167 * @return The id of the audio track 168 */ 169 public String getId() { 170 return mUniqueId; 171 } 172 173 /** 174 * Get the filename source for this audio track. 175 * 176 * @return The filename as an absolute file name 177 */ 178 public String getFilename() { 179 return mFilename; 180 } 181 182 /** 183 * @return The number of audio channels in the source of this audio track 184 */ 185 public int getAudioChannels() { 186 return mAudioChannels; 187 } 188 189 /** 190 * @return The audio codec of the source of this audio track 191 */ 192 public int getAudioType() { 193 return mAudioType; 194 } 195 196 /** 197 * @return The audio sample frequency of the audio track 198 */ 199 public int getAudioSamplingFrequency() { 200 return mAudioSamplingFrequency; 201 } 202 203 /** 204 * @return The audio bitrate of the audio track 205 */ 206 public int getAudioBitrate() { 207 return mAudioBitrate; 208 } 209 210 /** 211 * Set the volume of this audio track as percentage of the volume in the 212 * original audio source file. 213 * 214 * @param volumePercent Percentage of the volume to apply. If it is set to 215 * 0, then volume becomes mute. It it is set to 100, then volume 216 * is same as original volume. It it is set to 200, then volume 217 * is doubled (provided that volume amplification is supported) 218 * 219 * @throws UnsupportedOperationException if volume amplification is 220 * requested and is not supported. 221 */ 222 public void setVolume(int volumePercent) { 223 mVolumePercent = volumePercent; 224 } 225 226 /** 227 * Get the volume of the audio track as percentage of the volume in the 228 * original audio source file. 229 * 230 * @return The volume in percentage 231 */ 232 public int getVolume() { 233 return mVolumePercent; 234 } 235 236 /** 237 * @param muted true to mute the audio track 238 */ 239 public void setMute(boolean muted) { 240 mMuted = muted; 241 } 242 243 /** 244 * @return true if the audio track is muted 245 */ 246 public boolean isMuted() { 247 return mMuted; 248 } 249 250 /** 251 * Set the start time of this audio track relative to the storyboard 252 * timeline. Default value is 0. 253 * 254 * @param startTimeMs the start time in milliseconds 255 */ 256 public void setStartTime(long startTimeMs) { 257 mStartTimeMs = startTimeMs; 258 } 259 260 /** 261 * Get the start time of this audio track relative to the storyboard 262 * timeline. 263 * 264 * @return The start time in milliseconds 265 */ 266 public long getStartTime() { 267 return mStartTimeMs; 268 } 269 270 /** 271 * @return The duration in milliseconds. This value represents the audio 272 * track duration (not looped) 273 */ 274 public long getDuration() { 275 return mDurationMs; 276 } 277 278 /** 279 * @return The timeline duration. If looping is enabled this value 280 * represents the duration of the looped audio track, otherwise it 281 * is the duration of the audio track (mDurationMs). 282 */ 283 public long getTimelineDuration() { 284 return mTimelineDurationMs; 285 } 286 287 /** 288 * Sets the start and end marks for trimming an audio track 289 * 290 * @param beginMs start time in the audio track in milliseconds (relative to 291 * the beginning of the audio track) 292 * @param endMs end time in the audio track in milliseconds (relative to the 293 * beginning of the audio track) 294 */ 295 public void setExtractBoundaries(long beginMs, long endMs) { 296 if (beginMs > mDurationMs) { 297 throw new IllegalArgumentException("Invalid start time"); 298 } 299 if (endMs > mDurationMs) { 300 throw new IllegalArgumentException("Invalid end time"); 301 } 302 303 mBeginBoundaryTimeMs = beginMs; 304 mEndBoundaryTimeMs = endMs; 305 if (mLoop) { 306 // TODO: Compute mDurationMs (from the beginning of the loop until 307 // the end of all the loops. 308 mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs; 309 } else { 310 mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs; 311 } 312 } 313 314 /** 315 * @return The boundary begin time 316 */ 317 public long getBoundaryBeginTime() { 318 return mBeginBoundaryTimeMs; 319 } 320 321 /** 322 * @return The boundary end time 323 */ 324 public long getBoundaryEndTime() { 325 return mEndBoundaryTimeMs; 326 } 327 328 /** 329 * Enable the loop mode for this audio track. Note that only one of the 330 * audio tracks in the timeline can have the loop mode enabled. When looping 331 * is enabled the samples between mBeginBoundaryTimeMs and 332 * mEndBoundaryTimeMs are looped. 333 */ 334 public void enableLoop() { 335 mLoop = true; 336 } 337 338 /** 339 * Disable the loop mode 340 */ 341 public void disableLoop() { 342 mLoop = false; 343 } 344 345 /** 346 * @return true if looping is enabled 347 */ 348 public boolean isLooping() { 349 return mLoop; 350 } 351 352 /** 353 * Disable the audio duck effect 354 */ 355 public void disableDucking() { 356 mIsDuckingEnabled = false; 357 } 358 359 /** 360 * Enable ducking by specifying the required parameters 361 * 362 * @param threshold Ducking will be activated when the relative energy in 363 * the media items audio signal goes above this value. The valid 364 * range of values is 0 to 100. 365 * @param duckedTrackVolume The relative volume of the audio track when ducking 366 * is active. The valid range of values is 0 to 100. 367 */ 368 public void enableDucking(int threshold, int duckedTrackVolume) { 369 if (threshold < 0 || threshold > 100) { 370 throw new IllegalArgumentException("Invalid threshold value: " + threshold); 371 } 372 373 if (duckedTrackVolume < 0 || duckedTrackVolume > 100) { 374 throw new IllegalArgumentException("Invalid duckedTrackVolume value: " 375 + duckedTrackVolume); 376 } 377 378 mDuckingThreshold = threshold; 379 mDuckedTrackVolume = duckedTrackVolume; 380 mIsDuckingEnabled = true; 381 } 382 383 /** 384 * @return true if ducking is enabled 385 */ 386 public boolean isDuckingEnabled() { 387 return mIsDuckingEnabled; 388 } 389 390 /** 391 * @return The ducking threshold 392 */ 393 public int getDuckingThreshhold() { 394 return mDuckingThreshold; 395 } 396 397 /** 398 * @return The ducked track volume 399 */ 400 public int getDuckedTrackVolume() { 401 return mDuckedTrackVolume; 402 } 403 404 /** 405 * This API allows to generate a file containing the sample volume levels of 406 * this audio track object. This function may take significant time and is 407 * blocking. The filename can be retrieved using getAudioWaveformFilename(). 408 * 409 * @param listener The progress listener 410 * 411 * @throws IOException if the output file cannot be created 412 * @throws IllegalArgumentException if the audio file does not have a valid 413 * audio track 414 */ 415 public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener) 416 throws IOException { 417 // TODO: Set mAudioWaveformFilename at the end once the extract is 418 // complete 419 } 420 421 /** 422 * Get the audio waveform file name if extractAudioWaveform was successful. 423 * The file format is as following: 424 * <ul> 425 * <li>first 4 bytes provide the number of samples for each value, as 426 * big-endian signed</li> 427 * <li>4 following bytes is the total number of values in the file, as 428 * big-endian signed</li> 429 * <li>then, all values follow as bytes</li> 430 * </ul> 431 * 432 * @return the name of the file, null if the file does not exist 433 */ 434 public String getAudioWaveformFilename() { 435 return mAudioWaveformFilename; 436 } 437 438 /* 439 * {@inheritDoc} 440 */ 441 @Override 442 public boolean equals(Object object) { 443 if (!(object instanceof AudioTrack)) { 444 return false; 445 } 446 return mUniqueId.equals(((AudioTrack)object).mUniqueId); 447 } 448 449 /* 450 * {@inheritDoc} 451 */ 452 @Override 453 public int hashCode() { 454 return mUniqueId.hashCode(); 455 } 456} 457