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