Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 083c7a58 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "AudioTrack comments and range checks"

parents 547f1c42 e2a4b42c
Loading
Loading
Loading
Loading
+80 −36
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import android.util.Log;

/**
 * The AudioTrack class manages and plays a single audio resource for Java applications.
 * It allows streaming PCM audio buffers to the audio hardware for playback. This is
 * It allows streaming of PCM audio buffers to the audio sink for playback. This is
 * achieved by "pushing" the data to the AudioTrack object using one of the
 *  {@link #write(byte[], int, int)} and {@link #write(short[], int, int)} methods.
 *
@@ -53,7 +53,7 @@ import android.util.Log;
 * can play before running out of data.<br>
 * For an AudioTrack using the static mode, this size is the maximum size of the sound that can
 * be played from it.<br>
 * For the streaming mode, data will be written to the hardware in chunks of
 * For the streaming mode, data will be written to the audio sink in chunks of
 * sizes less than or equal to the total buffer size.
 *
 * AudioTrack is not final and thus permits subclasses, but such use is not recommended.
@@ -132,7 +132,7 @@ public class AudioTrack
    private static final int ERROR_NATIVESETUP_NATIVEINITFAILED    = -20;

    // Events:
    // to keep in sync with frameworks/base/include/media/AudioTrack.h
    // to keep in sync with frameworks/av/include/media/AudioTrack.h
    /**
     * Event id denotes when playback head has reached a previously set marker.
     */
@@ -161,9 +161,10 @@ public class AudioTrack
     */
    private final Object mPlayStateLock = new Object();
    /**
     * Size of the native audio buffer.
     * Sizes of the native audio buffer.
     */
    private int mNativeBufferSizeInBytes = 0;
    private int mNativeBufferSizeInFrames = 0;
    /**
     * Handler for marker events coming from the native code.
     */
@@ -194,7 +195,7 @@ public class AudioTrack
     */
    private int mStreamType = AudioManager.STREAM_MUSIC;
    /**
     * The way audio is consumed by the hardware, streaming or static.
     * The way audio is consumed by the audio sink, streaming or static.
     */
    private int mDataLoadMode = MODE_STREAM;
    /**
@@ -245,10 +246,13 @@ public class AudioTrack
     * @param audioFormat the format in which the audio data is represented.
     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
     *   {@link AudioFormat#ENCODING_PCM_8BIT}
     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
     *   from for playback. If using the AudioTrack in streaming mode, you can write data into
     *   this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
     *   this is the maximum size of the sound that will be played for this instance.
     * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
     *   read from for playback.
     *   If track's creation mode is {@link #MODE_STREAM}, you can write data into
     *   this buffer in chunks less than or equal to this size, and it is typical to use
     *   chunks of 1/2 of the total size to permit double-buffering.
     *   If the track's creation mode is {@link #MODE_STATIC},
     *   this is the maximum length sample, or audio clip, that can be played by this instance.
     *   See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
     *   for the successful creation of an AudioTrack instance in streaming mode. Using values
     *   smaller than getMinBufferSize() will result in an initialization failure.
@@ -466,7 +470,7 @@ public class AudioTrack
    }


    // Convenience method for the contructor's audio buffer size check.
    // Convenience method for the constructor's audio buffer size check.
    // preconditions:
    //    mChannelCount is valid
    //    mAudioFormat is valid
@@ -482,6 +486,7 @@ public class AudioTrack
        }

        mNativeBufferSizeInBytes = audioBufferSize;
        mNativeBufferSizeInFrames = audioBufferSize / frameSizeInBytes;
    }


@@ -561,7 +566,6 @@ public class AudioTrack

    /**
     * Returns the configured channel configuration.

     * See {@link AudioFormat#CHANNEL_OUT_MONO}
     * and {@link AudioFormat#CHANNEL_OUT_STEREO}.
     */
