summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndy Hung <hunga@google.com>2015-04-16 11:16:29 -0700
committerAndy Hung <hunga@google.com>2015-04-22 15:27:16 -0700
commit263b4c97823295c41900210515d0c769a236190c (patch)
treef83297d461673ad3625a95295722d554bb0283fc /media
parent73d74680b707d1f3ef7e3d0a21729501724e98f2 (diff)
downloadframeworks_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.java65
-rw-r--r--media/java/android/media/PlaybackSettings.java206
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;
+ }
+}