Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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 
     17 package android.media.cts;
     18 
     19 import android.content.pm.PackageManager;
     20 import android.cts.util.CtsAndroidTestCase;
     21 import android.media.AudioFormat;
     22 import android.media.AudioManager;
     23 import android.media.AudioTimestamp;
     24 import android.media.AudioTrack;
     25 import android.util.Log;
     26 import com.android.cts.util.ReportLog;
     27 import com.android.cts.util.ResultType;
     28 import com.android.cts.util.ResultUnit;
     29 
     30 import java.nio.ByteOrder;
     31 import java.nio.ByteBuffer;
     32 import java.nio.ShortBuffer;
     33 import java.nio.FloatBuffer;
     34 
     35 public class AudioTrackTest extends CtsAndroidTestCase {
     36     private String TAG = "AudioTrackTest";
     37     private final long WAIT_MSEC = 200;
     38     private final int OFFSET_DEFAULT = 0;
     39     private final int OFFSET_NEGATIVE = -10;
     40 
     41     private void log(String testName, String message) {
     42         Log.v(TAG, "[" + testName + "] " + message);
     43     }
     44 
     45     private void loge(String testName, String message) {
     46         Log.e(TAG, "[" + testName + "] " + message);
     47     }
     48 
     49     // -----------------------------------------------------------------
     50     // private class to hold test results
     51     private static class TestResults {
     52         public boolean mResult = false;
     53         public String mResultLog = "";
     54 
     55         public TestResults(boolean b, String s) {
     56             mResult = b;
     57             mResultLog = s;
     58         }
     59     }
     60 
     61     // -----------------------------------------------------------------
     62     // generic test methods
     63     public TestResults constructorTestMultiSampleRate(
     64     // parameters tested by this method
     65             int _inTest_streamType, int _inTest_mode, int _inTest_config, int _inTest_format,
     66             // parameter-dependent expected results
     67             int _expected_stateForMode) {
     68 
     69         int[] testSampleRates = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 };
     70         String failedRates = "Failure for rate(s): ";
     71         boolean localRes, finalRes = true;
     72 
     73         for (int i = 0; i < testSampleRates.length; i++) {
     74             AudioTrack track = null;
     75             try {
     76                 track = new AudioTrack(_inTest_streamType, testSampleRates[i], _inTest_config,
     77                         _inTest_format, AudioTrack.getMinBufferSize(testSampleRates[i],
     78                                 _inTest_config, _inTest_format), _inTest_mode);
     79             } catch (IllegalArgumentException iae) {
     80                 Log.e("MediaAudioTrackTest", "[ constructorTestMultiSampleRate ] exception at SR "
     81                         + testSampleRates[i] + ": \n" + iae);
     82                 localRes = false;
     83             }
     84             if (track != null) {
     85                 localRes = (track.getState() == _expected_stateForMode);
     86                 track.release();
     87             } else {
     88                 localRes = false;
     89             }
     90 
     91             if (!localRes) {
     92                 // log the error for the test runner
     93                 failedRates += Integer.toString(testSampleRates[i]) + "Hz ";
     94                 // log the error for logcat
     95                 log("constructorTestMultiSampleRate", "failed to construct "
     96                         + "AudioTrack(streamType="
     97                         + _inTest_streamType
     98                         + ", sampleRateInHz="
     99                         + testSampleRates[i]
    100                         + ", channelConfig="
    101                         + _inTest_config
    102                         + ", audioFormat="
    103                         + _inTest_format
    104                         + ", bufferSizeInBytes="
    105                         + AudioTrack.getMinBufferSize(testSampleRates[i], _inTest_config,
    106                                 AudioFormat.ENCODING_PCM_16BIT) + ", mode=" + _inTest_mode);
    107                 // mark test as failed
    108                 finalRes = false;
    109             }
    110         }
    111         return new TestResults(finalRes, failedRates);
    112     }
    113 
    114     // -----------------------------------------------------------------
    115     // AUDIOTRACK TESTS:
    116     // ----------------------------------
    117 
    118     // -----------------------------------------------------------------
    119     // AudioTrack constructor and AudioTrack.getMinBufferSize(...) for 16bit PCM
    120     // ----------------------------------
    121 
    122     // Test case 1: constructor for streaming AudioTrack, mono, 16bit at misc
    123     // valid sample rates
    124     public void testConstructorMono16MusicStream() throws Exception {
    125 
    126         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    127                 AudioTrack.MODE_STREAM, AudioFormat.CHANNEL_CONFIGURATION_MONO,
    128                 AudioFormat.ENCODING_PCM_16BIT, AudioTrack.STATE_INITIALIZED);
    129 
    130         assertTrue("testConstructorMono16MusicStream: " + res.mResultLog, res.mResult);
    131     }
    132 
    133     // Test case 2: constructor for streaming AudioTrack, stereo, 16bit at misc
    134     // valid sample rates
    135     public void testConstructorStereo16MusicStream() throws Exception {
    136 
    137         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    138                 AudioTrack.MODE_STREAM, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
    139                 AudioFormat.ENCODING_PCM_16BIT, AudioTrack.STATE_INITIALIZED);
    140 
    141         assertTrue("testConstructorStereo16MusicStream: " + res.mResultLog, res.mResult);
    142     }
    143 
    144     // Test case 3: constructor for static AudioTrack, mono, 16bit at misc valid
    145     // sample rates
    146     public void testConstructorMono16MusicStatic() throws Exception {
    147 
    148         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    149                 AudioTrack.MODE_STATIC, AudioFormat.CHANNEL_CONFIGURATION_MONO,
    150                 AudioFormat.ENCODING_PCM_16BIT, AudioTrack.STATE_NO_STATIC_DATA);
    151 
    152         assertTrue("testConstructorMono16MusicStatic: " + res.mResultLog, res.mResult);
    153     }
    154 
    155     // Test case 4: constructor for static AudioTrack, stereo, 16bit at misc
    156     // valid sample rates
    157     public void testConstructorStereo16MusicStatic() throws Exception {
    158 
    159         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    160                 AudioTrack.MODE_STATIC, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
    161                 AudioFormat.ENCODING_PCM_16BIT, AudioTrack.STATE_NO_STATIC_DATA);
    162 
    163         assertTrue("testConstructorStereo16MusicStatic: " + res.mResultLog, res.mResult);
    164     }
    165 
    166     // -----------------------------------------------------------------
    167     // AudioTrack constructor and AudioTrack.getMinBufferSize(...) for 8bit PCM
    168     // ----------------------------------
    169 
    170     // Test case 1: constructor for streaming AudioTrack, mono, 8bit at misc
    171     // valid sample rates
    172     public void testConstructorMono8MusicStream() throws Exception {
    173 
    174         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    175                 AudioTrack.MODE_STREAM, AudioFormat.CHANNEL_CONFIGURATION_MONO,
    176                 AudioFormat.ENCODING_PCM_8BIT, AudioTrack.STATE_INITIALIZED);
    177 
    178         assertTrue("testConstructorMono8MusicStream: " + res.mResultLog, res.mResult);
    179     }
    180 
    181     // Test case 2: constructor for streaming AudioTrack, stereo, 8bit at misc
    182     // valid sample rates
    183     public void testConstructorStereo8MusicStream() throws Exception {
    184 
    185         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    186                 AudioTrack.MODE_STREAM, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
    187                 AudioFormat.ENCODING_PCM_8BIT, AudioTrack.STATE_INITIALIZED);
    188 
    189         assertTrue("testConstructorStereo8MusicStream: " + res.mResultLog, res.mResult);
    190     }
    191 
    192     // Test case 3: constructor for static AudioTrack, mono, 8bit at misc valid
    193     // sample rates
    194     public void testConstructorMono8MusicStatic() throws Exception {
    195 
    196         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    197                 AudioTrack.MODE_STATIC, AudioFormat.CHANNEL_CONFIGURATION_MONO,
    198                 AudioFormat.ENCODING_PCM_8BIT, AudioTrack.STATE_NO_STATIC_DATA);
    199 
    200         assertTrue("testConstructorMono8MusicStatic: " + res.mResultLog, res.mResult);
    201     }
    202 
    203     // Test case 4: constructor for static AudioTrack, stereo, 8bit at misc
    204     // valid sample rates
    205     public void testConstructorStereo8MusicStatic() throws Exception {
    206 
    207         TestResults res = constructorTestMultiSampleRate(AudioManager.STREAM_MUSIC,
    208                 AudioTrack.MODE_STATIC, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
    209                 AudioFormat.ENCODING_PCM_8BIT, AudioTrack.STATE_NO_STATIC_DATA);
    210 
    211         assertTrue("testConstructorStereo8MusicStatic: " + res.mResultLog, res.mResult);
    212     }
    213 
    214     // -----------------------------------------------------------------
    215     // AudioTrack constructor for all stream types
    216     // ----------------------------------
    217 
    218     // Test case 1: constructor for all stream types
    219     public void testConstructorStreamType() throws Exception {
    220         // constants for test
    221         final int TYPE_TEST_SR = 22050;
    222         final int TYPE_TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    223         final int TYPE_TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    224         final int TYPE_TEST_MODE = AudioTrack.MODE_STREAM;
    225         final int[] STREAM_TYPES = { AudioManager.STREAM_ALARM, AudioManager.STREAM_MUSIC,
    226                 AudioManager.STREAM_NOTIFICATION, AudioManager.STREAM_RING,
    227                 AudioManager.STREAM_SYSTEM, AudioManager.STREAM_VOICE_CALL };
    228         final String[] STREAM_NAMES = { "STREAM_ALARM", "STREAM_MUSIC", "STREAM_NOTIFICATION",
    229                 "STREAM_RING", "STREAM_SYSTEM", "STREAM_VOICE_CALL" };
    230 
    231         boolean localTestRes = true;
    232         AudioTrack track = null;
    233         // test: loop constructor on all stream types
    234         for (int i = 0; i < STREAM_TYPES.length; i++) {
    235             try {
    236                 // -------- initialization --------------
    237                 track = new AudioTrack(STREAM_TYPES[i], TYPE_TEST_SR, TYPE_TEST_CONF,
    238                         TYPE_TEST_FORMAT, AudioTrack.getMinBufferSize(TYPE_TEST_SR, TYPE_TEST_CONF,
    239                                 TYPE_TEST_FORMAT), TYPE_TEST_MODE);
    240             } catch (IllegalArgumentException iae) {
    241                 loge("testConstructorStreamType", "exception for stream type " + STREAM_NAMES[i]
    242                         + ": " + iae);
    243                 localTestRes = false;
    244             }
    245             // -------- test --------------
    246             if (track != null) {
    247                 if (track.getState() != AudioTrack.STATE_INITIALIZED) {
    248                     localTestRes = false;
    249                     Log.e("MediaAudioTrackTest",
    250                             "[ testConstructorStreamType ] failed for stream type "
    251                                     + STREAM_NAMES[i]);
    252                 }
    253                 // -------- tear down --------------
    254                 track.release();
    255             } else {
    256                 localTestRes = false;
    257             }
    258         }
    259 
    260         assertTrue("testConstructorStreamType", localTestRes);
    261     }
    262 
    263     // -----------------------------------------------------------------
    264     // Playback head position
    265     // ----------------------------------
    266 
    267     // Test case 1: getPlaybackHeadPosition() at 0 after initialization
    268     public void testPlaybackHeadPositionAfterInit() throws Exception {
    269         // constants for test
    270         final String TEST_NAME = "testPlaybackHeadPositionAfterInit";
    271         final int TEST_SR = 22050;
    272         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    273         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    274         final int TEST_MODE = AudioTrack.MODE_STREAM;
    275         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    276 
    277         // -------- initialization --------------
    278         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    279                 AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT), TEST_MODE);
    280         // -------- test --------------
    281         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    282         assertTrue(TEST_NAME, track.getPlaybackHeadPosition() == 0);
    283         // -------- tear down --------------
    284         track.release();
    285     }
    286 
    287     // Test case 2: getPlaybackHeadPosition() increases after play()
    288     public void testPlaybackHeadPositionIncrease() throws Exception {
    289         // constants for test
    290         final String TEST_NAME = "testPlaybackHeadPositionIncrease";
    291         final int TEST_SR = 22050;
    292         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    293         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    294         final int TEST_MODE = AudioTrack.MODE_STREAM;
    295         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    296 
    297         // -------- initialization --------------
    298         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    299         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    300                 2 * minBuffSize, TEST_MODE);
    301         byte data[] = new byte[minBuffSize];
    302         // -------- test --------------
    303         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    304         track.write(data, OFFSET_DEFAULT, data.length);
    305         track.write(data, OFFSET_DEFAULT, data.length);
    306         track.play();
    307         Thread.sleep(100);
    308         log(TEST_NAME, "position =" + track.getPlaybackHeadPosition());
    309         assertTrue(TEST_NAME, track.getPlaybackHeadPosition() > 0);
    310         // -------- tear down --------------
    311         track.release();
    312     }
    313 
    314     // Test case 3: getPlaybackHeadPosition() is 0 after flush();
    315     public void testPlaybackHeadPositionAfterFlush() throws Exception {
    316         // constants for test
    317         final String TEST_NAME = "testPlaybackHeadPositionAfterFlush";
    318         final int TEST_SR = 22050;
    319         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    320         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    321         final int TEST_MODE = AudioTrack.MODE_STREAM;
    322         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    323 
    324         // -------- initialization --------------
    325         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    326         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    327                 2 * minBuffSize, TEST_MODE);
    328         byte data[] = new byte[minBuffSize];
    329         // -------- test --------------
    330         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    331         track.write(data, OFFSET_DEFAULT, data.length);
    332         track.write(data, OFFSET_DEFAULT, data.length);
    333         track.play();
    334         Thread.sleep(WAIT_MSEC);
    335         track.stop();
    336         track.flush();
    337         log(TEST_NAME, "position =" + track.getPlaybackHeadPosition());
    338         assertTrue(TEST_NAME, track.getPlaybackHeadPosition() == 0);
    339         // -------- tear down --------------
    340         track.release();
    341     }
    342 
    343     // Test case 3: getPlaybackHeadPosition() is 0 after stop();
    344     public void testPlaybackHeadPositionAfterStop() throws Exception {
    345         // constants for test
    346         final String TEST_NAME = "testPlaybackHeadPositionAfterStop";
    347         final int TEST_SR = 22050;
    348         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    349         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    350         final int TEST_MODE = AudioTrack.MODE_STREAM;
    351         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    352         final int TEST_LOOP_CNT = 10;
    353 
    354         // -------- initialization --------------
    355         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    356         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    357                 2 * minBuffSize, TEST_MODE);
    358         byte data[] = new byte[minBuffSize];
    359         // -------- test --------------
    360         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    361         track.write(data, OFFSET_DEFAULT, data.length);
    362         track.write(data, OFFSET_DEFAULT, data.length);
    363         track.play();
    364         Thread.sleep(WAIT_MSEC);
    365         track.stop();
    366         int count = 0;
    367         int pos;
    368         do {
    369             Thread.sleep(WAIT_MSEC);
    370             pos = track.getPlaybackHeadPosition();
    371             count++;
    372         } while((pos != 0) && (count < TEST_LOOP_CNT));
    373         log(TEST_NAME, "position =" + pos + ", read count ="+count);
    374         assertTrue(TEST_NAME, pos == 0);
    375         // -------- tear down --------------
    376         track.release();
    377     }
    378 
    379     // Test case 4: getPlaybackHeadPosition() is > 0 after play(); pause();
    380     public void testPlaybackHeadPositionAfterPause() throws Exception {
    381         // constants for test
    382         final String TEST_NAME = "testPlaybackHeadPositionAfterPause";
    383         final int TEST_SR = 22050;
    384         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    385         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    386         final int TEST_MODE = AudioTrack.MODE_STREAM;
    387         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    388 
    389         // -------- initialization --------------
    390         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    391         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    392                 2 * minBuffSize, TEST_MODE);
    393         byte data[] = new byte[minBuffSize];
    394         // -------- test --------------
    395         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    396         track.write(data, OFFSET_DEFAULT, data.length);
    397         track.write(data, OFFSET_DEFAULT, data.length);
    398         track.play();
    399         Thread.sleep(100);
    400         track.pause();
    401         int pos = track.getPlaybackHeadPosition();
    402         log(TEST_NAME, "position =" + pos);
    403         assertTrue(TEST_NAME, pos > 0);
    404         // -------- tear down --------------
    405         track.release();
    406     }
    407 
    408     // Test case 5: getPlaybackHeadPosition() remains 0 after pause(); flush(); play();
    409     public void testPlaybackHeadPositionAfterFlushAndPlay() throws Exception {
    410         // constants for test
    411         final String TEST_NAME = "testPlaybackHeadPositionAfterFlushAndPlay";
    412         final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
    413         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    414         final int TEST_MODE = AudioTrack.MODE_STREAM;
    415         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    416         final int TEST_SR = AudioTrack.getNativeOutputSampleRate(TEST_STREAM_TYPE);
    417 
    418         // -------- initialization --------------
    419         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    420         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    421                 2 * minBuffSize, TEST_MODE);
    422         byte data[] = new byte[minBuffSize];
    423         // -------- test --------------
    424         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    425         track.write(data, OFFSET_DEFAULT, data.length);
    426         track.write(data, OFFSET_DEFAULT, data.length);
    427         track.play();
    428         Thread.sleep(100);
    429         track.pause();
    430 
    431         int pos = track.getPlaybackHeadPosition();
    432         log(TEST_NAME, "position after pause =" + pos);
    433         assertTrue(TEST_NAME, pos > 0);
    434 
    435         track.flush();
    436         pos = track.getPlaybackHeadPosition();
    437         log(TEST_NAME, "position after flush =" + pos);
    438         assertTrue(TEST_NAME, pos == 0);
    439 
    440         track.play();
    441         pos = track.getPlaybackHeadPosition();
    442         log(TEST_NAME, "position after play =" + pos);
    443         assertTrue(TEST_NAME, pos == 0);
    444 
    445         Thread.sleep(100);
    446         pos = track.getPlaybackHeadPosition();
    447         log(TEST_NAME, "position after 100 ms sleep =" + pos);
    448         assertTrue(TEST_NAME, pos == 0);
    449         // -------- tear down --------------
    450         track.release();
    451     }
    452 
    453     // -----------------------------------------------------------------
    454     // Playback properties
    455     // ----------------------------------
    456 
    457     // Common code for the testSetStereoVolume* and testSetVolume* tests
    458     private void testSetVolumeCommon(String testName, float vol, boolean isStereo) throws Exception {
    459         // constants for test
    460         final int TEST_SR = 22050;
    461         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    462         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    463         final int TEST_MODE = AudioTrack.MODE_STREAM;
    464         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    465 
    466         // -------- initialization --------------
    467         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    468         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    469                 2 * minBuffSize, TEST_MODE);
    470         byte data[] = new byte[minBuffSize];
    471         // -------- test --------------
    472         track.write(data, OFFSET_DEFAULT, data.length);
    473         track.write(data, OFFSET_DEFAULT, data.length);
    474         track.play();
    475         if (isStereo) {
    476             // TODO to really test this, do a pan instead of using same value for left and right
    477             assertTrue(testName, track.setStereoVolume(vol, vol) == AudioTrack.SUCCESS);
    478         } else {
    479             assertTrue(testName, track.setVolume(vol) == AudioTrack.SUCCESS);
    480         }
    481         // -------- tear down --------------
    482         track.release();
    483     }
    484 
    485     // Test case 1: setStereoVolume() with max volume returns SUCCESS
    486     public void testSetStereoVolumeMax() throws Exception {
    487         final String TEST_NAME = "testSetStereoVolumeMax";
    488         float maxVol = AudioTrack.getMaxVolume();
    489         testSetVolumeCommon(TEST_NAME, maxVol, true /*isStereo*/);
    490     }
    491 
    492     // Test case 2: setStereoVolume() with min volume returns SUCCESS
    493     public void testSetStereoVolumeMin() throws Exception {
    494         final String TEST_NAME = "testSetStereoVolumeMin";
    495         float minVol = AudioTrack.getMinVolume();
    496         testSetVolumeCommon(TEST_NAME, minVol, true /*isStereo*/);
    497     }
    498 
    499     // Test case 3: setStereoVolume() with mid volume returns SUCCESS
    500     public void testSetStereoVolumeMid() throws Exception {
    501         final String TEST_NAME = "testSetStereoVolumeMid";
    502         float midVol = (AudioTrack.getMaxVolume() - AudioTrack.getMinVolume()) / 2;
    503         testSetVolumeCommon(TEST_NAME, midVol, true /*isStereo*/);
    504     }
    505 
    506     // Test case 4: setPlaybackRate() with half the content rate returns SUCCESS
    507     public void testSetPlaybackRate() throws Exception {
    508         // constants for test
    509         final String TEST_NAME = "testSetPlaybackRate";
    510         final int TEST_SR = 22050;
    511         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    512         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    513         final int TEST_MODE = AudioTrack.MODE_STREAM;
    514         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    515 
    516         // -------- initialization --------------
    517         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    518         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    519                 2 * minBuffSize, TEST_MODE);
    520         byte data[] = new byte[minBuffSize];
    521         // -------- test --------------
    522         track.write(data, OFFSET_DEFAULT, data.length);
    523         track.write(data, OFFSET_DEFAULT, data.length);
    524         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    525         track.play();
    526         assertTrue(TEST_NAME, track.setPlaybackRate((int) (TEST_SR / 2)) == AudioTrack.SUCCESS);
    527         // -------- tear down --------------
    528         track.release();
    529     }
    530 
    531     // Test case 5: setPlaybackRate(0) returns bad value error
    532     public void testSetPlaybackRateZero() throws Exception {
    533         // constants for test
    534         final String TEST_NAME = "testSetPlaybackRateZero";
    535         final int TEST_SR = 22050;
    536         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    537         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    538         final int TEST_MODE = AudioTrack.MODE_STREAM;
    539         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    540 
    541         // -------- initialization --------------
    542         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    543         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    544                 minBuffSize, TEST_MODE);
    545         // -------- test --------------
    546         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    547         assertTrue(TEST_NAME, track.setPlaybackRate(0) == AudioTrack.ERROR_BAD_VALUE);
    548         // -------- tear down --------------
    549         track.release();
    550     }
    551 
    552     // Test case 6: setPlaybackRate() accepts values twice the output sample
    553     // rate
    554     public void testSetPlaybackRateTwiceOutputSR() throws Exception {
    555         // constants for test
    556         final String TEST_NAME = "testSetPlaybackRateTwiceOutputSR";
    557         final int TEST_SR = 22050;
    558         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    559         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    560         final int TEST_MODE = AudioTrack.MODE_STREAM;
    561         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    562 
    563         // -------- initialization --------------
    564         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    565         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    566                 2 * minBuffSize, TEST_MODE);
    567         byte data[] = new byte[minBuffSize];
    568         int outputSR = AudioTrack.getNativeOutputSampleRate(TEST_STREAM_TYPE);
    569         // -------- test --------------
    570         track.write(data, OFFSET_DEFAULT, data.length);
    571         track.write(data, OFFSET_DEFAULT, data.length);
    572         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    573         track.play();
    574         assertTrue(TEST_NAME, track.setPlaybackRate(2 * outputSR) == AudioTrack.SUCCESS);
    575         // -------- tear down --------------
    576         track.release();
    577     }
    578 
    579     // Test case 7: setPlaybackRate() and retrieve value, should be the same for
    580     // half the content SR
    581     public void testSetGetPlaybackRate() throws Exception {
    582         // constants for test
    583         final String TEST_NAME = "testSetGetPlaybackRate";
    584         final int TEST_SR = 22050;
    585         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
    586         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    587         final int TEST_MODE = AudioTrack.MODE_STREAM;
    588         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    589 
    590         // -------- initialization --------------
    591         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    592         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    593                 2 * minBuffSize, TEST_MODE);
    594         byte data[] = new byte[minBuffSize];
    595         // -------- test --------------
    596         track.write(data, OFFSET_DEFAULT, data.length);
    597         track.write(data, OFFSET_DEFAULT, data.length);
    598         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    599         track.play();
    600         track.setPlaybackRate((int) (TEST_SR / 2));
    601         assertTrue(TEST_NAME, track.getPlaybackRate() == (int) (TEST_SR / 2));
    602         // -------- tear down --------------
    603         track.release();
    604     }
    605 
    606     // Test case 8: setPlaybackRate() invalid operation if track not initialized
    607     public void testSetPlaybackRateUninit() throws Exception {
    608         // constants for test
    609         final String TEST_NAME = "testSetPlaybackRateUninit";
    610         final int TEST_SR = 22050;
    611         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    612         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    613         final int TEST_MODE = AudioTrack.MODE_STATIC;
    614         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    615 
    616         // -------- initialization --------------
    617         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    618         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    619                 minBuffSize, TEST_MODE);
    620         // -------- test --------------
    621         assertEquals(TEST_NAME, AudioTrack.STATE_NO_STATIC_DATA, track.getState());
    622         assertEquals(TEST_NAME, AudioTrack.ERROR_INVALID_OPERATION,
    623                 track.setPlaybackRate(TEST_SR / 2));
    624         // -------- tear down --------------
    625         track.release();
    626     }
    627 
    628     // Test case 9: setVolume() with max volume returns SUCCESS
    629     public void testSetVolumeMax() throws Exception {
    630         final String TEST_NAME = "testSetVolumeMax";
    631         float maxVol = AudioTrack.getMaxVolume();
    632         testSetVolumeCommon(TEST_NAME, maxVol, false /*isStereo*/);
    633     }
    634 
    635     // Test case 10: setVolume() with min volume returns SUCCESS
    636     public void testSetVolumeMin() throws Exception {
    637         final String TEST_NAME = "testSetVolumeMin";
    638         float minVol = AudioTrack.getMinVolume();
    639         testSetVolumeCommon(TEST_NAME, minVol, false /*isStereo*/);
    640     }
    641 
    642     // Test case 11: setVolume() with mid volume returns SUCCESS
    643     public void testSetVolumeMid() throws Exception {
    644         final String TEST_NAME = "testSetVolumeMid";
    645         float midVol = (AudioTrack.getMaxVolume() - AudioTrack.getMinVolume()) / 2;
    646         testSetVolumeCommon(TEST_NAME, midVol, false /*isStereo*/);
    647     }
    648 
    649     // -----------------------------------------------------------------
    650     // Playback progress
    651     // ----------------------------------
    652 
    653     // Test case 1: setPlaybackHeadPosition() on playing track
    654     public void testSetPlaybackHeadPositionPlaying() throws Exception {
    655         // constants for test
    656         final String TEST_NAME = "testSetPlaybackHeadPositionPlaying";
    657         final int TEST_SR = 22050;
    658         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    659         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    660         final int TEST_MODE = AudioTrack.MODE_STREAM;
    661         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    662 
    663         // -------- initialization --------------
    664         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    665         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    666                 2 * minBuffSize, TEST_MODE);
    667         byte data[] = new byte[minBuffSize];
    668         // -------- test --------------
    669         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    670         track.write(data, OFFSET_DEFAULT, data.length);
    671         track.write(data, OFFSET_DEFAULT, data.length);
    672         track.play();
    673         assertTrue(TEST_NAME,
    674                 track.setPlaybackHeadPosition(10) == AudioTrack.ERROR_INVALID_OPERATION);
    675         // -------- tear down --------------
    676         track.release();
    677     }
    678 
    679     // Test case 2: setPlaybackHeadPosition() on stopped track
    680     public void testSetPlaybackHeadPositionStopped() throws Exception {
    681         // constants for test
    682         final String TEST_NAME = "testSetPlaybackHeadPositionStopped";
    683         final int TEST_SR = 22050;
    684         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    685         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    686         final int TEST_MODE = AudioTrack.MODE_STATIC;
    687         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    688 
    689         // -------- initialization --------------
    690         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    691         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    692                 2 * minBuffSize, TEST_MODE);
    693         byte data[] = new byte[minBuffSize];
    694         // -------- test --------------
    695         assertEquals(TEST_NAME, AudioTrack.STATE_NO_STATIC_DATA, track.getState());
    696         track.write(data, OFFSET_DEFAULT, data.length);
    697         track.write(data, OFFSET_DEFAULT, data.length);
    698         assertEquals(TEST_NAME, AudioTrack.STATE_INITIALIZED, track.getState());
    699         track.play();
    700         track.stop();
    701         assertEquals(TEST_NAME, AudioTrack.PLAYSTATE_STOPPED, track.getPlayState());
    702         assertEquals(TEST_NAME, AudioTrack.SUCCESS, track.setPlaybackHeadPosition(10));
    703         // -------- tear down --------------
    704         track.release();
    705     }
    706 
    707     // Test case 3: setPlaybackHeadPosition() on paused track
    708     public void testSetPlaybackHeadPositionPaused() throws Exception {
    709         // constants for test
    710         final String TEST_NAME = "testSetPlaybackHeadPositionPaused";
    711         final int TEST_SR = 22050;
    712         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    713         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    714         final int TEST_MODE = AudioTrack.MODE_STATIC;
    715         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    716 
    717         // -------- initialization --------------
    718         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    719         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    720                 2 * minBuffSize, TEST_MODE);
    721         byte data[] = new byte[minBuffSize];
    722         // -------- test --------------
    723         assertEquals(TEST_NAME, AudioTrack.STATE_NO_STATIC_DATA, track.getState());
    724         track.write(data, OFFSET_DEFAULT, data.length);
    725         track.write(data, OFFSET_DEFAULT, data.length);
    726         assertEquals(TEST_NAME, AudioTrack.STATE_INITIALIZED, track.getState());
    727         track.play();
    728         track.pause();
    729         assertEquals(TEST_NAME, AudioTrack.PLAYSTATE_PAUSED, track.getPlayState());
    730         assertEquals(TEST_NAME, AudioTrack.SUCCESS, track.setPlaybackHeadPosition(10));
    731         // -------- tear down --------------
    732         track.release();
    733     }
    734 
    735     // Test case 4: setPlaybackHeadPosition() beyond what has been written
    736     public void testSetPlaybackHeadPositionTooFar() throws Exception {
    737         // constants for test
    738         final String TEST_NAME = "testSetPlaybackHeadPositionTooFar";
    739         final int TEST_SR = 22050;
    740         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    741         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    742         final int TEST_MODE = AudioTrack.MODE_STATIC;
    743         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    744 
    745         // -------- initialization --------------
    746         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    747         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    748                 2 * minBuffSize, TEST_MODE);
    749         byte data[] = new byte[minBuffSize];
    750         // make up a frame index that's beyond what has been written: go from
    751         // buffer size to frame
    752         // count (given the audio track properties), and add 77.
    753         int frameIndexTooFar = (2 * minBuffSize / 2) + 77;
    754         // -------- test --------------
    755         assertEquals(TEST_NAME, AudioTrack.STATE_NO_STATIC_DATA, track.getState());
    756         track.write(data, OFFSET_DEFAULT, data.length);
    757         track.write(data, OFFSET_DEFAULT, data.length);
    758         assertEquals(TEST_NAME, AudioTrack.STATE_INITIALIZED, track.getState());
    759         track.play();
    760         track.stop();
    761         assertEquals(TEST_NAME, AudioTrack.PLAYSTATE_STOPPED, track.getPlayState());
    762         assertEquals(TEST_NAME, AudioTrack.ERROR_BAD_VALUE,
    763                 track.setPlaybackHeadPosition(frameIndexTooFar));
    764         // -------- tear down --------------
    765         track.release();
    766     }
    767 
    768     // Test case 5: setLoopPoints() fails for MODE_STREAM
    769     public void testSetLoopPointsStream() throws Exception {
    770         // constants for test
    771         final String TEST_NAME = "testSetLoopPointsStream";
    772         final int TEST_SR = 22050;
    773         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    774         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    775         final int TEST_MODE = AudioTrack.MODE_STREAM;
    776         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    777 
    778         // -------- initialization --------------
    779         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    780         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    781                 2 * minBuffSize, TEST_MODE);
    782         byte data[] = new byte[minBuffSize];
    783         // -------- test --------------
    784         track.write(data, OFFSET_DEFAULT, data.length);
    785         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    786         assertTrue(TEST_NAME, track.setLoopPoints(2, 50, 2) == AudioTrack.ERROR_INVALID_OPERATION);
    787         // -------- tear down --------------
    788         track.release();
    789     }
    790 
    791     // Test case 6: setLoopPoints() fails start > end
    792     public void testSetLoopPointsStartAfterEnd() throws Exception {
    793         // constants for test
    794         final String TEST_NAME = "testSetLoopPointsStartAfterEnd";
    795         final int TEST_SR = 22050;
    796         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    797         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    798         final int TEST_MODE = AudioTrack.MODE_STATIC;
    799         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    800 
    801         // -------- initialization --------------
    802         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    803         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    804                 minBuffSize, TEST_MODE);
    805         byte data[] = new byte[minBuffSize];
    806         // -------- test --------------
    807         track.write(data, OFFSET_DEFAULT, data.length);
    808         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    809         assertTrue(TEST_NAME, track.setLoopPoints(50, 0, 2) == AudioTrack.ERROR_BAD_VALUE);
    810         // -------- tear down --------------
    811         track.release();
    812     }
    813 
    814     // Test case 6: setLoopPoints() success
    815     public void testSetLoopPointsSuccess() throws Exception {
    816         // constants for test
    817         final String TEST_NAME = "testSetLoopPointsSuccess";
    818         final int TEST_SR = 22050;
    819         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    820         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    821         final int TEST_MODE = AudioTrack.MODE_STATIC;
    822         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    823 
    824         // -------- initialization --------------
    825         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    826         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    827                 minBuffSize, TEST_MODE);
    828         byte data[] = new byte[minBuffSize];
    829         // -------- test --------------
    830         track.write(data, OFFSET_DEFAULT, data.length);
    831         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    832         assertTrue(TEST_NAME, track.setLoopPoints(0, 50, 2) == AudioTrack.SUCCESS);
    833         // -------- tear down --------------
    834         track.release();
    835     }
    836 
    837     // Test case 7: setLoopPoints() fails with loop length bigger than content
    838     public void testSetLoopPointsLoopTooLong() throws Exception {
    839         // constants for test
    840         final String TEST_NAME = "testSetLoopPointsLoopTooLong";
    841         final int TEST_SR = 22050;
    842         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    843         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    844         final int TEST_MODE = AudioTrack.MODE_STATIC;
    845         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    846 
    847         // -------- initialization --------------
    848         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    849         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    850                 minBuffSize, TEST_MODE);
    851         byte data[] = new byte[minBuffSize];
    852         int dataSizeInFrames = minBuffSize / 2;
    853         // -------- test --------------
    854         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_NO_STATIC_DATA);
    855         track.write(data, OFFSET_DEFAULT, data.length);
    856         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    857         assertTrue(TEST_NAME, track.setLoopPoints(10, dataSizeInFrames + 20, 2) ==
    858             AudioTrack.ERROR_BAD_VALUE);
    859         // -------- tear down --------------
    860         track.release();
    861     }
    862 
    863     // Test case 8: setLoopPoints() fails with start beyond what can be written
    864     // for the track
    865     public void testSetLoopPointsStartTooFar() throws Exception {
    866         // constants for test
    867         final String TEST_NAME = "testSetLoopPointsStartTooFar";
    868         final int TEST_SR = 22050;
    869         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    870         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    871         final int TEST_MODE = AudioTrack.MODE_STATIC;
    872         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    873 
    874         // -------- initialization --------------
    875         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    876         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    877                 minBuffSize, TEST_MODE);
    878         byte data[] = new byte[minBuffSize];
    879         int dataSizeInFrames = minBuffSize / 2;// 16bit data
    880         // -------- test --------------
    881         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_NO_STATIC_DATA);
    882         track.write(data, OFFSET_DEFAULT, data.length);
    883         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    884         assertTrue(TEST_NAME,
    885                 track.setLoopPoints(dataSizeInFrames + 20, dataSizeInFrames + 50, 2) ==
    886                     AudioTrack.ERROR_BAD_VALUE);
    887         // -------- tear down --------------
    888         track.release();
    889     }
    890 
    891     // Test case 9: setLoopPoints() fails with end beyond what can be written
    892     // for the track
    893     public void testSetLoopPointsEndTooFar() throws Exception {
    894         // constants for test
    895         final String TEST_NAME = "testSetLoopPointsEndTooFar";
    896         final int TEST_SR = 22050;
    897         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    898         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    899         final int TEST_MODE = AudioTrack.MODE_STATIC;
    900         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    901 
    902         // -------- initialization --------------
    903         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    904         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    905                 minBuffSize, TEST_MODE);
    906         byte data[] = new byte[minBuffSize];
    907         int dataSizeInFrames = minBuffSize / 2;// 16bit data
    908         // -------- test --------------
    909         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_NO_STATIC_DATA);
    910         track.write(data, OFFSET_DEFAULT, data.length);
    911         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    912         int loopCount = 2;
    913         assertTrue(TEST_NAME,
    914                 track.setLoopPoints(dataSizeInFrames - 10, dataSizeInFrames + 50, loopCount) ==
    915                     AudioTrack.ERROR_BAD_VALUE);
    916         // -------- tear down --------------
    917         track.release();
    918     }
    919 
    920     // -----------------------------------------------------------------
    921     // Audio data supply
    922     // ----------------------------------
    923 
    924     // Test case 1: write() fails when supplying less data (bytes) than declared
    925     public void testWriteByteOffsetTooBig() throws Exception {
    926         // constants for test
    927         final String TEST_NAME = "testWriteByteOffsetTooBig";
    928         final int TEST_SR = 22050;
    929         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    930         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    931         final int TEST_MODE = AudioTrack.MODE_STREAM;
    932         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    933 
    934         // -------- initialization --------------
    935         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    936         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    937                 2 * minBuffSize, TEST_MODE);
    938         byte data[] = new byte[minBuffSize];
    939         // -------- test --------------
    940         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    941         int offset = 10;
    942         assertTrue(TEST_NAME, track.write(data, offset, data.length) == AudioTrack.ERROR_BAD_VALUE);
    943         // -------- tear down --------------
    944         track.release();
    945     }
    946 
    947     // Test case 2: write() fails when supplying less data (shorts) than
    948     // declared
    949     public void testWriteShortOffsetTooBig() throws Exception {
    950         // constants for test
    951         final String TEST_NAME = "testWriteShortOffsetTooBig";
    952         final int TEST_SR = 22050;
    953         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    954         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    955         final int TEST_MODE = AudioTrack.MODE_STREAM;
    956         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    957 
    958         // -------- initialization --------------
    959         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    960         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    961                 2 * minBuffSize, TEST_MODE);
    962         short data[] = new short[minBuffSize / 2];
    963         // -------- test --------------
    964         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    965         int offset = 10;
    966         assertTrue(TEST_NAME, track.write(data, offset, data.length)
    967                                                             == AudioTrack.ERROR_BAD_VALUE);
    968         // -------- tear down --------------
    969         track.release();
    970     }
    971 
    972     // Test case 3: write() fails when supplying less data (bytes) than declared
    973     public void testWriteByteSizeTooBig() throws Exception {
    974         // constants for test
    975         final String TEST_NAME = "testWriteByteSizeTooBig";
    976         final int TEST_SR = 22050;
    977         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    978         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    979         final int TEST_MODE = AudioTrack.MODE_STREAM;
    980         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
    981 
    982         // -------- initialization --------------
    983         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
    984         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
    985                 2 * minBuffSize, TEST_MODE);
    986         byte data[] = new byte[minBuffSize];
    987         // -------- test --------------
    988         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
    989         assertTrue(TEST_NAME, track.write(data, OFFSET_DEFAULT, data.length + 10)
    990                                                         == AudioTrack.ERROR_BAD_VALUE);
    991         // -------- tear down --------------
    992         track.release();
    993     }
    994 
    995     // Test case 4: write() fails when supplying less data (shorts) than
    996     // declared
    997     public void testWriteShortSizeTooBig() throws Exception {
    998         // constants for test
    999         final String TEST_NAME = "testWriteShortSizeTooBig";
   1000         final int TEST_SR = 22050;
   1001         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1002         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1003         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1004         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1005 
   1006         // -------- initialization --------------
   1007         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1008         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1009                 2 * minBuffSize, TEST_MODE);
   1010         short data[] = new short[minBuffSize / 2];
   1011         // -------- test --------------
   1012         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1013         assertTrue(TEST_NAME, track.write(data, OFFSET_DEFAULT, data.length + 10)
   1014                                                         == AudioTrack.ERROR_BAD_VALUE);
   1015         // -------- tear down --------------
   1016         track.release();
   1017     }
   1018 
   1019     // Test case 5: write() fails with negative offset
   1020     public void testWriteByteNegativeOffset() throws Exception {
   1021         // constants for test
   1022         final String TEST_NAME = "testWriteByteNegativeOffset";
   1023         final int TEST_SR = 22050;
   1024         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1025         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1026         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1027         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1028 
   1029         // -------- initialization --------------
   1030         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1031         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1032                 2 * minBuffSize, TEST_MODE);
   1033         byte data[] = new byte[minBuffSize];
   1034         // -------- test --------------
   1035         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1036         assertTrue(TEST_NAME, track.write(data, OFFSET_NEGATIVE, data.length - 10) ==
   1037             AudioTrack.ERROR_BAD_VALUE);
   1038         // -------- tear down --------------
   1039         track.release();
   1040     }
   1041 
   1042     // Test case 6: write() fails with negative offset
   1043     public void testWriteShortNegativeOffset() throws Exception {
   1044         // constants for test
   1045         final String TEST_NAME = "testWriteShortNegativeOffset";
   1046         final int TEST_SR = 22050;
   1047         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1048         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1049         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1050         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1051 
   1052         // -------- initialization --------------
   1053         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1054         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1055                 2 * minBuffSize, TEST_MODE);
   1056         short data[] = new short[minBuffSize / 2];
   1057         // -------- test --------------
   1058         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1059         assertTrue(TEST_NAME,
   1060         track.write(data, OFFSET_NEGATIVE, data.length - 10) == AudioTrack.ERROR_BAD_VALUE);
   1061         // -------- tear down --------------
   1062         track.release();
   1063     }
   1064 
   1065     // Test case 7: write() fails with negative size
   1066     public void testWriteByteNegativeSize() throws Exception {
   1067         // constants for test
   1068         final String TEST_NAME = "testWriteByteNegativeSize";
   1069         final int TEST_SR = 22050;
   1070         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1071         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1072         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1073         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1074 
   1075         // -------- initialization --------------
   1076         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1077         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1078                 2 * minBuffSize, TEST_MODE);
   1079         byte data[] = new byte[minBuffSize];
   1080         // -------- test --------------
   1081         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1082         int dataLength = -10;
   1083         assertTrue(TEST_NAME, track.write(data, OFFSET_DEFAULT, dataLength)
   1084                                                     == AudioTrack.ERROR_BAD_VALUE);
   1085         // -------- tear down --------------
   1086         track.release();
   1087     }
   1088 
   1089     // Test case 8: write() fails with negative size
   1090     public void testWriteShortNegativeSize() throws Exception {
   1091         // constants for test
   1092         final String TEST_NAME = "testWriteShortNegativeSize";
   1093         final int TEST_SR = 22050;
   1094         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1095         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1096         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1097         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1098 
   1099         // -------- initialization --------------
   1100         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1101         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1102                 2 * minBuffSize, TEST_MODE);
   1103         short data[] = new short[minBuffSize / 2];
   1104         // -------- test --------------
   1105         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1106         int dataLength = -10;
   1107         assertTrue(TEST_NAME, track.write(data, OFFSET_DEFAULT, dataLength)
   1108                                                         == AudioTrack.ERROR_BAD_VALUE);
   1109         // -------- tear down --------------
   1110         track.release();
   1111     }
   1112 
   1113     // Test case 9: write() succeeds and returns the size that was written for
   1114     // 16bit
   1115     public void testWriteByte() throws Exception {
   1116         // constants for test
   1117         final String TEST_NAME = "testWriteByte";
   1118         final int TEST_SR = 22050;
   1119         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1120         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1121         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1122         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1123 
   1124         // -------- initialization --------------
   1125         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1126         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1127                 2 * minBuffSize, TEST_MODE);
   1128         byte data[] = new byte[minBuffSize];
   1129         // -------- test --------------
   1130         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1131         assertTrue(TEST_NAME, track.write(data, OFFSET_DEFAULT, data.length) == data.length);
   1132         // -------- tear down --------------
   1133         track.release();
   1134     }
   1135 
   1136     // Test case 10: write() succeeds and returns the size that was written for
   1137     // 16bit
   1138     public void testWriteShort() throws Exception {
   1139         // constants for test
   1140         final String TEST_NAME = "testWriteShort";
   1141         final int TEST_SR = 22050;
   1142         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1143         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1144         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1145         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1146 
   1147         // -------- initialization --------------
   1148         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1149         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1150                 2 * minBuffSize, TEST_MODE);
   1151         short data[] = new short[minBuffSize / 2];
   1152         // -------- test --------------
   1153         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1154         assertTrue(TEST_NAME, track.write(data, OFFSET_DEFAULT, data.length) == data.length);
   1155         track.flush();
   1156         // -------- tear down --------------
   1157         track.release();
   1158     }
   1159 
   1160     // Test case 11: write() succeeds and returns the size that was written for
   1161     // 8bit
   1162     public void testWriteByte8bit() throws Exception {
   1163         // constants for test
   1164         final String TEST_NAME = "testWriteByte8bit";
   1165         final int TEST_SR = 22050;
   1166         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1167         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
   1168         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1169         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1170 
   1171         // -------- initialization --------------
   1172         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1173         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1174                 2 * minBuffSize, TEST_MODE);
   1175         byte data[] = new byte[minBuffSize];
   1176         // -------- test --------------
   1177         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1178         assertEquals(TEST_NAME, data.length, track.write(data, OFFSET_DEFAULT, data.length));
   1179         // -------- tear down --------------
   1180         track.release();
   1181     }
   1182 
   1183     // Test case 12: write() succeeds and returns the size that was written for
   1184     // 8bit
   1185     public void testWriteShort8bit() throws Exception {
   1186         // constants for test
   1187         final String TEST_NAME = "testWriteShort8bit";
   1188         final int TEST_SR = 22050;
   1189         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1190         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
   1191         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1192         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1193 
   1194         // -------- initialization --------------
   1195         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1196         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1197                 2 * minBuffSize, TEST_MODE);
   1198         short data[] = new short[minBuffSize / 2];
   1199         // -------- test --------------
   1200         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1201         assertEquals(TEST_NAME, data.length, track.write(data, OFFSET_DEFAULT, data.length));
   1202         // -------- tear down --------------
   1203         track.release();
   1204     }
   1205 
   1206     // -----------------------------------------------------------------
   1207     // Getters
   1208     // ----------------------------------
   1209 
   1210     // Test case 1: getMinBufferSize() return ERROR_BAD_VALUE if SR < 4000
   1211     public void testGetMinBufferSizeTooLowSR() throws Exception {
   1212         // constant for test
   1213         final String TEST_NAME = "testGetMinBufferSizeTooLowSR";
   1214         final int TEST_SR = 3999;
   1215         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1216         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
   1217 
   1218         // -------- initialization & test --------------
   1219         assertTrue(TEST_NAME, AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT) ==
   1220             AudioTrack.ERROR_BAD_VALUE);
   1221     }
   1222 
   1223     // Test case 2: getMinBufferSize() return ERROR_BAD_VALUE if sample rate too high
   1224     public void testGetMinBufferSizeTooHighSR() throws Exception {
   1225         // constant for test
   1226         final String TEST_NAME = "testGetMinBufferSizeTooHighSR";
   1227         // FIXME need an API to retrieve AudioTrack.SAMPLE_RATE_HZ_MAX
   1228         final int TEST_SR = 96001;
   1229         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1230         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
   1231 
   1232         // -------- initialization & test --------------
   1233         assertTrue(TEST_NAME, AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT) ==
   1234             AudioTrack.ERROR_BAD_VALUE);
   1235     }
   1236 
   1237     public void testAudioTrackProperties() throws Exception {
   1238         // constants for test
   1239         final String TEST_NAME = "testAudioTrackProperties";
   1240         final int TEST_SR = 22050;
   1241         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1242         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
   1243         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1244         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1245 
   1246         // -------- initialization --------------
   1247         int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1248         MockAudioTrack track = new MockAudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF,
   1249                 TEST_FORMAT, 2 * minBuffSize, TEST_MODE);
   1250         assertEquals(TEST_NAME, AudioTrack.STATE_INITIALIZED, track.getState());
   1251         assertEquals(TEST_NAME, TEST_FORMAT, track.getAudioFormat());
   1252         assertEquals(TEST_NAME, TEST_CONF, track.getChannelConfiguration());
   1253         assertEquals(TEST_NAME, TEST_SR, track.getSampleRate());
   1254         assertEquals(TEST_NAME, TEST_STREAM_TYPE, track.getStreamType());
   1255         final int hannelCount = 1;
   1256         assertEquals(hannelCount, track.getChannelCount());
   1257         final int notificationMarkerPosition = 0;
   1258         assertEquals(TEST_NAME, notificationMarkerPosition, track.getNotificationMarkerPosition());
   1259         final int markerInFrames = 2;
   1260         assertEquals(TEST_NAME, AudioTrack.SUCCESS,
   1261                 track.setNotificationMarkerPosition(markerInFrames));
   1262         assertEquals(TEST_NAME, markerInFrames, track.getNotificationMarkerPosition());
   1263         final int positionNotificationPeriod = 0;
   1264         assertEquals(TEST_NAME, positionNotificationPeriod, track.getPositionNotificationPeriod());
   1265         final int periodInFrames = 2;
   1266         assertEquals(TEST_NAME, AudioTrack.SUCCESS,
   1267                 track.setPositionNotificationPeriod(periodInFrames));
   1268         assertEquals(TEST_NAME, periodInFrames, track.getPositionNotificationPeriod());
   1269         track.setState(AudioTrack.STATE_NO_STATIC_DATA);
   1270         assertEquals(TEST_NAME, AudioTrack.STATE_NO_STATIC_DATA, track.getState());
   1271         track.setState(AudioTrack.STATE_UNINITIALIZED);
   1272         assertEquals(TEST_NAME, AudioTrack.STATE_UNINITIALIZED, track.getState());
   1273         int frameCount = 2 * minBuffSize;
   1274         if (TEST_CONF == AudioFormat.CHANNEL_CONFIGURATION_STEREO) {
   1275             frameCount /= 2;
   1276         }
   1277         if (TEST_FORMAT == AudioFormat.ENCODING_PCM_16BIT) {
   1278             frameCount /= 2;
   1279         }
   1280         assertTrue(TEST_NAME, track.getNativeFrameCount() >= frameCount);
   1281     }
   1282 
   1283     public void testReloadStaticData() throws Exception {
   1284         // constants for test
   1285         final String TEST_NAME = "testReloadStaticData";
   1286         final int TEST_SR = 22050;
   1287         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
   1288         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
   1289         final int TEST_MODE = AudioTrack.MODE_STATIC;
   1290         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1291 
   1292         // -------- initialization --------------
   1293         int bufferSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1294         byte data[] = createSoundDataInByteArray(bufferSize, TEST_SR, 1024);
   1295         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1296                 bufferSize, TEST_MODE);
   1297         // -------- test --------------
   1298         track.write(data, OFFSET_DEFAULT, bufferSize);
   1299         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1300         track.play();
   1301         Thread.sleep(WAIT_MSEC);
   1302         track.stop();
   1303         Thread.sleep(WAIT_MSEC);
   1304         assertEquals(TEST_NAME, AudioTrack.SUCCESS, track.reloadStaticData());
   1305         track.play();
   1306         Thread.sleep(WAIT_MSEC);
   1307         track.stop();
   1308         // -------- tear down --------------
   1309         track.release();
   1310     }
   1311 
   1312     public static byte[] createSoundDataInByteArray(int bufferSamples, final int sampleRate,
   1313             final double frequency, double sweep) {
   1314         final double rad = 2 * Math.PI * frequency / sampleRate;
   1315         byte[] vai = new byte[bufferSamples];
   1316         sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
   1317         for (int j = 0; j < vai.length; j++) {
   1318             int unsigned =  (int)(Math.sin(j * (rad + j * sweep)) * Byte.MAX_VALUE)
   1319                     + Byte.MAX_VALUE & 0xFF;
   1320             vai[j] = (byte) unsigned;
   1321         }
   1322         return vai;
   1323     }
   1324 
   1325     public static short[] createSoundDataInShortArray(int bufferSamples, final int sampleRate,
   1326             final double frequency, double sweep) {
   1327         final double rad = 2 * Math.PI * frequency / sampleRate;
   1328         short[] vai = new short[bufferSamples];
   1329         sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
   1330         for (int j = 0; j < vai.length; j++) {
   1331             vai[j] = (short)(Math.sin(j * (rad + j * sweep)) * Short.MAX_VALUE);
   1332         }
   1333         return vai;
   1334     }
   1335 
   1336     public static float[] createSoundDataInFloatArray(int bufferSamples, final int sampleRate,
   1337             final double frequency, double sweep) {
   1338         final double rad = 2 * Math.PI * frequency / sampleRate;
   1339         float[] vaf = new float[bufferSamples];
   1340         sweep = Math.PI * sweep / ((double)sampleRate * vaf.length);
   1341         for (int j = 0; j < vaf.length; j++) {
   1342             vaf[j] = (float)(Math.sin(j * (rad + j * sweep)));
   1343         }
   1344         return vaf;
   1345     }
   1346 
   1347     public static byte[] createSoundDataInByteArray(int bufferSamples, final int sampleRate,
   1348             final double frequency) {
   1349         return createSoundDataInByteArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
   1350     }
   1351 
   1352     public static short[] createSoundDataInShortArray(int bufferSamples, final int sampleRate,
   1353             final double frequency) {
   1354         return createSoundDataInShortArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
   1355     }
   1356 
   1357     public static float[] createSoundDataInFloatArray(int bufferSamples, final int sampleRate,
   1358             final double frequency) {
   1359         return createSoundDataInFloatArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
   1360     }
   1361 
   1362     public void testPlayStaticData() throws Exception {
   1363         // constants for test
   1364         final String TEST_NAME = "testPlayStaticData";
   1365         final int TEST_FORMAT_ARRAY[] = {  // 6 chirps repeated (TEST_LOOPS+1) times, 3 times
   1366                 AudioFormat.ENCODING_PCM_8BIT,
   1367                 AudioFormat.ENCODING_PCM_16BIT,
   1368                 AudioFormat.ENCODING_PCM_FLOAT,
   1369         };
   1370         final int TEST_SR_ARRAY[] = {
   1371                 12055, // Note multichannel tracks will sound very short at low sample rates
   1372                 48000,
   1373         };
   1374         final int TEST_CONF_ARRAY[] = {
   1375                 AudioFormat.CHANNEL_OUT_MONO,    // 1.0
   1376                 AudioFormat.CHANNEL_OUT_STEREO,  // 2.0
   1377                 AudioFormat.CHANNEL_OUT_7POINT1_SURROUND, // 7.1
   1378         };
   1379         final int TEST_MODE = AudioTrack.MODE_STATIC;
   1380         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1381         final double TEST_SWEEP = 100;
   1382         final int TEST_LOOPS = 1;
   1383 
   1384         for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
   1385             double frequency = 400; // frequency changes for each test
   1386             for (int TEST_SR : TEST_SR_ARRAY) {
   1387                 for (int TEST_CONF : TEST_CONF_ARRAY) {
   1388                     // -------- initialization --------------
   1389                     final int seconds = 1;
   1390                     final int channelCount = Integer.bitCount(TEST_CONF);
   1391                     final int bufferFrames = seconds * TEST_SR;
   1392                     final int bufferSamples = bufferFrames * channelCount;
   1393                     final int bufferSize = bufferSamples
   1394                             * AudioFormat.getBytesPerSample(TEST_FORMAT);
   1395                     final double testFrequency = frequency / channelCount;
   1396                     final long MILLISECONDS_PER_SECOND = 1000;
   1397                     AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR,
   1398                             TEST_CONF, TEST_FORMAT, bufferSize, TEST_MODE);
   1399                     assertEquals(TEST_NAME, track.getState(), AudioTrack.STATE_NO_STATIC_DATA);
   1400 
   1401                     // -------- test --------------
   1402 
   1403                     // test setLoopPoints and setPosition can be called here.
   1404                     assertEquals(TEST_NAME,
   1405                             track.setPlaybackHeadPosition(bufferFrames/2),
   1406                             android.media.AudioTrack.SUCCESS);
   1407                     assertEquals(TEST_NAME,
   1408                             track.setLoopPoints(
   1409                                     0 /*startInFrames*/, bufferFrames, 10 /*loopCount*/),
   1410                             android.media.AudioTrack.SUCCESS);
   1411                     // only need to write once to the static track
   1412                     switch (TEST_FORMAT) {
   1413                     case AudioFormat.ENCODING_PCM_8BIT: {
   1414                         byte data[] = createSoundDataInByteArray(
   1415                                 bufferSamples, TEST_SR,
   1416                                 testFrequency, TEST_SWEEP);
   1417                         assertEquals(TEST_NAME,
   1418                                 track.write(data, 0 /*offsetInBytes*/, data.length),
   1419                                 bufferSamples);
   1420                         } break;
   1421                     case AudioFormat.ENCODING_PCM_16BIT: {
   1422                         short data[] = createSoundDataInShortArray(
   1423                                 bufferSamples, TEST_SR,
   1424                                 testFrequency, TEST_SWEEP);
   1425                         assertEquals(TEST_NAME,
   1426                                 track.write(data, 0 /*offsetInBytes*/, data.length),
   1427                                 bufferSamples);
   1428                         } break;
   1429                     case AudioFormat.ENCODING_PCM_FLOAT: {
   1430                         float data[] = createSoundDataInFloatArray(
   1431                                 bufferSamples, TEST_SR,
   1432                                 testFrequency, TEST_SWEEP);
   1433                         assertEquals(TEST_NAME,
   1434                                 track.write(data, 0 /*offsetInBytes*/, data.length,
   1435                                         AudioTrack.WRITE_BLOCKING),
   1436                                 bufferSamples);
   1437                         } break;
   1438                     }
   1439                     assertEquals(TEST_NAME, track.getState(), AudioTrack.STATE_INITIALIZED);
   1440                     // test setLoopPoints and setPosition can be called here.
   1441                     assertEquals(TEST_NAME,
   1442                             track.setPlaybackHeadPosition(0 /*positionInFrames*/),
   1443                             android.media.AudioTrack.SUCCESS);
   1444                     assertEquals(TEST_NAME,
   1445                             track.setLoopPoints(0 /*startInFrames*/, bufferFrames, TEST_LOOPS),
   1446                             android.media.AudioTrack.SUCCESS);
   1447 
   1448                     track.play();
   1449                     Thread.sleep(seconds * MILLISECONDS_PER_SECOND * (TEST_LOOPS + 1));
   1450                     Thread.sleep(WAIT_MSEC);
   1451 
   1452                     // Check position after looping. AudioTrack.getPlaybackHeadPosition() returns
   1453                     // the running count of frames played, not the actual static buffer position.
   1454                     int position = track.getPlaybackHeadPosition();
   1455                     assertEquals(TEST_NAME, position, bufferFrames * (TEST_LOOPS + 1));
   1456 
   1457                     track.stop();
   1458                     Thread.sleep(WAIT_MSEC);
   1459                     // -------- tear down --------------
   1460                     track.release();
   1461                     frequency += 70; // increment test tone frequency
   1462                 }
   1463             }
   1464         }
   1465     }
   1466 
   1467     public void testPlayStreamData() throws Exception {
   1468         // constants for test
   1469         final String TEST_NAME = "testPlayStreamData";
   1470         final int TEST_FORMAT_ARRAY[] = {  // should hear 40 increasing frequency tones, 3 times
   1471                 AudioFormat.ENCODING_PCM_8BIT,
   1472                 AudioFormat.ENCODING_PCM_16BIT,
   1473                 AudioFormat.ENCODING_PCM_FLOAT,
   1474         };
   1475         final int TEST_SR_ARRAY[] = {
   1476                 4000,
   1477                 22050,
   1478                 44100,
   1479                 48000,
   1480                 96000,
   1481         };
   1482         final int TEST_CONF_ARRAY[] = {
   1483                 AudioFormat.CHANNEL_OUT_MONO,    // 1.0
   1484                 AudioFormat.CHANNEL_OUT_STEREO,  // 2.0
   1485                 AudioFormat.CHANNEL_OUT_STEREO | AudioFormat.CHANNEL_OUT_FRONT_CENTER, // 3.0
   1486                 AudioFormat.CHANNEL_OUT_QUAD,    // 4.0
   1487                 AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER,   // 5.0
   1488                 AudioFormat.CHANNEL_OUT_5POINT1, // 5.1
   1489                 AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER, // 6.1
   1490                 AudioFormat.CHANNEL_OUT_7POINT1_SURROUND, // 7.1
   1491         };
   1492         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1493         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1494 
   1495         for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
   1496             double frequency = 400; // frequency changes for each test
   1497             for (int TEST_SR : TEST_SR_ARRAY) {
   1498                 for (int TEST_CONF : TEST_CONF_ARRAY) {
   1499                     // -------- initialization --------------
   1500                     final int minBufferSize = AudioTrack.getMinBufferSize(TEST_SR,
   1501                             TEST_CONF, TEST_FORMAT); // in bytes
   1502                     final int bufferSamples = 12 * minBufferSize
   1503                             / AudioFormat.getBytesPerSample(TEST_FORMAT);
   1504                     final int channelCount = Integer.bitCount(TEST_CONF);
   1505                     final double testFrequency = frequency / channelCount;
   1506                     AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR,
   1507                             TEST_CONF, TEST_FORMAT, minBufferSize, TEST_MODE);
   1508                     assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1509                     boolean hasPlayed = false;
   1510                     int written = 0;
   1511 
   1512                     // -------- test --------------
   1513                     switch (TEST_FORMAT) {
   1514                     case AudioFormat.ENCODING_PCM_8BIT: {
   1515                         byte data[] = createSoundDataInByteArray(
   1516                                 bufferSamples, TEST_SR,
   1517                                 testFrequency);
   1518                         while (written < data.length) {
   1519                             int ret = track.write(data, written,
   1520                                     Math.min(data.length - written, minBufferSize));
   1521                             assertTrue(TEST_NAME, ret >= 0);
   1522                             written += ret;
   1523                             if (!hasPlayed) {
   1524                                 track.play();
   1525                                 hasPlayed = true;
   1526                             }
   1527                         }
   1528                         } break;
   1529                     case AudioFormat.ENCODING_PCM_16BIT: {
   1530                         short data[] = createSoundDataInShortArray(
   1531                                 bufferSamples, TEST_SR,
   1532                                 testFrequency);
   1533                         while (written < data.length) {
   1534                             int ret = track.write(data, written,
   1535                                     Math.min(data.length - written, minBufferSize));
   1536                             assertTrue(TEST_NAME, ret >= 0);
   1537                             written += ret;
   1538                             if (!hasPlayed) {
   1539                                 track.play();
   1540                                 hasPlayed = true;
   1541                             }
   1542                         }
   1543                         } break;
   1544                     case AudioFormat.ENCODING_PCM_FLOAT: {
   1545                         float data[] = createSoundDataInFloatArray(
   1546                                 bufferSamples, TEST_SR,
   1547                                 testFrequency);
   1548                         while (written < data.length) {
   1549                             int ret = track.write(data, written,
   1550                                     Math.min(data.length - written, minBufferSize),
   1551                                     AudioTrack.WRITE_BLOCKING);
   1552                             assertTrue(TEST_NAME, ret >= 0);
   1553                             written += ret;
   1554                             if (!hasPlayed) {
   1555                                 track.play();
   1556                                 hasPlayed = true;
   1557                             }
   1558                         }
   1559                         } break;
   1560                     }
   1561 
   1562                     Thread.sleep(WAIT_MSEC);
   1563                     track.stop();
   1564                     Thread.sleep(WAIT_MSEC);
   1565                     // -------- tear down --------------
   1566                     track.release();
   1567                     frequency += 70; // increment test tone frequency
   1568                 }
   1569             }
   1570         }
   1571     }
   1572 
   1573     public void testPlayStreamByteBuffer() throws Exception {
   1574         // constants for test
   1575         final String TEST_NAME = "testPlayStreamByteBuffer";
   1576         final int TEST_FORMAT_ARRAY[] = {  // should hear 4 tones played 3 times
   1577                 AudioFormat.ENCODING_PCM_8BIT,
   1578                 AudioFormat.ENCODING_PCM_16BIT,
   1579                 AudioFormat.ENCODING_PCM_FLOAT,
   1580         };
   1581         final int TEST_SR_ARRAY[] = {
   1582                 48000,
   1583         };
   1584         final int TEST_CONF_ARRAY[] = {
   1585                 AudioFormat.CHANNEL_OUT_STEREO,
   1586         };
   1587         final int TEST_WRITE_MODE_ARRAY[] = {
   1588                 AudioTrack.WRITE_BLOCKING,
   1589                 AudioTrack.WRITE_NON_BLOCKING,
   1590         };
   1591         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1592         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1593 
   1594         for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
   1595             double frequency = 800; // frequency changes for each test
   1596             for (int TEST_SR : TEST_SR_ARRAY) {
   1597                 for (int TEST_CONF : TEST_CONF_ARRAY) {
   1598                     for (int TEST_WRITE_MODE : TEST_WRITE_MODE_ARRAY) {
   1599                         for (int useDirect = 0; useDirect < 2; ++useDirect) {
   1600                             // -------- initialization --------------
   1601                             int minBufferSize = AudioTrack.getMinBufferSize(TEST_SR,
   1602                                     TEST_CONF, TEST_FORMAT); // in bytes
   1603                             int bufferSize = 12 * minBufferSize;
   1604                             int bufferSamples = bufferSize
   1605                                     / AudioFormat.getBytesPerSample(TEST_FORMAT);
   1606                             AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR,
   1607                                     TEST_CONF, TEST_FORMAT, minBufferSize, TEST_MODE);
   1608                             assertTrue(TEST_NAME,
   1609                                     track.getState() == AudioTrack.STATE_INITIALIZED);
   1610                             boolean hasPlayed = false;
   1611                             int written = 0;
   1612                             ByteBuffer bb = (useDirect == 1)
   1613                                     ? ByteBuffer.allocateDirect(bufferSize)
   1614                                             : ByteBuffer.allocate(bufferSize);
   1615                             bb.order(java.nio.ByteOrder.nativeOrder());
   1616 
   1617                             // -------- test --------------
   1618                             switch (TEST_FORMAT) {
   1619                                 case AudioFormat.ENCODING_PCM_8BIT: {
   1620                                     byte data[] = createSoundDataInByteArray(
   1621                                             bufferSamples, TEST_SR,
   1622                                             frequency);
   1623                                     bb.put(data);
   1624                                     bb.flip();
   1625                                 } break;
   1626                                 case AudioFormat.ENCODING_PCM_16BIT: {
   1627                                     short data[] = createSoundDataInShortArray(
   1628                                             bufferSamples, TEST_SR,
   1629                                             frequency);
   1630                                     ShortBuffer sb = bb.asShortBuffer();
   1631                                     sb.put(data);
   1632                                     bb.limit(sb.limit() * 2);
   1633                                 } break;
   1634                                 case AudioFormat.ENCODING_PCM_FLOAT: {
   1635                                     float data[] = createSoundDataInFloatArray(
   1636                                             bufferSamples, TEST_SR,
   1637                                             frequency);
   1638                                     FloatBuffer fb = bb.asFloatBuffer();
   1639                                     fb.put(data);
   1640                                     bb.limit(fb.limit() * 4);
   1641                                 } break;
   1642                             }
   1643 
   1644                             while (written < bufferSize) {
   1645                                 int ret = track.write(bb,
   1646                                         Math.min(bufferSize - written, minBufferSize),
   1647                                         TEST_WRITE_MODE);
   1648                                 assertTrue(TEST_NAME, ret >= 0);
   1649                                 written += ret;
   1650                                 if (!hasPlayed) {
   1651                                     track.play();
   1652                                     hasPlayed = true;
   1653                                 }
   1654                             }
   1655 
   1656                             Thread.sleep(WAIT_MSEC);
   1657                             track.stop();
   1658                             Thread.sleep(WAIT_MSEC);
   1659                             // -------- tear down --------------
   1660                             track.release();
   1661                             frequency += 200; // increment test tone frequency
   1662                         }
   1663                     }
   1664                 }
   1665             }
   1666         }
   1667     }
   1668 
   1669     private boolean hasAudioOutput() {
   1670         return getContext().getPackageManager()
   1671             .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
   1672     }
   1673 
   1674     public void testGetTimestamp() throws Exception {
   1675         if (!hasAudioOutput()) {
   1676             return;
   1677         }
   1678 
   1679         // constants for test
   1680         final String TEST_NAME = "testGetTimestamp";
   1681         final int TEST_SR = 22050;
   1682         final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO;
   1683         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
   1684         final int TEST_MODE = AudioTrack.MODE_STREAM;
   1685         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
   1686         final int TEST_LOOP_CNT = 10;
   1687         // For jitter we allow 30 msec in frames.  This is a large margin.
   1688         // Often this is just 0 or 1 frames, but that can depend on hardware.
   1689         final int TEST_JITTER_FRAMES_ALLOWED = TEST_SR * 30 / 1000;
   1690 
   1691         // -------- initialization --------------
   1692         final int bytesPerFrame =
   1693                 AudioFormat.getBytesPerSample(TEST_FORMAT)
   1694                 * AudioFormat.channelCountFromOutChannelMask(TEST_CONF);
   1695         final int minBufferSizeInBytes =
   1696                 AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
   1697         final int bufferSizeInBytes = minBufferSizeInBytes * 3;
   1698         byte[] data = new byte[bufferSizeInBytes];
   1699         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
   1700                 minBufferSizeInBytes, TEST_MODE);
   1701         // -------- test --------------
   1702         assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
   1703 
   1704         AudioTimestamp timestamp = new AudioTimestamp();
   1705         boolean hasPlayed = false;
   1706 
   1707         long framesWritten = 0, lastFramesPresented = 0, lastFramesPresentedAt = 0;
   1708         int cumulativeJitterCount = 0;
   1709         float cumulativeJitter = 0;
   1710         float maxJitter = 0;
   1711         for (int i = 0; i < TEST_LOOP_CNT; i++) {
   1712             final long writeTime = System.nanoTime();
   1713 
   1714             for (int written = 0; written < data.length;) {
   1715                 int ret = track.write(data, written,
   1716                         Math.min(data.length - written, minBufferSizeInBytes));
   1717                 assertTrue(TEST_NAME, ret >= 0);
   1718                 written += ret;
   1719                 if (!hasPlayed) {
   1720                     track.play();
   1721                     hasPlayed = true;
   1722                 }
   1723             }
   1724             framesWritten += data.length / bytesPerFrame;
   1725 
   1726             // track.getTimestamp may return false if there are no physical HAL outputs.
   1727             // This may occur on TV devices without connecting an HDMI monitor.
   1728             // It may also be true immediately after start-up, as the mixing thread could
   1729             // be idle, but since we've already pushed much more than the minimum buffer size,
   1730             // that is unlikely.
   1731             // Nevertheless, we don't want to have unnecessary failures, so we ignore the
   1732             // first iteration if we don't get a timestamp.
   1733             final boolean result = track.getTimestamp(timestamp);
   1734             assertTrue(TEST_NAME, result || i == 0);
   1735             if (!result) {
   1736                 continue;
   1737             }
   1738 
   1739             final long framesPresented = timestamp.framePosition;
   1740             final long framesPresentedAt = timestamp.nanoTime;
   1741 
   1742             // We read timestamp here to ensure that seen is greater than presented.
   1743             // This is an "on-the-fly" read without pausing because pausing may cause the
   1744             // timestamp to become stale and affect our jitter measurements.
   1745             final int framesSeen = track.getPlaybackHeadPosition();
   1746             assertTrue(TEST_NAME, framesWritten >= framesSeen);
   1747             assertTrue(TEST_NAME, framesSeen >= framesPresented);
   1748 
   1749             if (i > 1) { // need delta info from previous iteration (skipping first)
   1750                 final long deltaFrames = framesPresented - lastFramesPresented;
   1751                 final long deltaTime = framesPresentedAt - lastFramesPresentedAt;
   1752                 final long NANOSECONDS_PER_SECOND = 1000000000;
   1753                 final long expectedFrames = deltaTime * TEST_SR / NANOSECONDS_PER_SECOND;
   1754                 final long jitterFrames = Math.abs(deltaFrames - expectedFrames);
   1755 
   1756                 //Log.d(TAG, "framesWritten(" + framesWritten
   1757                 //        + ") framesSeen(" + framesSeen
   1758                 //        + ") framesPresented(" + framesPresented
   1759                 //        + ") jitter(" + jitterFrames + ")");
   1760 
   1761                 // We check that the timestamp position is reasonably accurate.
   1762                 assertTrue(TEST_NAME, deltaTime >= 0);
   1763                 assertTrue(TEST_NAME, deltaFrames >= 0);
   1764                 if (i > 2) {
   1765                     // The first two periods may have inherent jitter as the audio pipe
   1766                     // is filling up. We check jitter only after that.
   1767                     assertTrue(TEST_NAME, jitterFrames < TEST_JITTER_FRAMES_ALLOWED);
   1768                     cumulativeJitter += jitterFrames;
   1769                     cumulativeJitterCount++;
   1770                     if (jitterFrames > maxJitter) {
   1771                         maxJitter = jitterFrames;
   1772                     }
   1773                 }
   1774 
   1775                 //Log.d(TAG, "lastFramesPresentedAt(" + lastFramesPresentedAt
   1776                 //        + ") writeTime(" + writeTime
   1777                 //        + ") framesPresentedAt(" + framesPresentedAt + ")");
   1778 
   1779                 // We check that the timestamp time is reasonably current.
   1780                 assertTrue(TEST_NAME, framesPresentedAt >= writeTime);
   1781                 assertTrue(TEST_NAME, writeTime >= lastFramesPresentedAt);
   1782             }
   1783             lastFramesPresented = framesPresented;
   1784             lastFramesPresentedAt = framesPresentedAt;
   1785         }
   1786         // Full drain.
   1787         Thread.sleep(WAIT_MSEC);
   1788         track.stop();
   1789         Thread.sleep(WAIT_MSEC);
   1790         track.release();
   1791         // Log the average jitter
   1792         if (cumulativeJitterCount > 0) {
   1793             ReportLog log = getReportLog();
   1794             final float averageJitterInFrames = cumulativeJitter / cumulativeJitterCount;
   1795             final float averageJitterInMs = averageJitterInFrames * 1000 / TEST_SR;
   1796             final float maxJitterInMs = maxJitter * 1000 / TEST_SR;
   1797             // ReportLog needs at least one Value and Summary.
   1798             log.printValue("Maximum Jitter", maxJitterInMs,
   1799                     ResultType.LOWER_BETTER, ResultUnit.MS);
   1800             log.printSummary("Average Jitter", averageJitterInMs,
   1801                     ResultType.LOWER_BETTER, ResultUnit.MS);
   1802         }
   1803     }
   1804 
   1805 /* Do not run in JB-MR1. will be re-opened in the next platform release.
   1806     public void testResourceLeakage() throws Exception {
   1807         final int BUFFER_SIZE = 600 * 1024;
   1808         ByteBuffer data = ByteBuffer.allocate(BUFFER_SIZE);
   1809         for (int i = 0; i < 10; i++) {
   1810             Log.i(TAG, "testResourceLeakage round " + i);
   1811             data.rewind();
   1812             AudioTrack track = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
   1813                                               44100,
   1814                                               AudioFormat.CHANNEL_OUT_STEREO,
   1815                                               AudioFormat.ENCODING_PCM_16BIT,
   1816                                               data.capacity(),
   1817                                               AudioTrack.MODE_STREAM);
   1818             assertTrue(track != null);
   1819             track.write(data.array(), 0, data.capacity());
   1820             track.play();
   1821             Thread.sleep(100);
   1822             track.stop();
   1823             track.release();
   1824         }
   1825     }
   1826 */
   1827 
   1828     private class MockAudioTrack extends AudioTrack {
   1829 
   1830         public MockAudioTrack(int streamType, int sampleRateInHz, int channelConfig,
   1831                 int audioFormat, int bufferSizeInBytes, int mode) throws IllegalArgumentException {
   1832             super(streamType, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes, mode);
   1833         }
   1834 
   1835         public void setState(int state) {
   1836             super.setState(state);
   1837         }
   1838 
   1839         public int getNativeFrameCount() {
   1840             return super.getNativeFrameCount();
   1841         }
   1842     }
   1843 
   1844 }
   1845