@@ -579,8 +583,7 @@ public class AudioTrack
    /**
     * Returns the state of the AudioTrack instance. This is useful after the
     * AudioTrack instance has been created to check if it was initialized
     * properly. This ensures that the appropriate hardware resources have been
     * acquired.
     * properly. This ensures that the appropriate resources have been acquired.
     * @see #STATE_INITIALIZED
     * @see #STATE_NO_STATIC_DATA
     * @see #STATE_UNINITIALIZED
@@ -602,7 +605,13 @@ public class AudioTrack
    }

    /**
     *  Returns the native frame count used by the hardware.
     *  Returns the "native frame count", derived from the bufferSizeInBytes specified at
     *  creation time and converted to frame units.
     *  If track's creation mode is {@link #MODE_STATIC},
     *  it is equal to the specified bufferSizeInBytes converted to frame units.
     *  If track's creation mode is {@link #MODE_STREAM},
     *  it is typically greater than or equal to the specified bufferSizeInBytes converted to frame
     *  units; it may be rounded up to a larger value if needed by the target device implementation.
     *  @deprecated Only accessible by subclasses, which are not recommended for AudioTrack.
     *  See {@link AudioManager#getProperty(String)} for key
     *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
@@ -614,6 +623,8 @@ public class AudioTrack

    /**
     * Returns marker position expressed in frames.
     * @return marker position in wrapping frame units similar to {@link #getPlaybackHeadPosition},
     * or zero if marker is disabled.
     */
    public int getNotificationMarkerPosition() {
        return native_get_marker_pos();
@@ -621,20 +632,26 @@ public class AudioTrack

    /**
     * Returns the notification update period expressed in frames.
     * Zero means that no position update notifications are being delivered.
     */
    public int getPositionNotificationPeriod() {
        return native_get_pos_update_period();
    }

    /**
     * Returns the playback head position expressed in frames
     * Returns the playback head position expressed in frames.
     * Though the "int" type is signed 32-bits, the value should be reinterpreted as if it is
     * unsigned 32-bits.  That is, the next position after 0x7FFFFFFF is (int) 0x80000000.
     * This is a continuously advancing counter.  It will wrap (overflow) periodically,
     * for example approximately once every 27:03:11 hours:minutes:seconds at 44.1 kHz.
     * It is reset to zero by flush(), reload(), and stop().
     */
    public int getPlaybackHeadPosition() {
        return native_get_position();
    }

    /**
     *  Returns the hardware output sample rate
     *  Returns the output sample rate in Hz for the specified stream type.
     */
    static public int getNativeOutputSampleRate(int streamType) {
        return native_get_output_sample_rate(streamType);
@@ -653,8 +670,7 @@ public class AudioTrack
     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
     *   {@link AudioFormat#ENCODING_PCM_8BIT}
     * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed,
     *   or {@link #ERROR} if the implementation was unable to query the hardware for its output
     *     properties,
     *   or {@link #ERROR} if unable to query for output properties,
     *   or the minimum buffer size expressed in bytes.
     */
    static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
@@ -788,8 +804,8 @@ public class AudioTrack
    /**
     * Sets the playback sample rate for this track. This sets the sampling rate at which
     * the audio data will be consumed and played back, not the original sampling rate of the
     * content. Setting it to half the sample rate of the content will cause the playback to
     * last twice as long, but will also result in a negative pitch shift.
     * content. For example, setting it to half the sample rate of the content will cause the
     * 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)}.
     * @param sampleRateInHz the sample rate expressed in Hz
@@ -808,8 +824,11 @@ public class AudioTrack


    /**
     * Sets the position of the notification marker.
     * @param markerInFrames marker in frames
     * 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.
     * To set a marker at a position which would appear as zero due to wraparound,
     * a workaround is to use a non-zero position near zero, such as -1 or 1.
     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
     *  {@link #ERROR_INVALID_OPERATION}
     */
@@ -839,6 +858,8 @@ public class AudioTrack
     * The track must be stopped or paused for the position to be changed,
     * and must use the {@link #MODE_STATIC} mode.
     * @param positionInFrames playback head position expressed in frames
     * Zero corresponds to start of buffer.
     * The position must not be greater than the buffer size in frames, or negative.
     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
     *    {@link #ERROR_INVALID_OPERATION}
     */
@@ -847,18 +868,28 @@ public class AudioTrack
                getPlayState() == PLAYSTATE_PLAYING) {
            return ERROR_INVALID_OPERATION;
        }
        if (!(0 <= positionInFrames && positionInFrames <= mNativeBufferSizeInFrames)) {
            return ERROR_BAD_VALUE;
        }
        return native_set_position(positionInFrames);
    }

    /**
     * Sets the loop points and the loop count. The loop can be infinite.
     * Similarly to setPlaybackHeadPosition,
     * the track must be stopped or paused for the position to be changed,
     * the track must be stopped or paused for the loop points to be changed,
     * and must use the {@link #MODE_STATIC} mode.
     * @param startInFrames loop start marker expressed in frames
     * Zero corresponds to start of buffer.
     * The start marker must not be greater than or equal to the buffer size in frames, or negative.
     * @param endInFrames loop end marker expressed in frames
     * The total buffer size in frames corresponds to end of buffer.
     * The end marker must not be greater than the buffer size in frames.
     * For looping, the end marker must not be less than or equal to the start marker,
     * but to disable looping
     * it is permitted for start marker, end marker, and loop count to all be 0.
     * @param loopCount the number of times the loop is looped.
     *    A value of -1 means infinite looping.
     *    A value of -1 means infinite looping, and 0 disables looping.
     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
     *    {@link #ERROR_INVALID_OPERATION}
     */
@@ -867,6 +898,12 @@ public class AudioTrack
                getPlayState() == PLAYSTATE_PLAYING) {
            return ERROR_INVALID_OPERATION;
        }
        if (loopCount == 0) {
            ;   // explicitly allowed as an exception to the loop region range check
        } else if (!(0 <= startInFrames && startInFrames < mNativeBufferSizeInFrames &&
                startInFrames < endInFrames && endInFrames <= mNativeBufferSizeInFrames)) {
            return ERROR_BAD_VALUE;
        }
        return native_set_loop(startInFrames, endInFrames, loopCount);
    }

@@ -888,6 +925,7 @@ public class AudioTrack
    //--------------------
    /**
     * Starts playing an AudioTrack.
     * If track's creation mode is {@link #MODE_STATIC}, you must have called write() prior.
     *
     * @throws IllegalStateException
     */
@@ -952,7 +990,8 @@ public class AudioTrack

    /**
     * Flushes the audio data currently queued for playback. Any data that has
     * not been played back will be discarded.
     * not been played back will be discarded.  No-op if not stopped or paused,
     * or if the track's creation mode is not {@link #MODE_STREAM}.
     */
    public void flush() {
        if (mState == STATE_INITIALIZED) {
@@ -963,11 +1002,13 @@ public class AudioTrack
    }

    /**
     * Writes the audio data to the audio hardware for playback. Will block until
     * all data has been written to the audio mixer.
     * Writes the audio data to the audio sink for playback (streaming mode),
     * or copies audio data for later playback (static buffer mode).
     * In streaming mode, will block until all data has been written to the audio sink.
     * In static buffer mode, copies the data to the buffer starting at offset 0.
     * Note that the actual playback of this data might occur after this function
     * returns. This function is thread safe with respect to {@link #stop} calls,
     * in which case all of the specified data might not be written to the mixer.
     * in which case all of the specified data might not be written to the audio sink.
     *
     * @param audioData the array that holds the data to play.
     * @param offsetInBytes the offset expressed in bytes in audioData where the data to play
@@ -1004,11 +1045,13 @@ public class AudioTrack


    /**
     * Writes the audio data to the audio hardware for playback. Will block until
     * all data has been written to the audio mixer.
     * Writes the audio data to the audio sink for playback (streaming mode),
     * or copies audio data for later playback (static buffer mode).
     * In streaming mode, will block until all data has been written to the audio sink.
     * In static buffer mode, copies the data to the buffer starting at offset 0.
     * Note that the actual playback of this data might occur after this function
     * returns. This function is thread safe with respect to {@link #stop} calls,
     * in which case all of the specified data might not be written to the mixer.
     * in which case all of the specified data might not be written to the audio sink.
     *
     * @param audioData the array that holds the data to play.
     * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
@@ -1046,8 +1089,8 @@ public class AudioTrack

    /**
     * Notifies the native resource to reuse the audio data already loaded in the native
     * layer. This call is only valid with AudioTrack instances that don't use the streaming
     * model.
     * layer, that is to rewind to start of buffer.
     * The track's creation mode must be {@link #MODE_STATIC}.
     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
     *  {@link #ERROR_INVALID_OPERATION}
     */
@@ -1088,8 +1131,9 @@ public class AudioTrack

    /**
     * Sets the send level of the audio track to the attached auxiliary effect
     * {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
     * <p>By default the send level is 0, so even if an effect is attached to the player
     * {@link #attachAuxEffect(int)}.  The level value range is 0.0f to 1.0f.
     * Values are clamped to the (0.0f, 1.0f) interval if outside this range.
     * <p>By default the send level is 0.0f, so even if an effect is attached to the player
     * this method must be called for the effect to be applied.
     * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
     * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,