AudioTrack.java revision df3cb5279857cac41909643c6703e8fc1621fad1
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media;
18
19import java.lang.ref.WeakReference;
20import java.lang.IllegalArgumentException;
21import java.lang.IllegalStateException;
22
23import android.os.Handler;
24import android.os.Looper;
25import android.os.Message;
26import android.media.AudioManager;
27import android.util.Log;
28
29
30/**
31 * The AudioTrack class manages and plays a single audio resource for Java applications.
32 * It allows streaming PCM audio buffers to the audio hardware for playback. This is
33 * achieved by "pushing" the data to the AudioTrack object using one of the
34 *  {@link #write(byte[], int, int)} and {@link #write(short[], int, int)} methods.
35 *
36 * <p>An AudioTrack instance can operate under two modes: static or streaming.<br>
37 * In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using
38 * one of the {@code write()} methods. These are blocking and return when the data has been
39 * transferred from the Java layer to the native layer and queued for playback. The streaming
40 * mode is most useful when playing blocks of audio data that for instance are:
41 *
42 * <ul>
43 *   <li>too big to fit in memory because of the duration of the sound to play,</li>
44 *   <li>too big to fit in memory because of the characteristics of the audio data
45 *         (high sampling rate, bits per sample ...)</li>
46 *   <li>received or generated while previously queued audio is playing.</li>
47 * </ul>
48 *
49 * The static mode should be chosen when dealing with short sounds that fit in memory and
50 * that need to be played with the smallest latency possible. The static mode will
51 * therefore be preferred for UI and game sounds that are played often, and with the
52 * smallest overhead possible.
53 *
54 * <p>Upon creation, an AudioTrack object initializes its associated audio buffer.
55 * The size of this buffer, specified during the construction, determines how long an AudioTrack
56 * can play before running out of data.<br>
57 * For an AudioTrack using the static mode, this size is the maximum size of the sound that can
58 * be played from it.<br>
59 * For the streaming mode, data will be written to the hardware in chunks of
60 * sizes less than or equal to the total buffer size.
61 */
62public class AudioTrack
63{
64    //---------------------------------------------------------
65    // Constants
66    //--------------------
67    /** Minimum value for a channel volume */
68    private static final float VOLUME_MIN = 0.0f;
69    /** Maximum value for a channel volume */
70    private static final float VOLUME_MAX = 1.0f;
71
72    /** Minimum value for sample rate */
73    private static final int SAMPLE_RATE_HZ_MIN = 4000;
74    /** Maximum value for sample rate */
75    private static final int SAMPLE_RATE_HZ_MAX = 48000;
76
77    /** indicates AudioTrack state is stopped */
78    public static final int PLAYSTATE_STOPPED = 1;  // matches SL_PLAYSTATE_STOPPED
79    /** indicates AudioTrack state is paused */
80    public static final int PLAYSTATE_PAUSED  = 2;  // matches SL_PLAYSTATE_PAUSED
81    /** indicates AudioTrack state is playing */
82    public static final int PLAYSTATE_PLAYING = 3;  // matches SL_PLAYSTATE_PLAYING
83
84    // keep these values in sync with android_media_AudioTrack.cpp
85    /**
86     * Creation mode where audio data is transferred from Java to the native layer
87     * only once before the audio starts playing.
88     */
89    public static final int MODE_STATIC = 0;
90    /**
91     * Creation mode where audio data is streamed from Java to the native layer
92     * as the audio is playing.
93     */
94    public static final int MODE_STREAM = 1;
95
96    /**
97     * State of an AudioTrack that was not successfully initialized upon creation.
98     */
99    public static final int STATE_UNINITIALIZED = 0;
100    /**
101     * State of an AudioTrack that is ready to be used.
102     */
103    public static final int STATE_INITIALIZED   = 1;
104    /**
105     * State of a successfully initialized AudioTrack that uses static data,
106     * but that hasn't received that data yet.
107     */
108    public static final int STATE_NO_STATIC_DATA = 2;
109
110    // Error codes:
111    // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
112    /**
113     * Denotes a successful operation.
114     */
115    public  static final int SUCCESS                               = 0;
116    /**
117     * Denotes a generic operation failure.
118     */
119    public  static final int ERROR                                 = -1;
120    /**
121     * Denotes a failure due to the use of an invalid value.
122     */
123    public  static final int ERROR_BAD_VALUE                       = -2;
124    /**
125     * Denotes a failure due to the improper use of a method.
126     */
127    public  static final int ERROR_INVALID_OPERATION               = -3;
128
129    private static final int ERROR_NATIVESETUP_AUDIOSYSTEM         = -16;
130    private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK  = -17;
131    private static final int ERROR_NATIVESETUP_INVALIDFORMAT       = -18;
132    private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE   = -19;
133    private static final int ERROR_NATIVESETUP_NATIVEINITFAILED    = -20;
134
135    // Events:
136    // to keep in sync with frameworks/base/include/media/AudioTrack.h
137    /**
138     * Event id denotes when playback head has reached a previously set marker.
139     */
140    private static final int NATIVE_EVENT_MARKER  = 3;
141    /**
142     * Event id denotes when previously set update period has elapsed during playback.
143     */
144    private static final int NATIVE_EVENT_NEW_POS = 4;
145
146    private final static String TAG = "AudioTrack-Java";
147
148
149    //--------------------------------------------------------------------------
150    // Member variables
151    //--------------------
152    /**
153     * Indicates the state of the AudioTrack instance.
154     */
155    private int mState = STATE_UNINITIALIZED;
156    /**
157     * Indicates the play state of the AudioTrack instance.
158     */
159    private int mPlayState = PLAYSTATE_STOPPED;
160    /**
161     * Lock to make sure mPlayState updates are reflecting the actual state of the object.
162     */
163    private final Object mPlayStateLock = new Object();
164    /**
165     * The listener the AudioTrack notifies when the playback position reaches a marker
166     * or for periodic updates during the progression of the playback head.
167     *  @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener)
168     */
169    private OnPlaybackPositionUpdateListener mPositionListener = null;
170    /**
171     * Lock to protect event listener updates against event notifications.
172     */
173    private final Object mPositionListenerLock = new Object();
174    /**
175     * Size of the native audio buffer.
176     */
177    private int mNativeBufferSizeInBytes = 0;
178    /**
179     * Handler for marker events coming from the native code.
180     */
181    private NativeEventHandlerDelegate mEventHandlerDelegate = null;
182    /**
183     * Looper associated with the thread that creates the AudioTrack instance.
184     */
185    private Looper mInitializationLooper = null;
186    /**
187     * The audio data sampling rate in Hz.
188     */
189    private int mSampleRate; // initialized by all constructors
190    /**
191     * The number of audio output channels (1 is mono, 2 is stereo).
192     */
193    private int mChannelCount = 1;
194    /**
195     * The audio channel mask.
196     */
197    private int mChannels = AudioFormat.CHANNEL_OUT_MONO;
198
199    /**
200     * The type of the audio stream to play. See
201     *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
202     *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
203     *   {@link AudioManager#STREAM_ALARM}, {@link AudioManager#STREAM_NOTIFICATION}, and
204     *   {@link AudioManager#STREAM_DTMF}.
205     */
206    private int mStreamType = AudioManager.STREAM_MUSIC;
207    /**
208     * The way audio is consumed by the hardware, streaming or static.
209     */
210    private int mDataLoadMode = MODE_STREAM;
211    /**
212     * The current audio channel configuration.
213     */
214    private int mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO;
215    /**
216     * The encoding of the audio samples.
217     * @see AudioFormat#ENCODING_PCM_8BIT
218     * @see AudioFormat#ENCODING_PCM_16BIT
219     */
220    private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
221    /**
222     * Audio session ID
223     */
224    private int mSessionId = 0;
225
226
227    //--------------------------------
228    // Used exclusively by native code
229    //--------------------
230    /**
231     * Accessed by native methods: provides access to C++ AudioTrack object.
232     */
233    @SuppressWarnings("unused")
234    private int mNativeTrackInJavaObj;
235    /**
236     * Accessed by native methods: provides access to the JNI data (i.e. resources used by
237     * the native AudioTrack object, but not stored in it).
238     */
239    @SuppressWarnings("unused")
240    private int mJniData;
241
242
243    //--------------------------------------------------------------------------
244    // Constructor, Finalize
245    //--------------------
246    /**
247     * Class constructor.
248     * @param streamType the type of the audio stream. See
249     *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
250     *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
251     *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
252     * @param sampleRateInHz the sample rate expressed in Hertz.
253     * @param channelConfig describes the configuration of the audio channels.
254     *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
255     *   {@link AudioFormat#CHANNEL_OUT_STEREO}
256     * @param audioFormat the format in which the audio data is represented.
257     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
258     *   {@link AudioFormat#ENCODING_PCM_8BIT}
259     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
260     *   from for playback. If using the AudioTrack in streaming mode, you can write data into
261     *   this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
262     *   this is the maximum size of the sound that will be played for this instance.
263     *   See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
264     *   for the successful creation of an AudioTrack instance in streaming mode. Using values
265     *   smaller than getMinBufferSize() will result in an initialization failure.
266     * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
267     * @throws java.lang.IllegalArgumentException
268     */
269    public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
270            int bufferSizeInBytes, int mode)
271    throws IllegalArgumentException {
272        this(streamType, sampleRateInHz, channelConfig, audioFormat,
273                bufferSizeInBytes, mode, 0);
274    }
275
276    /**
277     * Class constructor with audio session. Use this constructor when the AudioTrack must be
278     * attached to a particular audio session. The primary use of the audio session ID is to
279     * associate audio effects to a particular instance of AudioTrack: if an audio session ID
280     * is provided when creating an AudioEffect, this effect will be applied only to audio tracks
281     * and media players in the same session and not to the output mix.
282     * When an AudioTrack is created without specifying a session, it will create its own session
283     * which can be retreived by calling the {@link #getAudioSessionId()} method.
284     * If a non-zero session ID is provided, this AudioTrack will share effects attached to this
285     * session
286     * with all other media players or audio tracks in the same session, otherwise a new session
287     * will be created for this track if none is supplied.
288     * @param streamType the type of the audio stream. See
289     *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
290     *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
291     *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
292     * @param sampleRateInHz the sample rate expressed in Hertz.
293     * @param channelConfig describes the configuration of the audio channels.
294     *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
295     *   {@link AudioFormat#CHANNEL_OUT_STEREO}
296     * @param audioFormat the format in which the audio data is represented.
297     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
298     *   {@link AudioFormat#ENCODING_PCM_8BIT}
299     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
300     *   from for playback. If using the AudioTrack in streaming mode, you can write data into
301     *   this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
302     *   this is the maximum size of the sound that will be played for this instance.
303     *   See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
304     *   for the successful creation of an AudioTrack instance in streaming mode. Using values
305     *   smaller than getMinBufferSize() will result in an initialization failure.
306     * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
307     * @param sessionId Id of audio session the AudioTrack must be attached to
308     * @throws java.lang.IllegalArgumentException
309     */
310    public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
311            int bufferSizeInBytes, int mode, int sessionId)
312    throws IllegalArgumentException {
313        mState = STATE_UNINITIALIZED;
314
315        // remember which looper is associated with the AudioTrack instantiation
316        if ((mInitializationLooper = Looper.myLooper()) == null) {
317            mInitializationLooper = Looper.getMainLooper();
318        }
319
320        audioParamCheck(streamType, sampleRateInHz, channelConfig, audioFormat, mode);
321
322        audioBuffSizeCheck(bufferSizeInBytes);
323
324        if (sessionId < 0) {
325            throw (new IllegalArgumentException("Invalid audio session ID: "+sessionId));
326        }
327
328        int[] session = new int[1];
329        session[0] = sessionId;
330        // native initialization
331        int initResult = native_setup(new WeakReference<AudioTrack>(this),
332                mStreamType, mSampleRate, mChannels, mAudioFormat,
333                mNativeBufferSizeInBytes, mDataLoadMode, session);
334        if (initResult != SUCCESS) {
335            loge("Error code "+initResult+" when initializing AudioTrack.");
336            return; // with mState == STATE_UNINITIALIZED
337        }
338
339        mSessionId = session[0];
340
341        if (mDataLoadMode == MODE_STATIC) {
342            mState = STATE_NO_STATIC_DATA;
343        } else {
344            mState = STATE_INITIALIZED;
345        }
346    }
347
348    // mask of all the channels supported by this implementation
349    private static final int SUPPORTED_OUT_CHANNELS =
350            AudioFormat.CHANNEL_OUT_FRONT_LEFT |
351            AudioFormat.CHANNEL_OUT_FRONT_RIGHT |
352            AudioFormat.CHANNEL_OUT_FRONT_CENTER |
353            AudioFormat.CHANNEL_OUT_LOW_FREQUENCY |
354            AudioFormat.CHANNEL_OUT_BACK_LEFT |
355            AudioFormat.CHANNEL_OUT_BACK_RIGHT |
356            AudioFormat.CHANNEL_OUT_BACK_CENTER;
357
358    // Convenience method for the constructor's parameter checks.
359    // This is where constructor IllegalArgumentException-s are thrown
360    // postconditions:
361    //    mStreamType is valid
362    //    mChannelCount is valid
363    //    mChannels is valid
364    //    mAudioFormat is valid
365    //    mSampleRate is valid
366    //    mDataLoadMode is valid
367    private void audioParamCheck(int streamType, int sampleRateInHz,
368                                 int channelConfig, int audioFormat, int mode) {
369
370        //--------------
371        // stream type
372        if( (streamType != AudioManager.STREAM_ALARM) && (streamType != AudioManager.STREAM_MUSIC)
373           && (streamType != AudioManager.STREAM_RING) && (streamType != AudioManager.STREAM_SYSTEM)
374           && (streamType != AudioManager.STREAM_VOICE_CALL)
375           && (streamType != AudioManager.STREAM_NOTIFICATION)
376           && (streamType != AudioManager.STREAM_BLUETOOTH_SCO)
377           && (streamType != AudioManager.STREAM_DTMF)) {
378            throw (new IllegalArgumentException("Invalid stream type."));
379        } else {
380            mStreamType = streamType;
381        }
382
383        //--------------
384        // sample rate, note these values are subject to change
385        if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
386            throw (new IllegalArgumentException(sampleRateInHz
387                    + "Hz is not a supported sample rate."));
388        } else {
389            mSampleRate = sampleRateInHz;
390        }
391
392        //--------------
393        // channel config
394        mChannelConfiguration = channelConfig;
395
396        switch (channelConfig) {
397        case AudioFormat.CHANNEL_OUT_DEFAULT: //AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
398        case AudioFormat.CHANNEL_OUT_MONO:
399        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
400            mChannelCount = 1;
401            mChannels = AudioFormat.CHANNEL_OUT_MONO;
402            break;
403        case AudioFormat.CHANNEL_OUT_STEREO:
404        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
405            mChannelCount = 2;
406            mChannels = AudioFormat.CHANNEL_OUT_STEREO;
407            break;
408        default:
409            if (!isMultichannelConfigSupported(channelConfig)) {
410                // input channel configuration features unsupported channels
411                mChannelCount = 0;
412                mChannels = AudioFormat.CHANNEL_INVALID;
413                mChannelConfiguration = AudioFormat.CHANNEL_INVALID;
414                throw(new IllegalArgumentException("Unsupported channel configuration."));
415            } else {
416                mChannels = channelConfig;
417                mChannelCount = Integer.bitCount(channelConfig);
418            }
419        }
420
421        //--------------
422        // audio format
423        switch (audioFormat) {
424        case AudioFormat.ENCODING_DEFAULT:
425            mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
426            break;
427        case AudioFormat.ENCODING_PCM_16BIT:
428        case AudioFormat.ENCODING_PCM_8BIT:
429            mAudioFormat = audioFormat;
430            break;
431        default:
432            mAudioFormat = AudioFormat.ENCODING_INVALID;
433            throw(new IllegalArgumentException("Unsupported sample encoding."
434                + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT."));
435        }
436
437        //--------------
438        // audio load mode
439        if ( (mode != MODE_STREAM) && (mode != MODE_STATIC) ) {
440            throw(new IllegalArgumentException("Invalid mode."));
441        } else {
442            mDataLoadMode = mode;
443        }
444    }
445
446    /**
447     * Convenience method to check that the channel configuration (a.k.a channel mask) is supported
448     * @param channelConfig the mask to validate
449     * @return false if the AudioTrack can't be used with such a mask
450     */
451    private static boolean isMultichannelConfigSupported(int channelConfig) {
452        // check for unsupported channels
453        if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
454            Log.e(TAG, "Channel configuration features unsupported channels");
455            return false;
456        }
457        // check for unsupported multichannel combinations:
458        // - FL/FR must be present
459        // - L/R channels must be paired (e.g. no single L channel)
460        final int frontPair =
461                AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
462        if ((channelConfig & frontPair) != frontPair) {
463                Log.e(TAG, "Front channels must be present in multichannel configurations");
464                return false;
465        }
466        final int backPair =
467                AudioFormat.CHANNEL_OUT_BACK_LEFT | AudioFormat.CHANNEL_OUT_BACK_RIGHT;
468        if ((channelConfig & backPair) != 0) {
469            if ((channelConfig & backPair) != backPair) {
470                Log.e(TAG, "Rear channels can't be used independently");
471                return false;
472            }
473        }
474        return true;
475    }
476
477
478    // Convenience method for the contructor's audio buffer size check.
479    // preconditions:
480    //    mChannelCount is valid
481    //    mAudioFormat is valid
482    // postcondition:
483    //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
484    private void audioBuffSizeCheck(int audioBufferSize) {
485        // NB: this section is only valid with PCM data.
486        //     To update when supporting compressed formats
487        int frameSizeInBytes = mChannelCount
488                * (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2);
489        if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
490            throw (new IllegalArgumentException("Invalid audio buffer size."));
491        }
492
493        mNativeBufferSizeInBytes = audioBufferSize;
494    }
495
496
497    /**
498     * Releases the native AudioTrack resources.
499     */
500    public void release() {
501        // even though native_release() stops the native AudioTrack, we need to stop
502        // AudioTrack subclasses too.
503        try {
504            stop();
505        } catch(IllegalStateException ise) {
506            // don't raise an exception, we're releasing the resources.
507        }
508        native_release();
509        mState = STATE_UNINITIALIZED;
510    }
511
512    @Override
513    protected void finalize() {
514        native_finalize();
515    }
516
517    //--------------------------------------------------------------------------
518    // Getters
519    //--------------------
520    /**
521     * Returns the minimum valid volume value. Volume values set under this one will
522     * be clamped at this value.
523     * @return the minimum volume expressed as a linear attenuation.
524     */
525    static public float getMinVolume() {
526        return VOLUME_MIN;
527    }
528
529    /**
530     * Returns the maximum valid volume value. Volume values set above this one will
531     * be clamped at this value.
532     * @return the maximum volume expressed as a linear attenuation.
533     */
534    static public float getMaxVolume() {
535        return VOLUME_MAX;
536    }
537
538    /**
539     * Returns the configured audio data sample rate in Hz
540     */
541    public int getSampleRate() {
542        return mSampleRate;
543    }
544
545    /**
546     * Returns the current playback rate in Hz.
547     */
548    public int getPlaybackRate() {
549        return native_get_playback_rate();
550    }
551
552    /**
553     * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT}
554     * and {@link AudioFormat#ENCODING_PCM_8BIT}.
555     */
556    public int getAudioFormat() {
557        return mAudioFormat;
558    }
559
560    /**
561     * Returns the type of audio stream this AudioTrack is configured for.
562     * Compare the result against {@link AudioManager#STREAM_VOICE_CALL},
563     * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING},
564     * {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM},
565     * {@link AudioManager#STREAM_NOTIFICATION}, or {@link AudioManager#STREAM_DTMF}.
566     */
567    public int getStreamType() {
568        return mStreamType;
569    }
570
571    /**
572     * Returns the configured channel configuration.
573
574     * See {@link AudioFormat#CHANNEL_OUT_MONO}
575     * and {@link AudioFormat#CHANNEL_OUT_STEREO}.
576     */
577    public int getChannelConfiguration() {
578        return mChannelConfiguration;
579    }
580
581    /**
582     * Returns the configured number of channels.
583     */
584    public int getChannelCount() {
585        return mChannelCount;
586    }
587
588    /**
589     * Returns the state of the AudioTrack instance. This is useful after the
590     * AudioTrack instance has been created to check if it was initialized
591     * properly. This ensures that the appropriate hardware resources have been
592     * acquired.
593     * @see #STATE_INITIALIZED
594     * @see #STATE_NO_STATIC_DATA
595     * @see #STATE_UNINITIALIZED
596     */
597    public int getState() {
598        return mState;
599    }
600
601    /**
602     * Returns the playback state of the AudioTrack instance.
603     * @see #PLAYSTATE_STOPPED
604     * @see #PLAYSTATE_PAUSED
605     * @see #PLAYSTATE_PLAYING
606     */
607    public int getPlayState() {
608        synchronized (mPlayStateLock) {
609            return mPlayState;
610        }
611    }
612
613    /**
614     *  Returns the native frame count used by the hardware.
615     */
616    protected int getNativeFrameCount() {
617        return native_get_native_frame_count();
618    }
619
620    /**
621     * Returns marker position expressed in frames.
622     */
623    public int getNotificationMarkerPosition() {
624        return native_get_marker_pos();
625    }
626
627    /**
628     * Returns the notification update period expressed in frames.
629     */
630    public int getPositionNotificationPeriod() {
631        return native_get_pos_update_period();
632    }
633
634    /**
635     * Returns the playback head position expressed in frames
636     */
637    public int getPlaybackHeadPosition() {
638        return native_get_position();
639    }
640
641    /**
642     *  Returns the hardware output sample rate
643     */
644    static public int getNativeOutputSampleRate(int streamType) {
645        return native_get_output_sample_rate(streamType);
646    }
647
648    /**
649     * Returns the minimum buffer size required for the successful creation of an AudioTrack
650     * object to be created in the {@link #MODE_STREAM} mode. Note that this size doesn't
651     * guarantee a smooth playback under load, and higher values should be chosen according to
652     * the expected frequency at which the buffer will be refilled with additional data to play.
653     * @param sampleRateInHz the sample rate expressed in Hertz.
654     * @param channelConfig describes the configuration of the audio channels.
655     *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
656     *   {@link AudioFormat#CHANNEL_OUT_STEREO}
657     * @param audioFormat the format in which the audio data is represented.
658     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
659     *   {@link AudioFormat#ENCODING_PCM_8BIT}
660     * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed,
661     *   or {@link #ERROR} if the implementation was unable to query the hardware for its output
662     *     properties,
663     *   or the minimum buffer size expressed in bytes.
664     */
665    static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
666        int channelCount = 0;
667        switch(channelConfig) {
668        case AudioFormat.CHANNEL_OUT_MONO:
669        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
670            channelCount = 1;
671            break;
672        case AudioFormat.CHANNEL_OUT_STEREO:
673        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
674            channelCount = 2;
675            break;
676        default:
677            if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
678                // input channel configuration features unsupported channels
679                loge("getMinBufferSize(): Invalid channel configuration.");
680                return ERROR_BAD_VALUE;
681            } else {
682                channelCount = Integer.bitCount(channelConfig);
683            }
684        }
685
686        if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)
687            && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) {
688            loge("getMinBufferSize(): Invalid audio format.");
689            return ERROR_BAD_VALUE;
690        }
691
692        // sample rate, note these values are subject to change
693        if ( (sampleRateInHz < SAMPLE_RATE_HZ_MIN) || (sampleRateInHz > SAMPLE_RATE_HZ_MAX) ) {
694            loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate.");
695            return ERROR_BAD_VALUE;
696        }
697
698        int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
699        if ((size == -1) || (size == 0)) {
700            loge("getMinBufferSize(): error querying hardware");
701            return ERROR;
702        }
703        else {
704            return size;
705        }
706    }
707
708    /**
709     * Returns the audio session ID.
710     *
711     * @return the ID of the audio session this AudioTrack belongs to.
712     */
713    public int getAudioSessionId() {
714        return mSessionId;
715    }
716
717    //--------------------------------------------------------------------------
718    // Initialization / configuration
719    //--------------------
720    /**
721     * Sets the listener the AudioTrack notifies when a previously set marker is reached or
722     * for each periodic playback head position update.
723     * Notifications will be received in the same thread as the one in which the AudioTrack
724     * instance was created.
725     * @param listener
726     */
727    public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener) {
728        setPlaybackPositionUpdateListener(listener, null);
729    }
730
731    /**
732     * Sets the listener the AudioTrack notifies when a previously set marker is reached or
733     * for each periodic playback head position update.
734     * Use this method to receive AudioTrack events in the Handler associated with another
735     * thread than the one in which you created the AudioTrack instance.
736     * @param listener
737     * @param handler the Handler that will receive the event notification messages.
738     */
739    public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener,
740                                                    Handler handler) {
741        synchronized (mPositionListenerLock) {
742            mPositionListener = listener;
743        }
744        if (listener != null) {
745            mEventHandlerDelegate = new NativeEventHandlerDelegate(this, handler);
746        }
747
748    }
749
750
751
752     /**
753     * Sets the specified left/right output volume values on the AudioTrack. Values are clamped
754     * to the ({@link #getMinVolume()}, {@link #getMaxVolume()}) interval if outside this range.
755     * @param leftVolume output attenuation for the left channel. A value of 0.0f is silence,
756     *      a value of 1.0f is no attenuation.
757     * @param rightVolume output attenuation for the right channel
758     * @return error code or success, see {@link #SUCCESS},
759     *    {@link #ERROR_INVALID_OPERATION}
760     */
761    public int setStereoVolume(float leftVolume, float rightVolume) {
762        if (mState != STATE_INITIALIZED) {
763            return ERROR_INVALID_OPERATION;
764        }
765
766        // clamp the volumes
767        if (leftVolume < getMinVolume()) {
768            leftVolume = getMinVolume();
769        }
770        if (leftVolume > getMaxVolume()) {
771            leftVolume = getMaxVolume();
772        }
773        if (rightVolume < getMinVolume()) {
774            rightVolume = getMinVolume();
775        }
776        if (rightVolume > getMaxVolume()) {
777            rightVolume = getMaxVolume();
778        }
779
780        native_setVolume(leftVolume, rightVolume);
781
782        return SUCCESS;
783    }
784
785
786    /**
787     * Similar, except set volume of all channels to same value.
788     * @hide
789     */
790    public int setVolume(float volume) {
791        return setStereoVolume(volume, volume);
792    }
793
794
795    /**
796     * Sets the playback sample rate for this track. This sets the sampling rate at which
797     * the audio data will be consumed and played back, not the original sampling rate of the
798     * content. Setting it to half the sample rate of the content will cause the playback to
799     * last twice as long, but will also result in a negative pitch shift.
800     * The valid sample rate range is from 1Hz to twice the value returned by
801     * {@link #getNativeOutputSampleRate(int)}.
802     * @param sampleRateInHz the sample rate expressed in Hz
803     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
804     *    {@link #ERROR_INVALID_OPERATION}
805     */
806    public int setPlaybackRate(int sampleRateInHz) {
807        if (mState != STATE_INITIALIZED) {
808            return ERROR_INVALID_OPERATION;
809        }
810        if (sampleRateInHz <= 0) {
811            return ERROR_BAD_VALUE;
812        }
813        return native_set_playback_rate(sampleRateInHz);
814    }
815
816
817    /**
818     * Sets the position of the notification marker.
819     * @param markerInFrames marker in frames
820     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
821     *  {@link #ERROR_INVALID_OPERATION}
822     */
823    public int setNotificationMarkerPosition(int markerInFrames) {
824        if (mState != STATE_INITIALIZED) {
825            return ERROR_INVALID_OPERATION;
826        }
827        return native_set_marker_pos(markerInFrames);
828    }
829
830
831    /**
832     * Sets the period for the periodic notification event.
833     * @param periodInFrames update period expressed in frames
834     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
835     */
836    public int setPositionNotificationPeriod(int periodInFrames) {
837        if (mState != STATE_INITIALIZED) {
838            return ERROR_INVALID_OPERATION;
839        }
840        return native_set_pos_update_period(periodInFrames);
841    }
842
843
844    /**
845     * Sets the playback head position. The track must be stopped for the position to be changed.
846     * @param positionInFrames playback head position expressed in frames
847     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
848     *    {@link #ERROR_INVALID_OPERATION}
849     */
850    public int setPlaybackHeadPosition(int positionInFrames) {
851        synchronized(mPlayStateLock) {
852            if ((mPlayState == PLAYSTATE_STOPPED) || (mPlayState == PLAYSTATE_PAUSED)) {
853                return native_set_position(positionInFrames);
854            } else {
855                return ERROR_INVALID_OPERATION;
856            }
857        }
858    }
859
860    /**
861     * Sets the loop points and the loop count. The loop can be infinite.
862     * @param startInFrames loop start marker expressed in frames
863     * @param endInFrames loop end marker expressed in frames
864     * @param loopCount the number of times the loop is looped.
865     *    A value of -1 means infinite looping.
866     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
867     *    {@link #ERROR_INVALID_OPERATION}
868     */
869    public int setLoopPoints(int startInFrames, int endInFrames, int loopCount) {
870        if (mDataLoadMode == MODE_STREAM) {
871            return ERROR_INVALID_OPERATION;
872        }
873        return native_set_loop(startInFrames, endInFrames, loopCount);
874    }
875
876    /**
877     * Sets the initialization state of the instance. To be used in an AudioTrack subclass
878     * constructor to set a subclass-specific post-initialization state.
879     * @param state the state of the AudioTrack instance
880     */
881    protected void setState(int state) {
882        mState = state;
883    }
884
885
886    //---------------------------------------------------------
887    // Transport control methods
888    //--------------------
889    /**
890     * Starts playing an AudioTrack.
891     *
892     * @throws IllegalStateException
893     */
894    public void play()
895    throws IllegalStateException {
896        if (mState != STATE_INITIALIZED) {
897            throw(new IllegalStateException("play() called on uninitialized AudioTrack."));
898        }
899
900        synchronized(mPlayStateLock) {
901            native_start();
902            mPlayState = PLAYSTATE_PLAYING;
903        }
904    }
905
906    /**
907     * Stops playing the audio data.
908     * When used on an instance created in {@link #MODE_STREAM} mode, audio will stop playing
909     * after the last buffer that was written has been played. For an immediate stop, use
910     * {@link #pause()}, followed by {@link #flush()} to discard audio data that hasn't been played
911     * back yet.
912     * @throws IllegalStateException
913     */
914    public void stop()
915    throws IllegalStateException {
916        if (mState != STATE_INITIALIZED) {
917            throw(new IllegalStateException("stop() called on uninitialized AudioTrack."));
918        }
919
920        // stop playing
921        synchronized(mPlayStateLock) {
922            native_stop();
923            mPlayState = PLAYSTATE_STOPPED;
924        }
925    }
926
927    /**
928     * Pauses the playback of the audio data. Data that has not been played
929     * back will not be discarded. Subsequent calls to {@link #play} will play
930     * this data back. See {@link #flush()} to discard this data.
931     *
932     * @throws IllegalStateException
933     */
934    public void pause()
935    throws IllegalStateException {
936        if (mState != STATE_INITIALIZED) {
937            throw(new IllegalStateException("pause() called on uninitialized AudioTrack."));
938        }
939        //logd("pause()");
940
941        // pause playback
942        synchronized(mPlayStateLock) {
943            native_pause();
944            mPlayState = PLAYSTATE_PAUSED;
945        }
946    }
947
948
949    //---------------------------------------------------------
950    // Audio data supply
951    //--------------------
952
953    /**
954     * Flushes the audio data currently queued for playback. Any data that has
955     * not been played back will be discarded.
956     */
957    public void flush() {
958        if (mState == STATE_INITIALIZED) {
959            // flush the data in native layer
960            native_flush();
961        }
962
963    }
964
965    /**
966     * Writes the audio data to the audio hardware for playback. Will block until
967     * all data has been written to the audio mixer.
968     * Note that the actual playback of this data might occur after this function
969     * returns. This function is thread safe with respect to {@link #stop} calls,
970     * in which case all of the specified data might not be written to the mixer.
971     *
972     * @param audioData the array that holds the data to play.
973     * @param offsetInBytes the offset expressed in bytes in audioData where the data to play
974     *    starts.
975     * @param sizeInBytes the number of bytes to read in audioData after the offset.
976     * @return the number of bytes that were written or {@link #ERROR_INVALID_OPERATION}
977     *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
978     *    the parameters don't resolve to valid data and indexes.
979     */
980
981    public int write(byte[] audioData, int offsetInBytes, int sizeInBytes) {
982        if ((mDataLoadMode == MODE_STATIC)
983                && (mState == STATE_NO_STATIC_DATA)
984                && (sizeInBytes > 0)) {
985            mState = STATE_INITIALIZED;
986        }
987
988        if (mState != STATE_INITIALIZED) {
989            return ERROR_INVALID_OPERATION;
990        }
991
992        if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
993                || (offsetInBytes + sizeInBytes > audioData.length)) {
994            return ERROR_BAD_VALUE;
995        }
996
997        return native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat);
998    }
999
1000
1001    /**
1002     * Writes the audio data to the audio hardware for playback. Will block until
1003     * all data has been written to the audio mixer.
1004     * Note that the actual playback of this data might occur after this function
1005     * returns. This function is thread safe with respect to {@link #stop} calls,
1006     * in which case all of the specified data might not be written to the mixer.
1007     *
1008     * @param audioData the array that holds the data to play.
1009     * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
1010     *     starts.
1011     * @param sizeInShorts the number of bytes to read in audioData after the offset.
1012     * @return the number of shorts that were written or {@link #ERROR_INVALID_OPERATION}
1013      *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
1014      *    the parameters don't resolve to valid data and indexes.
1015     */
1016
1017    public int write(short[] audioData, int offsetInShorts, int sizeInShorts) {
1018        if ((mDataLoadMode == MODE_STATIC)
1019                && (mState == STATE_NO_STATIC_DATA)
1020                && (sizeInShorts > 0)) {
1021            mState = STATE_INITIALIZED;
1022        }
1023
1024        if (mState != STATE_INITIALIZED) {
1025            return ERROR_INVALID_OPERATION;
1026        }
1027
1028        if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
1029                || (offsetInShorts + sizeInShorts > audioData.length)) {
1030            return ERROR_BAD_VALUE;
1031        }
1032
1033        return native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat);
1034    }
1035
1036
1037    /**
1038     * Notifies the native resource to reuse the audio data already loaded in the native
1039     * layer. This call is only valid with AudioTrack instances that don't use the streaming
1040     * model.
1041     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1042     *  {@link #ERROR_INVALID_OPERATION}
1043     */
1044    public int reloadStaticData() {
1045        if (mDataLoadMode == MODE_STREAM) {
1046            return ERROR_INVALID_OPERATION;
1047        }
1048        return native_reload_static();
1049    }
1050
1051    //--------------------------------------------------------------------------
1052    // Audio effects management
1053    //--------------------
1054
1055    /**
1056     * Attaches an auxiliary effect to the audio track. A typical auxiliary
1057     * effect is a reverberation effect which can be applied on any sound source
1058     * that directs a certain amount of its energy to this effect. This amount
1059     * is defined by setAuxEffectSendLevel().
1060     * {@see #setAuxEffectSendLevel(float)}.
1061     * <p>After creating an auxiliary effect (e.g.
1062     * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
1063     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling
1064     * this method to attach the audio track to the effect.
1065     * <p>To detach the effect from the audio track, call this method with a
1066     * null effect id.
1067     *
1068     * @param effectId system wide unique id of the effect to attach
1069     * @return error code or success, see {@link #SUCCESS},
1070     *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR_BAD_VALUE}
1071     */
1072    public int attachAuxEffect(int effectId) {
1073        if (mState != STATE_INITIALIZED) {
1074            return ERROR_INVALID_OPERATION;
1075        }
1076        return native_attachAuxEffect(effectId);
1077    }
1078
1079    /**
1080     * Sets the send level of the audio track to the attached auxiliary effect
1081     * {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
1082     * <p>By default the send level is 0, so even if an effect is attached to the player
1083     * this method must be called for the effect to be applied.
1084     * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
1085     * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
1086     * so an appropriate conversion from linear UI input x to level is:
1087     * x == 0 -&gt; level = 0
1088     * 0 &lt; x &lt;= R -&gt; level = 10^(72*(x-R)/20/R)
1089     *
1090     * @param level send level scalar
1091     * @return error code or success, see {@link #SUCCESS},
1092     *    {@link #ERROR_INVALID_OPERATION}
1093     */
1094    public int setAuxEffectSendLevel(float level) {
1095        if (mState != STATE_INITIALIZED) {
1096            return ERROR_INVALID_OPERATION;
1097        }
1098        // clamp the level
1099        if (level < getMinVolume()) {
1100            level = getMinVolume();
1101        }
1102        if (level > getMaxVolume()) {
1103            level = getMaxVolume();
1104        }
1105        native_setAuxEffectSendLevel(level);
1106        return SUCCESS;
1107    }
1108
1109    //---------------------------------------------------------
1110    // Interface definitions
1111    //--------------------
1112    /**
1113     * Interface definition for a callback to be invoked when the playback head position of
1114     * an AudioTrack has reached a notification marker or has increased by a certain period.
1115     */
1116    public interface OnPlaybackPositionUpdateListener  {
1117        /**
1118         * Called on the listener to notify it that the previously set marker has been reached
1119         * by the playback head.
1120         */
1121        void onMarkerReached(AudioTrack track);
1122
1123        /**
1124         * Called on the listener to periodically notify it that the playback head has reached
1125         * a multiple of the notification period.
1126         */
1127        void onPeriodicNotification(AudioTrack track);
1128    }
1129
1130
1131    //---------------------------------------------------------
1132    // Inner classes
1133    //--------------------
1134    /**
1135     * Helper class to handle the forwarding of native events to the appropriate listener
1136     * (potentially) handled in a different thread
1137     */
1138    private class NativeEventHandlerDelegate {
1139        private final AudioTrack mAudioTrack;
1140        private final Handler mHandler;
1141
1142        NativeEventHandlerDelegate(AudioTrack track, Handler handler) {
1143            mAudioTrack = track;
1144            // find the looper for our new event handler
1145            Looper looper;
1146            if (handler != null) {
1147                looper = handler.getLooper();
1148            } else {
1149                // no given handler, use the looper the AudioTrack was created in
1150                looper = mInitializationLooper;
1151            }
1152
1153            // construct the event handler with this looper
1154            if (looper != null) {
1155                // implement the event handler delegate
1156                mHandler = new Handler(looper) {
1157                    @Override
1158                    public void handleMessage(Message msg) {
1159                        if (mAudioTrack == null) {
1160                            return;
1161                        }
1162                        OnPlaybackPositionUpdateListener listener = null;
1163                        synchronized (mPositionListenerLock) {
1164                            listener = mAudioTrack.mPositionListener;
1165                        }
1166                        switch(msg.what) {
1167                        case NATIVE_EVENT_MARKER:
1168                            if (listener != null) {
1169                                listener.onMarkerReached(mAudioTrack);
1170                            }
1171                            break;
1172                        case NATIVE_EVENT_NEW_POS:
1173                            if (listener != null) {
1174                                listener.onPeriodicNotification(mAudioTrack);
1175                            }
1176                            break;
1177                        default:
1178                            Log.e(TAG, "[ android.media.AudioTrack.NativeEventHandler ] " +
1179                                    "Unknown event type: " + msg.what);
1180                            break;
1181                        }
1182                    }
1183                };
1184            } else {
1185                mHandler = null;
1186            }
1187        }
1188
1189        Handler getHandler() {
1190            return mHandler;
1191        }
1192    }
1193
1194
1195    //---------------------------------------------------------
1196    // Java methods called from the native side
1197    //--------------------
1198    @SuppressWarnings("unused")
1199    private static void postEventFromNative(Object audiotrack_ref,
1200            int what, int arg1, int arg2, Object obj) {
1201        //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
1202        AudioTrack track = (AudioTrack)((WeakReference)audiotrack_ref).get();
1203        if (track == null) {
1204            return;
1205        }
1206
1207        if (track.mEventHandlerDelegate != null) {
1208            Message m =
1209                track.mEventHandlerDelegate.getHandler().obtainMessage(what, arg1, arg2, obj);
1210            track.mEventHandlerDelegate.getHandler().sendMessage(m);
1211        }
1212
1213    }
1214
1215
1216    //---------------------------------------------------------
1217    // Native methods called from the Java side
1218    //--------------------
1219
1220    private native final int native_setup(Object audiotrack_this,
1221            int streamType, int sampleRate, int nbChannels, int audioFormat,
1222            int buffSizeInBytes, int mode, int[] sessionId);
1223
1224    private native final void native_finalize();
1225
1226    private native final void native_release();
1227
1228    private native final void native_start();
1229
1230    private native final void native_stop();
1231
1232    private native final void native_pause();
1233
1234    private native final void native_flush();
1235
1236    private native final int native_write_byte(byte[] audioData,
1237                                               int offsetInBytes, int sizeInBytes, int format);
1238
1239    private native final int native_write_short(short[] audioData,
1240                                                int offsetInShorts, int sizeInShorts, int format);
1241
1242    private native final int native_reload_static();
1243
1244    private native final int native_get_native_frame_count();
1245
1246    private native final void native_setVolume(float leftVolume, float rightVolume);
1247
1248    private native final int native_set_playback_rate(int sampleRateInHz);
1249    private native final int native_get_playback_rate();
1250
1251    private native final int native_set_marker_pos(int marker);
1252    private native final int native_get_marker_pos();
1253
1254    private native final int native_set_pos_update_period(int updatePeriod);
1255    private native final int native_get_pos_update_period();
1256
1257    private native final int native_set_position(int position);
1258    private native final int native_get_position();
1259
1260    private native final int native_set_loop(int start, int end, int loopCount);
1261
1262    static private native final int native_get_output_sample_rate(int streamType);
1263    static private native final int native_get_min_buff_size(
1264            int sampleRateInHz, int channelConfig, int audioFormat);
1265
1266    private native final int native_get_session_id();
1267
1268    private native final int native_attachAuxEffect(int effectId);
1269    private native final void native_setAuxEffectSendLevel(float level);
1270
1271    //---------------------------------------------------------
1272    // Utility methods
1273    //------------------
1274
1275    private static void logd(String msg) {
1276        Log.d(TAG, "[ android.media.AudioTrack ] " + msg);
1277    }
1278
1279    private static void loge(String msg) {
1280        Log.e(TAG, "[ android.media.AudioTrack ] " + msg);
1281    }
1282
1283}
1284