Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.media.cts;
     18 
     19 import com.android.cts.stub.R;
     20 
     21 import dalvik.annotation.TestLevel;
     22 import dalvik.annotation.TestTargetClass;
     23 import dalvik.annotation.TestTargetNew;
     24 import dalvik.annotation.TestTargets;
     25 import dalvik.annotation.ToBeFixed;
     26 
     27 import android.content.Context;
     28 import android.content.res.AssetFileDescriptor;
     29 import android.media.AudioManager;
     30 import android.media.SoundPool;
     31 import android.test.AndroidTestCase;
     32 
     33 import java.io.File;
     34 import java.io.FileDescriptor;
     35 import java.io.FileOutputStream;
     36 import java.io.InputStream;
     37 
     38 @TestTargetClass(SoundPool.class)
     39 public class SoundPoolTest extends AndroidTestCase {
     40 
     41     private static final int SOUNDPOOL_STREAMS = 4;
     42     private static final int SOUND_A = R.raw.a_4;
     43     private static final int SOUND_CS = R.raw.c_sharp_5;
     44     private static final int SOUND_E = R.raw.e_5;
     45     private static final int SOUND_B = R.raw.b_5;
     46     private static final int SOUND_GS = R.raw.g_sharp_5;
     47     private static final int PRIORITY = 1;
     48     private static final int LOUD = 20;
     49     private static final int QUIET = LOUD / 2;
     50     private static final int SILENT = 0;
     51 
     52     private static final int[] SOUNDS = { SOUND_A, SOUND_CS, SOUND_E, SOUND_B, SOUND_GS };
     53 
     54     private static final String FILE_NAME = "a_4.ogg";
     55     private File mFile;
     56     private SoundPool mSoundPool;
     57 
     58     @Override
     59     protected void setUp() throws Exception {
     60         super.setUp();
     61         mFile = new File(mContext.getFilesDir(), FILE_NAME);
     62     }
     63 
     64     @Override
     65     protected void tearDown() throws Exception {
     66         super.tearDown();
     67         if (mFile.exists()) {
     68             mFile.delete();
     69         }
     70         if (mSoundPool != null) {
     71             mSoundPool.release();
     72             mSoundPool = null;
     73             return;
     74         }
     75     }
     76 
     77     @TestTargets({
     78         @TestTargetNew(
     79             level = TestLevel.COMPLETE,
     80             method = "load",
     81             args = {AssetFileDescriptor.class, int.class}
     82         ),
     83         @TestTargetNew(
     84             level = TestLevel.COMPLETE,
     85             method = "load",
     86             args = {Context.class, int.class, int.class}
     87         ),
     88         @TestTargetNew(
     89             level = TestLevel.COMPLETE,
     90             method = "load",
     91             args = {FileDescriptor.class, long.class, long.class, int.class}
     92         ),
     93         @TestTargetNew(
     94             level = TestLevel.COMPLETE,
     95             method = "load",
     96             args = {String.class, int.class}
     97         ),
     98         @TestTargetNew(
     99             level = TestLevel.SUFFICIENT,
    100             method = "unload",
    101             args = {int.class}
    102         ),
    103         @TestTargetNew(
    104             level = TestLevel.COMPLETE,
    105             method = "release",
    106             args = {}
    107         )
    108     })
    109     @ToBeFixed(explanation = "unload() does not return true as specified")
    110     public void testLoad() throws Exception {
    111         int srcQuality = 100;
    112         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality);
    113         int sampleId1 = mSoundPool.load(mContext, SOUND_A, PRIORITY);
    114         waitUntilLoaded(sampleId1);
    115         // should return true, but returns false
    116         mSoundPool.unload(sampleId1);
    117 
    118         AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(SOUND_CS);
    119         int sampleId2;
    120         sampleId2 = mSoundPool.load(afd, PRIORITY);
    121         waitUntilLoaded(sampleId2);
    122         mSoundPool.unload(sampleId2);
    123 
    124         FileDescriptor fd = afd.getFileDescriptor();
    125         long offset = afd.getStartOffset();
    126         long length = afd.getLength();
    127         int sampleId3;
    128         sampleId3 = mSoundPool.load(fd, offset, length, PRIORITY);
    129         waitUntilLoaded(sampleId3);
    130         mSoundPool.unload(sampleId3);
    131 
    132         String path = mFile.getAbsolutePath();
    133         createSoundFile(mFile);
    134         int sampleId4;
    135         sampleId4 = mSoundPool.load(path, PRIORITY);
    136         waitUntilLoaded(sampleId4);
    137         mSoundPool.unload(sampleId4);
    138     }
    139 
    140     private void createSoundFile(File f) throws Exception {
    141         FileOutputStream fOutput = null;
    142         try {
    143             fOutput = new FileOutputStream(f);
    144             InputStream is = mContext.getResources().openRawResource(SOUND_A);
    145             byte[] buffer = new byte[1024];
    146             int length = is.read(buffer);
    147             while (length != -1) {
    148                 fOutput.write(buffer, 0, length);
    149                 length = is.read(buffer);
    150             }
    151         } finally {
    152             if (fOutput != null) {
    153                 fOutput.flush();
    154                 fOutput.close();
    155             }
    156         }
    157     }
    158 
    159     @TestTargets({
    160         @TestTargetNew(
    161             level = TestLevel.COMPLETE,
    162             method = "load",
    163             args = {Context.class, int.class, int.class}
    164         ),
    165         @TestTargetNew(
    166             level = TestLevel.COMPLETE,
    167             method = "pause",
    168             args = {int.class}
    169         ),
    170         @TestTargetNew(
    171             level = TestLevel.COMPLETE,
    172             method = "play",
    173             args = {int.class, float.class, float.class, int.class, int.class, float.class}
    174         ),
    175         @TestTargetNew(
    176             level = TestLevel.COMPLETE,
    177             method = "resume",
    178             args = {int.class}
    179         ),
    180         @TestTargetNew(
    181             level = TestLevel.COMPLETE,
    182             method = "setLoop",
    183             args = {int.class, int.class}
    184         ),
    185         @TestTargetNew(
    186             level = TestLevel.COMPLETE,
    187             method = "setPriority",
    188             args = {int.class, int.class}
    189         ),
    190         @TestTargetNew(
    191             level = TestLevel.COMPLETE,
    192             method = "setRate",
    193             args = {int.class, float.class}
    194         ),
    195         @TestTargetNew(
    196             level = TestLevel.COMPLETE,
    197             method = "setVolume",
    198             args = {int.class, float.class, float.class}
    199         ),
    200         @TestTargetNew(
    201             level = TestLevel.COMPLETE,
    202             method = "SoundPool",
    203             args = {int.class, int.class, int.class}
    204         ),
    205         @TestTargetNew(
    206             level = TestLevel.COMPLETE,
    207             method = "stop",
    208             args = {int.class}
    209         )
    210     })
    211     public void testSoundPoolOp() throws Exception {
    212         int srcQuality = 100;
    213         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality);
    214         int sampleID = loadSampleSync(SOUND_A, PRIORITY);
    215 
    216         int waitMsec = 1000;
    217         float leftVolume = SILENT;
    218         float rightVolume = LOUD;
    219         int priority = 1;
    220         int loop = 0;
    221         float rate = 1f;
    222         int streamID = mSoundPool.play(sampleID, leftVolume, rightVolume, priority, loop, rate);
    223         assertTrue(streamID != 0);
    224         Thread.sleep(waitMsec);
    225         rate = 1.4f;
    226         mSoundPool.setRate(streamID, rate);
    227         Thread.sleep(waitMsec);
    228         mSoundPool.setRate(streamID, 1f);
    229         Thread.sleep(waitMsec);
    230         mSoundPool.pause(streamID);
    231         Thread.sleep(waitMsec);
    232         mSoundPool.resume(streamID);
    233         Thread.sleep(waitMsec);
    234         mSoundPool.stop(streamID);
    235 
    236         streamID = mSoundPool.play(sampleID, leftVolume, rightVolume, priority, loop, rate);
    237         assertTrue(streamID != 0);
    238         loop = -1;// loop forever
    239         mSoundPool.setLoop(streamID, loop);
    240         Thread.sleep(waitMsec);
    241         leftVolume = SILENT;
    242         rightVolume = SILENT;
    243         mSoundPool.setVolume(streamID, leftVolume, rightVolume);
    244         Thread.sleep(waitMsec);
    245         rightVolume = LOUD;
    246         mSoundPool.setVolume(streamID, leftVolume, rightVolume);
    247         priority = 0;
    248         mSoundPool.setPriority(streamID, priority);
    249         Thread.sleep(waitMsec * 10);
    250         mSoundPool.stop(streamID);
    251         mSoundPool.unload(sampleID);
    252     }
    253 
    254     @TestTargets({
    255         @TestTargetNew(
    256             level = TestLevel.COMPLETE,
    257             method = "load",
    258             args = {Context.class, int.class, int.class}
    259         ),
    260         @TestTargetNew(
    261             level = TestLevel.COMPLETE,
    262             method = "play",
    263             args = {int.class, float.class, float.class, int.class, int.class, float.class}
    264         ),
    265         @TestTargetNew(
    266             level = TestLevel.COMPLETE,
    267             method = "SoundPool",
    268             args = {int.class, int.class, int.class}
    269         ),
    270         @TestTargetNew(
    271             level = TestLevel.COMPLETE,
    272             method = "stop",
    273             args = {int.class}
    274         )
    275     })
    276     public void testMultiSound() throws Exception {
    277         int srcQuality = 100;
    278         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality);
    279         int sampleID1 = loadSampleSync(SOUND_A, PRIORITY);
    280         int sampleID2 = loadSampleSync(SOUND_CS, PRIORITY);
    281         long waitMsec = 1000;
    282         Thread.sleep(waitMsec);
    283 
    284         // play sounds one at a time
    285         int streamID1 = mSoundPool.play(sampleID1, LOUD, QUIET, PRIORITY, -1, 1);
    286         assertTrue(streamID1 != 0);
    287         Thread.sleep(waitMsec * 4);
    288         mSoundPool.stop(streamID1);
    289         int streamID2 = mSoundPool.play(sampleID2, QUIET, LOUD, PRIORITY, -1, 1);
    290         assertTrue(streamID2 != 0);
    291         Thread.sleep(waitMsec * 4);
    292         mSoundPool.stop(streamID2);
    293 
    294         // play both at once repeating the first, but not the second
    295         streamID1 = mSoundPool.play(sampleID1, LOUD, QUIET, PRIORITY, 1, 1);
    296         streamID2 = mSoundPool.play(sampleID2, QUIET, LOUD, PRIORITY, 0, 1);
    297         assertTrue(streamID1 != 0);
    298         assertTrue(streamID2 != 0);
    299         Thread.sleep(4000);
    300         // both streams should have stopped by themselves; no way to check
    301 
    302         mSoundPool.release();
    303         mSoundPool = null;
    304     }
    305 
    306     @TestTargets({
    307         @TestTargetNew(
    308             level = TestLevel.COMPLETE,
    309             method = "load",
    310             args = {Context.class, int.class, int.class}
    311         ),
    312         @TestTargetNew(
    313             level = TestLevel.COMPLETE,
    314             method = "SoundPool",
    315             args = {int.class, int.class, int.class}
    316         )
    317     })
    318     public void testLoadMore() throws Exception {
    319         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, 0);
    320         int[] soundIds = new int[SOUNDS.length];
    321         int[] streamIds = new int[SOUNDS.length];
    322         for (int i = 0; i < SOUNDS.length; i++) {
    323             soundIds[i] = loadSampleSync(SOUNDS[i], PRIORITY);
    324             System.out.println("load: " + soundIds[i]);
    325         }
    326         for (int i = 0; i < soundIds.length; i++) {
    327             streamIds[i] = mSoundPool.play(soundIds[i], LOUD, LOUD, PRIORITY, -1, 1);
    328         }
    329         Thread.sleep(3000);
    330         for (int stream : streamIds) {
    331             assertTrue(stream != 0);
    332             mSoundPool.stop(stream);
    333         }
    334         for (int sound : soundIds) {
    335             mSoundPool.unload(sound);
    336         }
    337         mSoundPool.release();
    338     }
    339 
    340     /**
    341      * Load a sample and wait until it is ready to be played.
    342      * @return The sample ID.
    343      * @throws InterruptedException
    344      */
    345     private int loadSampleSync(int sampleId, int prio) throws InterruptedException {
    346         int sample = mSoundPool.load(mContext, sampleId, prio);
    347         waitUntilLoaded(sample);
    348         return sample;
    349     }
    350 
    351     /**
    352      * Wait until the specified sample is loaded.
    353      * @param sampleId The sample ID.
    354      * @throws InterruptedException
    355      */
    356     private void waitUntilLoaded(int sampleId) throws InterruptedException {
    357         int stream = 0;
    358         while (stream == 0) {
    359             Thread.sleep(500);
    360             stream = mSoundPool.play(sampleId, SILENT, SILENT, 1, 0, 1);
    361         }
    362         mSoundPool.stop(stream);
    363     }
    364 }
    365