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