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