/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.videoeditor.service; import java.io.IOException; import roughcut.media.videoeditor.AudioTrack; import roughcut.media.videoeditor.MediaProperties; import roughcut.media.videoeditor.VideoEditor; import roughcut.media.videoeditor.WaveformData; /** * This class represents an audio track in the user interface */ public class MovieAudioTrack { // Instance variables private final String mUniqueId; private final String mFilename; private final int mRawResourceId; private final long mDurationMs; private long mStartTimeMs; private long mTimelineDurationMs; private int mVolumePercent; private boolean mMuted; private long mBeginBoundaryTimeMs; private long mEndBoundaryTimeMs; private boolean mLoop; private final int mAudioChannels; private final int mAudioType; private final int mAudioBitrate; private final int mAudioSamplingFrequency; // Ducking variables private boolean mIsDuckingEnabled; // The audio waveform data private WaveformData mWaveformData; private long mAppStartTimeMs; private int mAppVolumePercent; private boolean mAppMuted; private boolean mAppIsDuckingEnabled; private boolean mAppLoop; /** * An object of this type cannot be instantiated by using the default * constructor */ @SuppressWarnings("unused") private MovieAudioTrack() throws IOException { this((AudioTrack)null); } /** * Constructor * * @param audioTrack The audio track */ MovieAudioTrack(AudioTrack audioTrack) { mUniqueId = audioTrack.getId(); mFilename = audioTrack.getFilename(); mRawResourceId = 0; mAppStartTimeMs = mStartTimeMs = audioTrack.getStartTime(); mDurationMs = audioTrack.getDuration(); mBeginBoundaryTimeMs = audioTrack.getBoundaryBeginTime(); mEndBoundaryTimeMs = audioTrack.getBoundaryEndTime(); mAudioChannels = audioTrack.getAudioChannels(); mAudioType = audioTrack.getAudioType(); mAudioBitrate = audioTrack.getAudioBitrate(); mAudioSamplingFrequency = audioTrack.getAudioSamplingFrequency(); mAppVolumePercent = mVolumePercent = audioTrack.getVolume(); mAppMuted = mMuted = audioTrack.isMuted(); mAppLoop = mLoop = audioTrack.isLooping(); mAppIsDuckingEnabled = mIsDuckingEnabled = audioTrack.isDuckingEnabled(); try { mWaveformData = audioTrack.getWaveformData(); } catch (Exception ex) { mWaveformData = null; } mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs; } /** * Constructor * * @param resId The audio track raw resource id */ MovieAudioTrack(int resId) { mUniqueId = null; mFilename = null; mRawResourceId = resId; mAppStartTimeMs = mStartTimeMs = 0; mDurationMs = VideoEditor.DURATION_OF_STORYBOARD; mBeginBoundaryTimeMs = mStartTimeMs; mEndBoundaryTimeMs = mDurationMs; mAudioChannels = 0; mAudioType = MediaProperties.ACODEC_AAC_LC; mAudioBitrate = 0; mAudioSamplingFrequency = 0; mAppVolumePercent = mVolumePercent = 100; mAppMuted = mMuted = false; mAppLoop = mLoop = true; mAppIsDuckingEnabled = mIsDuckingEnabled = true; mWaveformData = null; mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs; } /** * @return The id of the media item */ public String getId() { return mUniqueId; } /** * @return The raw resource id */ public int getRawResourceId() { return mRawResourceId; } /** * Get the filename source for this audio track. * * @return The filename as an absolute file name */ public String getFilename() { return mFilename; } /** * @return The number of audio channels in the source of this audio track */ public int getAudioChannels() { return mAudioChannels; } /** * @return The audio codec of the source of this audio track */ public int getAudioType() { return mAudioType; } /** * @return The audio sample frequency of the audio track */ public int getAudioSamplingFrequency() { return mAudioSamplingFrequency; } /** * @return The audio bitrate of the audio track */ public int getAudioBitrate() { return mAudioBitrate; } /** * Set the volume of this audio track as percentage of the volume in the * original audio source file. * * @param volumePercent Percentage of the volume to apply. If it is set to * 0, then volume becomes mute. It it is set to 100, then volume * is same as original volume. It it is set to 200, then volume * is doubled (provided that volume amplification is supported) * @throws UnsupportedOperationException if volume amplification is requested * and is not supported. */ void setVolume(int volumePercent) { mVolumePercent = volumePercent; } /** * Get the volume of the audio track as percentage of the volume in the * original audio source file. * * @return The volume in percentage */ int getVolume() { return mVolumePercent; } /** * Set the volume of this audio track as percentage of the volume in the * original audio source file. * * @param volumePercent Percentage of the volume to apply. If it is set to * 0, then volume becomes mute. It it is set to 100, then volume * is same as original volume. It it is set to 200, then volume * is doubled (provided that volume amplification is supported) * @throws UnsupportedOperationException if volume amplification is requested * and is not supported. */ public void setAppVolume(int volumePercent) { mAppVolumePercent = volumePercent; } /** * Get the volume of the audio track as percentage of the volume in the * original audio source file. * * @return The volume in percentage */ public int getAppVolume() { return mAppVolumePercent; } /** * @param muted true to mute the audio track */ void setMute(boolean muted) { mMuted = muted; } /** * @return true if the audio track is muted */ boolean isMuted() { return mMuted; } /** * @param muted true to mute the audio track */ public void setAppMute(boolean muted) { mAppMuted = muted; } /** * @return true if the audio track is muted */ public boolean isAppMuted() { return mAppMuted; } /** * Set the start time of this audio track relative to the storyboard * timeline. Default value is 0. * * @param startTimeMs the start time in milliseconds */ void setStartTime(long startTimeMs) { mStartTimeMs = startTimeMs; } /** * Get the start time of this audio track relative to the storyboard * timeline. * * @return The start time in milliseconds */ public long getStartTime() { return mStartTimeMs; } /** * Set the start time of this audio track relative to the storyboard * timeline. Default value is 0. * * @param startTimeMs the start time in milliseconds */ public void setAppStartTime(long startTimeMs) { mAppStartTimeMs = startTimeMs; } /** * Get the start time of this audio track relative to the storyboard * timeline. * * @return The start time in milliseconds */ public long getAppStartTime() { return mAppStartTimeMs; } /** * @return The duration in milliseconds. This value represents the audio * track duration (not looped) */ public long getDuration() { return mDurationMs; } /** * @return The timeline duration. */ public long getTimelineDuration() { return mTimelineDurationMs; } /** * Sets the start and end marks for trimming an audio track * * @param beginMs start time in the audio track in milliseconds (relative to * the beginning of the audio track) * @param endMs end time in the audio track in milliseconds (relative to the * beginning of the audio track) */ void setExtractBoundaries(long beginMs, long endMs) { mBeginBoundaryTimeMs = beginMs; mEndBoundaryTimeMs = endMs; mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs; } /** * @return The boundary begin time */ public long getBoundaryBeginTime() { return mBeginBoundaryTimeMs; } /** * @return The boundary end time */ public long getBoundaryEndTime() { return mEndBoundaryTimeMs; } /** * Enable the loop mode for this audio track. Note that only one of the * audio tracks in the timeline can have the loop mode enabled. When looping * is enabled the samples between mBeginBoundaryTimeMs and * mEndBoundaryTimeMs are looped. * * @param loop true to enable looping */ void enableLoop(boolean loop) { mLoop = loop; } /** * @return true if looping is enabled */ boolean isLooping() { return mLoop; } /** * Enable the loop mode for this audio track. Note that only one of the * audio tracks in the timeline can have the loop mode enabled. When looping * is enabled the samples between mBeginBoundaryTimeMs and * mEndBoundaryTimeMs are looped. * * @param loop true to enable looping */ public void enableAppLoop(boolean loop) { mAppLoop = loop; } /** * @return true if looping is enabled */ public boolean isAppLooping() { return mAppLoop; } /** * Enable/disable ducking * * @param enabled true to enable ducking */ void enableDucking(boolean enabled) { mIsDuckingEnabled = enabled; } /** * @return true if ducking is enabled */ boolean isDuckingEnabled() { return mIsDuckingEnabled; } /** * Enable/disable ducking * * @param enabled true to enable ducking */ public void enableAppDucking(boolean enabled) { mAppIsDuckingEnabled = enabled; } /** * @return true if ducking is enabled */ public boolean isAppDuckingEnabled() { return mAppIsDuckingEnabled; } /** * @return The waveform data */ public WaveformData getWaveformData() { return mWaveformData; } /** * @param waveformData The audio waveform data */ void setWaveformData(WaveformData waveformData) { mWaveformData = waveformData; } /* * {@inheritDoc} */ @Override public boolean equals(Object object) { if (!(object instanceof MovieAudioTrack)) { return false; } return mUniqueId.equals(((MovieAudioTrack)object).mUniqueId); } /* * {@inheritDoc} */ @Override public int hashCode() { return mUniqueId.hashCode(); } }