Loading api/current.txt +20 −0 Original line number Diff line number Diff line Loading @@ -14995,6 +14995,7 @@ package android.media { method public int getPlayState(); method public int getPlaybackHeadPosition(); method public int getPlaybackRate(); method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public int getSampleRate(); Loading @@ -15012,6 +15013,7 @@ package android.media { method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener); method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener, android.os.Handler); method public int setPlaybackRate(int); method public void setPlaybackSettings(android.media.PlaybackSettings); method public int setPositionNotificationPeriod(int); method public boolean setPreferredOutputDevice(android.media.AudioDeviceInfo); method protected deprecated void setState(int); Loading Loading @@ -16375,6 +16377,24 @@ package android.media { method public abstract void onAudioDeviceConnection(); } public final class PlaybackSettings { ctor public PlaybackSettings(); method public android.media.PlaybackSettings allowDefaults(); method public int getAudioFallbackMode(); method public int getAudioStretchMode(); method public float getPitch(); method public float getSpeed(); method public android.media.PlaybackSettings setAudioFallbackMode(int); method public android.media.PlaybackSettings setAudioStretchMode(int); method public android.media.PlaybackSettings setPitch(float); method public android.media.PlaybackSettings setSpeed(float); field public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_FALLBACK_MODE_FAIL = 2; // 0x2 field public static final int AUDIO_FALLBACK_MODE_MUTE = 1; // 0x1 field public static final int AUDIO_STRETCH_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating(); api/system-current.txt +20 −0 Original line number Diff line number Diff line Loading @@ -16207,6 +16207,7 @@ package android.media { method public int getPlayState(); method public int getPlaybackHeadPosition(); method public int getPlaybackRate(); method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public int getSampleRate(); Loading @@ -16224,6 +16225,7 @@ package android.media { method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener); method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener, android.os.Handler); method public int setPlaybackRate(int); method public void setPlaybackSettings(android.media.PlaybackSettings); method public int setPositionNotificationPeriod(int); method public boolean setPreferredOutputDevice(android.media.AudioDeviceInfo); method protected deprecated void setState(int); Loading Loading @@ -17590,6 +17592,24 @@ package android.media { method public abstract void onAudioDeviceConnection(); } public final class PlaybackSettings { ctor public PlaybackSettings(); method public android.media.PlaybackSettings allowDefaults(); method public int getAudioFallbackMode(); method public int getAudioStretchMode(); method public float getPitch(); method public float getSpeed(); method public android.media.PlaybackSettings setAudioFallbackMode(int); method public android.media.PlaybackSettings setAudioStretchMode(int); method public android.media.PlaybackSettings setPitch(float); method public android.media.PlaybackSettings setSpeed(float); field public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_FALLBACK_MODE_FAIL = 2; // 0x2 field public static final int AUDIO_FALLBACK_MODE_MUTE = 1; // 0x1 field public static final int AUDIO_STRETCH_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating(); core/jni/android_media_AudioTrack.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -676,6 +676,63 @@ static jint android_media_AudioTrack_get_playback_rate(JNIEnv *env, jobject thi } // ---------------------------------------------------------------------------- static void android_media_AudioTrack_set_playback_settings(JNIEnv *env, jobject thiz, jfloatArray floatArray, jintArray intArray) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "AudioTrack not initialized"); return; } // NOTE: Get<Primitive>ArrayRegion throws ArrayIndexOutOfBoundsException if not valid. // TODO: consider the actual occupancy. float farray[2]; int iarray[2]; if ((env->GetFloatArrayRegion(floatArray, 0, 2, farray), env->ExceptionCheck()) == JNI_FALSE && (env->GetIntArrayRegion(intArray, 0, 2, iarray), env->ExceptionCheck()) == JNI_FALSE) { // arrays retrieved OK AudioPlaybackRate playbackRate; playbackRate.mSpeed = farray[0]; playbackRate.mPitch = farray[1]; playbackRate.mFallbackMode = (AudioTimestretchFallbackMode)iarray[0]; playbackRate.mStretchMode = (AudioTimestretchStretchMode)iarray[1]; if (lpTrack->setPlaybackRate(playbackRate) != OK) { jniThrowException(env, "java/lang/IllegalArgumentException", "arguments out of range"); } } } // ---------------------------------------------------------------------------- static void android_media_AudioTrack_get_playback_settings(JNIEnv *env, jobject thiz, jfloatArray floatArray, jintArray intArray) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "AudioTrack not initialized"); return; } AudioPlaybackRate playbackRate = lpTrack->getPlaybackRate(); float farray[2] = { playbackRate.mSpeed, playbackRate.mPitch, }; int iarray[2] = { playbackRate.mFallbackMode, playbackRate.mStretchMode, }; // NOTE: Set<Primitive>ArrayRegion throws ArrayIndexOutOfBoundsException if not valid. env->SetFloatArrayRegion(floatArray, 0, 2, farray); env->SetIntArrayRegion(intArray, 0, 2, iarray); } // ---------------------------------------------------------------------------- static jint android_media_AudioTrack_set_marker_pos(JNIEnv *env, jobject thiz, jint markerPos) { Loading Loading @@ -942,6 +999,10 @@ static JNINativeMethod gMethods[] = { "(I)I", (void *)android_media_AudioTrack_set_playback_rate}, {"native_get_playback_rate", "()I", (void *)android_media_AudioTrack_get_playback_rate}, {"native_set_playback_settings", "([F[I)V", (void *)android_media_AudioTrack_set_playback_settings}, {"native_get_playback_settings", "([F[I)V", (void *)android_media_AudioTrack_get_playback_settings}, {"native_set_marker_pos","(I)I", (void *)android_media_AudioTrack_set_marker_pos}, {"native_get_marker_pos","()I", (void *)android_media_AudioTrack_get_marker_pos}, {"native_set_pos_update_period", Loading media/java/android/media/AudioTrack.java +64 −1 Original line number Diff line number Diff line Loading @@ -946,12 +946,29 @@ 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}. Loading Loading @@ -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} Loading @@ -1322,6 +1340,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 Loading Loading @@ -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(); Loading media/java/android/media/PlaybackSettings.java 0 → 100644 +206 −0 Original line number Diff line number Diff line /* * 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; } } Loading
api/current.txt +20 −0 Original line number Diff line number Diff line Loading @@ -14995,6 +14995,7 @@ package android.media { method public int getPlayState(); method public int getPlaybackHeadPosition(); method public int getPlaybackRate(); method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public int getSampleRate(); Loading @@ -15012,6 +15013,7 @@ package android.media { method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener); method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener, android.os.Handler); method public int setPlaybackRate(int); method public void setPlaybackSettings(android.media.PlaybackSettings); method public int setPositionNotificationPeriod(int); method public boolean setPreferredOutputDevice(android.media.AudioDeviceInfo); method protected deprecated void setState(int); Loading Loading @@ -16375,6 +16377,24 @@ package android.media { method public abstract void onAudioDeviceConnection(); } public final class PlaybackSettings { ctor public PlaybackSettings(); method public android.media.PlaybackSettings allowDefaults(); method public int getAudioFallbackMode(); method public int getAudioStretchMode(); method public float getPitch(); method public float getSpeed(); method public android.media.PlaybackSettings setAudioFallbackMode(int); method public android.media.PlaybackSettings setAudioStretchMode(int); method public android.media.PlaybackSettings setPitch(float); method public android.media.PlaybackSettings setSpeed(float); field public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_FALLBACK_MODE_FAIL = 2; // 0x2 field public static final int AUDIO_FALLBACK_MODE_MUTE = 1; // 0x1 field public static final int AUDIO_STRETCH_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating();
api/system-current.txt +20 −0 Original line number Diff line number Diff line Loading @@ -16207,6 +16207,7 @@ package android.media { method public int getPlayState(); method public int getPlaybackHeadPosition(); method public int getPlaybackRate(); method public android.media.PlaybackSettings getPlaybackSettings(); method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredOutputDevice(); method public int getSampleRate(); Loading @@ -16224,6 +16225,7 @@ package android.media { method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener); method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener, android.os.Handler); method public int setPlaybackRate(int); method public void setPlaybackSettings(android.media.PlaybackSettings); method public int setPositionNotificationPeriod(int); method public boolean setPreferredOutputDevice(android.media.AudioDeviceInfo); method protected deprecated void setState(int); Loading Loading @@ -17590,6 +17592,24 @@ package android.media { method public abstract void onAudioDeviceConnection(); } public final class PlaybackSettings { ctor public PlaybackSettings(); method public android.media.PlaybackSettings allowDefaults(); method public int getAudioFallbackMode(); method public int getAudioStretchMode(); method public float getPitch(); method public float getSpeed(); method public android.media.PlaybackSettings setAudioFallbackMode(int); method public android.media.PlaybackSettings setAudioStretchMode(int); method public android.media.PlaybackSettings setPitch(float); method public android.media.PlaybackSettings setSpeed(float); field public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_FALLBACK_MODE_FAIL = 2; // 0x2 field public static final int AUDIO_FALLBACK_MODE_MUTE = 1; // 0x1 field public static final int AUDIO_STRETCH_MODE_DEFAULT = 0; // 0x0 field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1 } public final class Rating implements android.os.Parcelable { method public int describeContents(); method public float getPercentRating();
core/jni/android_media_AudioTrack.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -676,6 +676,63 @@ static jint android_media_AudioTrack_get_playback_rate(JNIEnv *env, jobject thi } // ---------------------------------------------------------------------------- static void android_media_AudioTrack_set_playback_settings(JNIEnv *env, jobject thiz, jfloatArray floatArray, jintArray intArray) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "AudioTrack not initialized"); return; } // NOTE: Get<Primitive>ArrayRegion throws ArrayIndexOutOfBoundsException if not valid. // TODO: consider the actual occupancy. float farray[2]; int iarray[2]; if ((env->GetFloatArrayRegion(floatArray, 0, 2, farray), env->ExceptionCheck()) == JNI_FALSE && (env->GetIntArrayRegion(intArray, 0, 2, iarray), env->ExceptionCheck()) == JNI_FALSE) { // arrays retrieved OK AudioPlaybackRate playbackRate; playbackRate.mSpeed = farray[0]; playbackRate.mPitch = farray[1]; playbackRate.mFallbackMode = (AudioTimestretchFallbackMode)iarray[0]; playbackRate.mStretchMode = (AudioTimestretchStretchMode)iarray[1]; if (lpTrack->setPlaybackRate(playbackRate) != OK) { jniThrowException(env, "java/lang/IllegalArgumentException", "arguments out of range"); } } } // ---------------------------------------------------------------------------- static void android_media_AudioTrack_get_playback_settings(JNIEnv *env, jobject thiz, jfloatArray floatArray, jintArray intArray) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "AudioTrack not initialized"); return; } AudioPlaybackRate playbackRate = lpTrack->getPlaybackRate(); float farray[2] = { playbackRate.mSpeed, playbackRate.mPitch, }; int iarray[2] = { playbackRate.mFallbackMode, playbackRate.mStretchMode, }; // NOTE: Set<Primitive>ArrayRegion throws ArrayIndexOutOfBoundsException if not valid. env->SetFloatArrayRegion(floatArray, 0, 2, farray); env->SetIntArrayRegion(intArray, 0, 2, iarray); } // ---------------------------------------------------------------------------- static jint android_media_AudioTrack_set_marker_pos(JNIEnv *env, jobject thiz, jint markerPos) { Loading Loading @@ -942,6 +999,10 @@ static JNINativeMethod gMethods[] = { "(I)I", (void *)android_media_AudioTrack_set_playback_rate}, {"native_get_playback_rate", "()I", (void *)android_media_AudioTrack_get_playback_rate}, {"native_set_playback_settings", "([F[I)V", (void *)android_media_AudioTrack_set_playback_settings}, {"native_get_playback_settings", "([F[I)V", (void *)android_media_AudioTrack_get_playback_settings}, {"native_set_marker_pos","(I)I", (void *)android_media_AudioTrack_set_marker_pos}, {"native_get_marker_pos","()I", (void *)android_media_AudioTrack_get_marker_pos}, {"native_set_pos_update_period", Loading
media/java/android/media/AudioTrack.java +64 −1 Original line number Diff line number Diff line Loading @@ -946,12 +946,29 @@ 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}. Loading Loading @@ -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} Loading @@ -1322,6 +1340,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 Loading Loading @@ -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(); Loading
media/java/android/media/PlaybackSettings.java 0 → 100644 +206 −0 Original line number Diff line number Diff line /* * 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; } }