Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright 2015 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 
     17 package android.media;
     18 
     19 import android.annotation.IntDef;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 
     23 import java.lang.annotation.Retention;
     24 import java.lang.annotation.RetentionPolicy;
     25 
     26 /**
     27  * Structure for common playback params.
     28  *
     29  * Used by {@link AudioTrack} {@link AudioTrack#getPlaybackParams()} and
     30  * {@link AudioTrack#setPlaybackParams(PlaybackParams)}
     31  * to control playback behavior.
     32  * <p> <strong>audio fallback mode:</strong>
     33  * select out-of-range parameter handling.
     34  * <ul>
     35  * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_DEFAULT}:
     36  *   System will determine best handling. </li>
     37  * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_MUTE}:
     38  *   Play silence for params normally out of range.</li>
     39  * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_FAIL}:
     40  *   Return {@link java.lang.IllegalArgumentException} from
     41  *   <code>AudioTrack.setPlaybackParams(PlaybackParams)</code>.</li>
     42  * </ul>
     43  * <p> <strong>pitch:</strong> increases or decreases the tonal frequency of the audio content.
     44  * It is expressed as a multiplicative factor, where normal pitch is 1.0f.
     45  * <p> <strong>speed:</strong> increases or decreases the time to
     46  * play back a set of audio or video frames.
     47  * It is expressed as a multiplicative factor, where normal speed is 1.0f.
     48  * <p> Different combinations of speed and pitch may be used for audio playback;
     49  * some common ones:
     50  * <ul>
     51  * <li> <em>Pitch equals 1.0f.</em> Speed change will be done with pitch preserved,
     52  * often called <em>timestretching</em>.</li>
     53  * <li> <em>Pitch equals speed.</em> Speed change will be done by <em>resampling</em>,
     54  * similar to {@link AudioTrack#setPlaybackRate(int)}.</li>
     55  * </ul>
     56  */
     57 public final class PlaybackParams implements Parcelable {
     58     /** @hide */
     59     @IntDef(
     60         value = {
     61                 AUDIO_FALLBACK_MODE_DEFAULT,
     62                 AUDIO_FALLBACK_MODE_MUTE,
     63                 AUDIO_FALLBACK_MODE_FAIL,
     64         }
     65     )
     66     @Retention(RetentionPolicy.SOURCE)
     67     public @interface AudioFallbackMode {}
     68     public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0;
     69     public static final int AUDIO_FALLBACK_MODE_MUTE = 1;
     70     public static final int AUDIO_FALLBACK_MODE_FAIL = 2;
     71 
     72     /** @hide */
     73     @IntDef(
     74         value = {
     75                 AUDIO_STRETCH_MODE_DEFAULT,
     76                 AUDIO_STRETCH_MODE_VOICE,
     77         }
     78     )
     79     @Retention(RetentionPolicy.SOURCE)
     80     public @interface AudioStretchMode {}
     81     /** @hide */
     82     public static final int AUDIO_STRETCH_MODE_DEFAULT = 0;
     83     /** @hide */
     84     public static final int AUDIO_STRETCH_MODE_VOICE = 1;
     85 
     86     // flags to indicate which params are actually set
     87     private static final int SET_SPEED               = 1 << 0;
     88     private static final int SET_PITCH               = 1 << 1;
     89     private static final int SET_AUDIO_FALLBACK_MODE = 1 << 2;
     90     private static final int SET_AUDIO_STRETCH_MODE  = 1 << 3;
     91     private int mSet = 0;
     92 
     93     // params
     94     private int mAudioFallbackMode = AUDIO_FALLBACK_MODE_DEFAULT;
     95     private int mAudioStretchMode = AUDIO_STRETCH_MODE_DEFAULT;
     96     private float mPitch = 1.0f;
     97     private float mSpeed = 1.0f;
     98 
     99     public PlaybackParams() {
    100     }
    101 
    102     private PlaybackParams(Parcel in) {
    103         mSet = in.readInt();
    104         mAudioFallbackMode = in.readInt();
    105         mAudioStretchMode = in.readInt();
    106         mPitch = in.readFloat();
    107         if (mPitch < 0.f) {
    108             mPitch = 0.f;
    109         }
    110         mSpeed = in.readFloat();
    111     }
    112 
    113     /**
    114      * Allows defaults to be returned for properties not set.
    115      * Otherwise a {@link java.lang.IllegalArgumentException} exception
    116      * is raised when getting those properties
    117      * which have defaults but have never been set.
    118      * @return this <code>PlaybackParams</code> instance.
    119      */
    120     public PlaybackParams allowDefaults() {
    121         mSet |= SET_AUDIO_FALLBACK_MODE | SET_AUDIO_STRETCH_MODE | SET_PITCH | SET_SPEED;
    122         return this;
    123     }
    124 
    125     /**
    126      * Sets the audio fallback mode.
    127      * @param audioFallbackMode
    128      * @return this <code>PlaybackParams</code> instance.
    129      */
    130     public PlaybackParams setAudioFallbackMode(@AudioFallbackMode int audioFallbackMode) {
    131         mAudioFallbackMode = audioFallbackMode;
    132         mSet |= SET_AUDIO_FALLBACK_MODE;
    133         return this;
    134     }
    135 
    136     /**
    137      * Retrieves the audio fallback mode.
    138      * @return audio fallback mode
    139      * @throws IllegalStateException if the audio fallback mode is not set.
    140      */
    141     public @AudioFallbackMode int getAudioFallbackMode() {
    142         if ((mSet & SET_AUDIO_FALLBACK_MODE) == 0) {
    143             throw new IllegalStateException("audio fallback mode not set");
    144         }
    145         return mAudioFallbackMode;
    146     }
    147 
    148     /**
    149      * @hide
    150      * Sets the audio stretch mode.
    151      * @param audioStretchMode
    152      * @return this <code>PlaybackParams</code> instance.
    153      */
    154     public PlaybackParams setAudioStretchMode(@AudioStretchMode int audioStretchMode) {
    155         mAudioStretchMode = audioStretchMode;
    156         mSet |= SET_AUDIO_STRETCH_MODE;
    157         return this;
    158     }
    159 
    160     /**
    161      * @hide
    162      * Retrieves the audio stretch mode.
    163      * @return audio stretch mode
    164      * @throws IllegalStateException if the audio stretch mode is not set.
    165      */
    166     public @AudioStretchMode int getAudioStretchMode() {
    167         if ((mSet & SET_AUDIO_STRETCH_MODE) == 0) {
    168             throw new IllegalStateException("audio stretch mode not set");
    169         }
    170         return mAudioStretchMode;
    171     }
    172 
    173     /**
    174      * Sets the pitch factor.
    175      * @param pitch
    176      * @return this <code>PlaybackParams</code> instance.
    177      * @throws InvalidArgumentException if the pitch is negative
    178      */
    179     public PlaybackParams setPitch(float pitch) {
    180         if (pitch < 0.f) {
    181             throw new IllegalArgumentException("pitch must not be negative");
    182         }
    183         mPitch = pitch;
    184         mSet |= SET_PITCH;
    185         return this;
    186     }
    187 
    188     /**
    189      * Retrieves the pitch factor.
    190      * @return pitch
    191      * @throws IllegalStateException if pitch is not set.
    192      */
    193     public float getPitch() {
    194         if ((mSet & SET_PITCH) == 0) {
    195             throw new IllegalStateException("pitch not set");
    196         }
    197         return mPitch;
    198     }
    199 
    200     /**
    201      * Sets the speed factor.
    202      * @param speed
    203      * @return this <code>PlaybackParams</code> instance.
    204      */
    205     public PlaybackParams setSpeed(float speed) {
    206         mSpeed = speed;
    207         mSet |= SET_SPEED;
    208         return this;
    209     }
    210 
    211     /**
    212      * Retrieves the speed factor.
    213      * @return speed
    214      * @throws IllegalStateException if speed is not set.
    215      */
    216     public float getSpeed() {
    217         if ((mSet & SET_SPEED) == 0) {
    218             throw new IllegalStateException("speed not set");
    219         }
    220         return mSpeed;
    221     }
    222 
    223     public static final Parcelable.Creator<PlaybackParams> CREATOR =
    224             new Parcelable.Creator<PlaybackParams>() {
    225                 @Override
    226                 public PlaybackParams createFromParcel(Parcel in) {
    227                     return new PlaybackParams(in);
    228                 }
    229 
    230                 @Override
    231                 public PlaybackParams[] newArray(int size) {
    232                     return new PlaybackParams[size];
    233                 }
    234             };
    235 
    236 
    237     @Override
    238     public int describeContents() {
    239         return 0;
    240     }
    241 
    242     @Override
    243     public void writeToParcel(Parcel dest, int flags) {
    244         dest.writeInt(mSet);
    245         dest.writeInt(mAudioFallbackMode);
    246         dest.writeInt(mAudioStretchMode);
    247         dest.writeFloat(mPitch);
    248         dest.writeFloat(mSpeed);
    249     }
    250 }
    251