diff options
author | Andy Hung <hunga@google.com> | 2015-04-16 11:16:29 -0700 |
---|---|---|
committer | Andy Hung <hunga@google.com> | 2015-04-22 15:27:16 -0700 |
commit | 263b4c97823295c41900210515d0c769a236190c (patch) | |
tree | f83297d461673ad3625a95295722d554bb0283fc /media | |
parent | 73d74680b707d1f3ef7e3d0a21729501724e98f2 (diff) | |
download | frameworks_base-263b4c97823295c41900210515d0c769a236190c.zip frameworks_base-263b4c97823295c41900210515d0c769a236190c.tar.gz frameworks_base-263b4c97823295c41900210515d0c769a236190c.tar.bz2 |
Add PlaybackSettings for use with AudioTrack
Change-Id: Ie59686d46869558d489a7600170ddace00e548d5
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/AudioTrack.java | 65 | ||||
-rw-r--r-- | media/java/android/media/PlaybackSettings.java | 206 |
2 files changed, 270 insertions, 1 deletions
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index ded9d31..093ff26 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -946,13 +946,30 @@ public class AudioTrack } /** - * Returns the current playback rate in Hz. + * Returns the current playback sample rate rate in Hz. */ public int getPlaybackRate() { return native_get_playback_rate(); } /** + * Returns the current playback settings. + * See {@link #setPlaybackSettings(PlaybackSettings)} to set playback settings + * @return current {@link PlaybackSettings}. + * @throws IllegalStateException if track is not initialized. + */ + public @NonNull PlaybackSettings getPlaybackSettings() { + float[] floatArray = new float[2]; + int[] intArray = new int[2]; + native_get_playback_settings(floatArray, intArray); + return new PlaybackSettings() + .setSpeed(floatArray[0]) + .setPitch(floatArray[1]) + .setAudioFallbackMode(intArray[0]) + .setAudioStretchMode(intArray[1]); + } + + /** * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT} * and {@link AudioFormat#ENCODING_PCM_8BIT}. */ @@ -1307,6 +1324,7 @@ public class AudioTrack * playback to last twice as long, but will also result in a pitch shift down by one octave. * The valid sample rate range is from 1 Hz to twice the value returned by * {@link #getNativeOutputSampleRate(int)}. + * Use {@link #setPlaybackSettings(PlaybackSettings)} for speed control. * @param sampleRateInHz the sample rate expressed in Hz * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, * {@link #ERROR_INVALID_OPERATION} @@ -1323,6 +1341,42 @@ public class AudioTrack /** + * Sets the playback settings. + * This method returns failure if it cannot apply the playback settings. + * One possible cause is that the parameters for speed or pitch are out of range. + * Another possible cause is that the <code>AudioTrack</code> is streaming + * (see {@link #MODE_STREAM}) and the + * buffer size is too small. For speeds greater than 1.0f, the <code>AudioTrack</code> buffer + * on configuration must be larger than the speed multiplied by the minimum size + * {@link #getMinBufferSize(int, int, int)}) to allow proper playback. + * @param settings see {@link PlaybackSettings}. In particular, + * speed, pitch, and audio mode should be set. + * @throws IllegalArgumentException if the settings are invalid or not accepted. + * @throws IllegalStateException if track is not initialized. + */ + public void setPlaybackSettings(@NonNull PlaybackSettings settings) { + if (settings == null) { + throw new IllegalArgumentException("settings is null"); + } + float[] floatArray; + int[] intArray; + try { + floatArray = new float[] { + settings.getSpeed(), + settings.getPitch(), + }; + intArray = new int[] { + settings.getAudioFallbackMode(), + settings.getAudioStretchMode(), + }; + } catch (IllegalStateException e) { + throw new IllegalArgumentException(e); + } + native_set_playback_settings(floatArray, intArray); + } + + + /** * Sets the position of the notification marker. At most one marker can be active. * @param markerInFrames marker position in wrapping frame units similar to * {@link #getPlaybackHeadPosition}, or zero to disable the marker. @@ -2207,6 +2261,15 @@ public class AudioTrack private native final int native_set_playback_rate(int sampleRateInHz); private native final int native_get_playback_rate(); + // floatArray must be a non-null array of length >= 2 + // [0] is speed + // [1] is pitch + // intArray must be a non-null array of length >= 2 + // [0] is audio fallback mode + // [1] is audio stretch mode + private native final void native_set_playback_settings(float[] floatArray, int[] intArray); + private native final void native_get_playback_settings(float[] floatArray, int[] intArray); + private native final int native_set_marker_pos(int marker); private native final int native_get_marker_pos(); diff --git a/media/java/android/media/PlaybackSettings.java b/media/java/android/media/PlaybackSettings.java new file mode 100644 index 0000000..ceb6bb1 --- /dev/null +++ b/media/java/android/media/PlaybackSettings.java @@ -0,0 +1,206 @@ +/* + * 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 java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import android.annotation.IntDef; + +/** + * Structure for common playback settings. + * + * Used by {@link AudioTrack} {@link AudioTrack#getPlaybackSettings()} and + * {@link AudioTrack#setPlaybackSettings(PlaybackSettings)} + * to control playback behavior. + * <p> <strong>audio fallback mode:</strong> + * select out-of-range parameter handling. + * <ul> + * <li> {@link PlaybackSettings#AUDIO_FALLBACK_MODE_DEFAULT}: + * System will determine best handling. </li> + * <li> {@link PlaybackSettings#AUDIO_FALLBACK_MODE_MUTE}: + * Play silence for settings normally out of range.</li> + * <li> {@link PlaybackSettings#AUDIO_FALLBACK_MODE_FAIL}: + * Return {@link java.lang.IllegalArgumentException} from + * <code>AudioTrack.setPlaybackSettings(PlaybackSettings)</code>.</li> + * </ul> + * <p> <strong>audio stretch mode:</strong> select + * timestretch handling. + * <ul> + * <li> {@link PlaybackSettings#AUDIO_STRETCH_MODE_DEFAULT}: + * System will determine best selection. </li> + * <li> {@link PlaybackSettings#AUDIO_STRETCH_MODE_VOICE}: + * Content is primarily voice.</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 PlaybackSettings { + /** @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 {} + public static final int AUDIO_STRETCH_MODE_DEFAULT = 0; + public static final int AUDIO_STRETCH_MODE_VOICE = 1; + + // flags to indicate which settings 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; + + // settings + private int mAudioFallbackMode = AUDIO_FALLBACK_MODE_DEFAULT; + private int mAudioStretchMode = AUDIO_STRETCH_MODE_DEFAULT; + private float mPitch = 1.0f; + private float mSpeed = 1.0f; + + /** + * 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>PlaybackSettings</code> instance. + */ + public PlaybackSettings 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>PlaybackSettings</code> instance. + */ + public PlaybackSettings 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; + } + + /** + * Sets the audio stretch mode. + * @param audioStretchMode + * @return this <code>PlaybackSettings</code> instance. + */ + public PlaybackSettings setAudioStretchMode(@AudioStretchMode int audioStretchMode) { + mAudioStretchMode = audioStretchMode; + mSet |= SET_AUDIO_STRETCH_MODE; + return this; + } + + /** + * 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>PlaybackSettings</code> instance. + */ + public PlaybackSettings setPitch(float pitch) { + 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>PlaybackSettings</code> instance. + */ + public PlaybackSettings 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; + } +} |