/* * Copyright 2015 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 android.media; import android.annotation.IntDef; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Structure for common playback params. * * Used by {@link AudioTrack} {@link AudioTrack#getPlaybackParams()} and * {@link AudioTrack#setPlaybackParams(PlaybackParams)} * to control playback behavior. * <p> <strong>audio fallback mode:</strong> * select out-of-range parameter handling. * <ul> * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_DEFAULT}: * System will determine best handling. </li> * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_MUTE}: * Play silence for params normally out of range.</li> * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_FAIL}: * Return {@link java.lang.IllegalArgumentException} from * <code>AudioTrack.setPlaybackParams(PlaybackParams)</code>.</li> * </ul> * <p> <strong>pitch:</strong> increases or decreases the tonal frequency of the audio content. * It is expressed as a multiplicative factor, where normal pitch is 1.0f. * <p> <strong>speed:</strong> increases or decreases the time to * play back a set of audio or video frames. * It is expressed as a multiplicative factor, where normal speed is 1.0f. * <p> Different combinations of speed and pitch may be used for audio playback; * some common ones: * <ul> * <li> <em>Pitch equals 1.0f.</em> Speed change will be done with pitch preserved, * often called <em>timestretching</em>.</li> * <li> <em>Pitch equals speed.</em> Speed change will be done by <em>resampling</em>, * similar to {@link AudioTrack#setPlaybackRate(int)}.</li> * </ul> */ public final class PlaybackParams implements Parcelable { /** @hide */ @IntDef( value = { AUDIO_FALLBACK_MODE_DEFAULT, AUDIO_FALLBACK_MODE_MUTE, AUDIO_FALLBACK_MODE_FAIL, } ) @Retention(RetentionPolicy.SOURCE) public @interface AudioFallbackMode {} public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0; public static final int AUDIO_FALLBACK_MODE_MUTE = 1; public static final int AUDIO_FALLBACK_MODE_FAIL = 2; /** @hide */ @IntDef( value = { AUDIO_STRETCH_MODE_DEFAULT, AUDIO_STRETCH_MODE_VOICE, } ) @Retention(RetentionPolicy.SOURCE) public @interface AudioStretchMode {} /** @hide */ public static final int AUDIO_STRETCH_MODE_DEFAULT = 0; /** @hide */ public static final int AUDIO_STRETCH_MODE_VOICE = 1; // flags to indicate which params are actually set private static final int SET_SPEED = 1 << 0; private static final int SET_PITCH = 1 << 1; private static final int SET_AUDIO_FALLBACK_MODE = 1 << 2; private static final int SET_AUDIO_STRETCH_MODE = 1 << 3; private int mSet = 0; // params private int mAudioFallbackMode = AUDIO_FALLBACK_MODE_DEFAULT; private int mAudioStretchMode = AUDIO_STRETCH_MODE_DEFAULT; private float mPitch = 1.0f; private float mSpeed = 1.0f; public PlaybackParams() { } private PlaybackParams(Parcel in) { mSet = in.readInt(); mAudioFallbackMode = in.readInt(); mAudioStretchMode = in.readInt(); mPitch = in.readFloat(); if (mPitch < 0.f) { mPitch = 0.f; } mSpeed = in.readFloat(); } /** * Allows defaults to be returned for properties not set. * Otherwise a {@link java.lang.IllegalArgumentException} exception * is raised when getting those properties * which have defaults but have never been set. * @return this <code>PlaybackParams</code> instance. */ public PlaybackParams allowDefaults() { mSet |= SET_AUDIO_FALLBACK_MODE | SET_AUDIO_STRETCH_MODE | SET_PITCH | SET_SPEED; return this; } /** * Sets the audio fallback mode. * @param audioFallbackMode * @return this <code>PlaybackParams</code> instance. */ public PlaybackParams setAudioFallbackMode(@AudioFallbackMode int audioFallbackMode) { mAudioFallbackMode = audioFallbackMode; mSet |= SET_AUDIO_FALLBACK_MODE; return this; } /** * Retrieves the audio fallback mode. * @return audio fallback mode * @throws IllegalStateException if the audio fallback mode is not set. */ public @AudioFallbackMode int getAudioFallbackMode() { if ((mSet & SET_AUDIO_FALLBACK_MODE) == 0) { throw new IllegalStateException("audio fallback mode not set"); } return mAudioFallbackMode; } /** * @hide * Sets the audio stretch mode. * @param audioStretchMode * @return this <code>PlaybackParams</code> instance. */ public PlaybackParams setAudioStretchMode(@AudioStretchMode int audioStretchMode) { mAudioStretchMode = audioStretchMode; mSet |= SET_AUDIO_STRETCH_MODE; return this; } /** * @hide * Retrieves the audio stretch mode. * @return audio stretch mode * @throws IllegalStateException if the audio stretch mode is not set. */ public @AudioStretchMode int getAudioStretchMode() { if ((mSet & SET_AUDIO_STRETCH_MODE) == 0) { throw new IllegalStateException("audio stretch mode not set"); } return mAudioStretchMode; } /** * Sets the pitch factor. * @param pitch * @return this <code>PlaybackParams</code> instance. * @throws InvalidArgumentException if the pitch is negative */ public PlaybackParams setPitch(float pitch) { if (pitch < 0.f) { throw new IllegalArgumentException("pitch must not be negative"); } mPitch = pitch; mSet |= SET_PITCH; return this; } /** * Retrieves the pitch factor. * @return pitch * @throws IllegalStateException if pitch is not set. */ public float getPitch() { if ((mSet & SET_PITCH) == 0) { throw new IllegalStateException("pitch not set"); } return mPitch; } /** * Sets the speed factor. * @param speed * @return this <code>PlaybackParams</code> instance. */ public PlaybackParams setSpeed(float speed) { mSpeed = speed; mSet |= SET_SPEED; return this; } /** * Retrieves the speed factor. * @return speed * @throws IllegalStateException if speed is not set. */ public float getSpeed() { if ((mSet & SET_SPEED) == 0) { throw new IllegalStateException("speed not set"); } return mSpeed; } public static final Parcelable.Creator<PlaybackParams> CREATOR = new Parcelable.Creator<PlaybackParams>() { @Override public PlaybackParams createFromParcel(Parcel in) { return new PlaybackParams(in); } @Override public PlaybackParams[] newArray(int size) { return new PlaybackParams[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mSet); dest.writeInt(mAudioFallbackMode); dest.writeInt(mAudioStretchMode); dest.writeFloat(mPitch); dest.writeFloat(mSpeed); } }