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.media.R; 20 21 22 import android.content.Context; 23 import android.content.res.AssetFileDescriptor; 24 import android.media.AudioManager; 25 import android.media.SoundPool; 26 import android.test.AndroidTestCase; 27 28 import java.io.File; 29 import java.io.FileDescriptor; 30 import java.io.FileOutputStream; 31 import java.io.InputStream; 32 33 abstract class SoundPoolTest extends AndroidTestCase { 34 35 private static final int SOUNDPOOL_STREAMS = 4; 36 private static final int PRIORITY = 1; 37 private static final int LOUD = 20; 38 private static final int QUIET = LOUD / 2; 39 private static final int SILENT = 0; 40 private File mFile; 41 private SoundPool mSoundPool; 42 43 /** 44 * function to return resource ID for A4 sound. 45 * should be implemented by child class 46 * @return resource ID 47 */ 48 protected abstract int getSoundA(); 49 50 protected abstract int getSoundCs(); 51 52 protected abstract int getSoundE(); 53 54 protected abstract int getSoundB(); 55 56 protected abstract int getSoundGs(); 57 58 protected abstract String getFileName(); 59 60 private int[] getSounds() { 61 int[] sounds = { getSoundA(), 62 getSoundCs(), 63 getSoundE(), 64 getSoundB(), 65 getSoundGs() }; 66 return sounds; 67 } 68 69 @Override 70 protected void setUp() throws Exception { 71 super.setUp(); 72 mFile = new File(mContext.getFilesDir(), getFileName()); 73 } 74 75 @Override 76 protected void tearDown() throws Exception { 77 super.tearDown(); 78 if (mFile.exists()) { 79 mFile.delete(); 80 } 81 if (mSoundPool != null) { 82 mSoundPool.release(); 83 mSoundPool = null; 84 return; 85 } 86 } 87 88 public void testLoad() throws Exception { 89 int srcQuality = 100; 90 mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality); 91 int sampleId1 = mSoundPool.load(mContext, getSoundA(), PRIORITY); 92 waitUntilLoaded(sampleId1); 93 // should return true, but returns false 94 mSoundPool.unload(sampleId1); 95 96 AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(getSoundCs()); 97 int sampleId2; 98 sampleId2 = mSoundPool.load(afd, PRIORITY); 99 waitUntilLoaded(sampleId2); 100 mSoundPool.unload(sampleId2); 101 102 FileDescriptor fd = afd.getFileDescriptor(); 103 long offset = afd.getStartOffset(); 104 long length = afd.getLength(); 105 int sampleId3; 106 sampleId3 = mSoundPool.load(fd, offset, length, PRIORITY); 107 waitUntilLoaded(sampleId3); 108 mSoundPool.unload(sampleId3); 109 110 String path = mFile.getAbsolutePath(); 111 createSoundFile(mFile); 112 int sampleId4; 113 sampleId4 = mSoundPool.load(path, PRIORITY); 114 waitUntilLoaded(sampleId4); 115 mSoundPool.unload(sampleId4); 116 } 117 118 private void createSoundFile(File f) throws Exception { 119 FileOutputStream fOutput = null; 120 try { 121 fOutput = new FileOutputStream(f); 122 InputStream is = mContext.getResources().openRawResource(getSoundA()); 123 byte[] buffer = new byte[1024]; 124 int length = is.read(buffer); 125 while (length != -1) { 126 fOutput.write(buffer, 0, length); 127 length = is.read(buffer); 128 } 129 } finally { 130 if (fOutput != null) { 131 fOutput.flush(); 132 fOutput.close(); 133 } 134 } 135 } 136 137 public void testSoundPoolOp() throws Exception { 138 int srcQuality = 100; 139 mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality); 140 int sampleID = loadSampleSync(getSoundA(), PRIORITY); 141 142 int waitMsec = 1000; 143 float leftVolume = SILENT; 144 float rightVolume = LOUD; 145 int priority = 1; 146 int loop = 0; 147 float rate = 1f; 148 int streamID = mSoundPool.play(sampleID, leftVolume, rightVolume, priority, loop, rate); 149 assertTrue(streamID != 0); 150 Thread.sleep(waitMsec); 151 rate = 1.4f; 152 mSoundPool.setRate(streamID, rate); 153 Thread.sleep(waitMsec); 154 mSoundPool.setRate(streamID, 1f); 155 Thread.sleep(waitMsec); 156 mSoundPool.pause(streamID); 157 Thread.sleep(waitMsec); 158 mSoundPool.resume(streamID); 159 Thread.sleep(waitMsec); 160 mSoundPool.stop(streamID); 161 162 streamID = mSoundPool.play(sampleID, leftVolume, rightVolume, priority, loop, rate); 163 assertTrue(streamID != 0); 164 loop = -1;// loop forever 165 mSoundPool.setLoop(streamID, loop); 166 Thread.sleep(waitMsec); 167 leftVolume = SILENT; 168 rightVolume = SILENT; 169 mSoundPool.setVolume(streamID, leftVolume, rightVolume); 170 Thread.sleep(waitMsec); 171 rightVolume = LOUD; 172 mSoundPool.setVolume(streamID, leftVolume, rightVolume); 173 priority = 0; 174 mSoundPool.setPriority(streamID, priority); 175 Thread.sleep(waitMsec * 10); 176 mSoundPool.stop(streamID); 177 mSoundPool.unload(sampleID); 178 } 179 180 public void testMultiSound() throws Exception { 181 int srcQuality = 100; 182 mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality); 183 int sampleID1 = loadSampleSync(getSoundA(), PRIORITY); 184 int sampleID2 = loadSampleSync(getSoundCs(), PRIORITY); 185 long waitMsec = 1000; 186 Thread.sleep(waitMsec); 187 188 // play sounds one at a time 189 int streamID1 = mSoundPool.play(sampleID1, LOUD, QUIET, PRIORITY, -1, 1); 190 assertTrue(streamID1 != 0); 191 Thread.sleep(waitMsec * 4); 192 mSoundPool.stop(streamID1); 193 int streamID2 = mSoundPool.play(sampleID2, QUIET, LOUD, PRIORITY, -1, 1); 194 assertTrue(streamID2 != 0); 195 Thread.sleep(waitMsec * 4); 196 mSoundPool.stop(streamID2); 197 198 // play both at once repeating the first, but not the second 199 streamID1 = mSoundPool.play(sampleID1, LOUD, QUIET, PRIORITY, 1, 1); 200 streamID2 = mSoundPool.play(sampleID2, QUIET, LOUD, PRIORITY, 0, 1); 201 assertTrue(streamID1 != 0); 202 assertTrue(streamID2 != 0); 203 Thread.sleep(4000); 204 // both streams should have stopped by themselves; no way to check 205 206 mSoundPool.release(); 207 mSoundPool = null; 208 } 209 210 public void testLoadMore() throws Exception { 211 mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, 0); 212 int[] sounds = getSounds(); 213 int[] soundIds = new int[sounds.length]; 214 int[] streamIds = new int[sounds.length]; 215 for (int i = 0; i < sounds.length; i++) { 216 soundIds[i] = loadSampleSync(sounds[i], PRIORITY); 217 System.out.println("load: " + soundIds[i]); 218 } 219 for (int i = 0; i < soundIds.length; i++) { 220 streamIds[i] = mSoundPool.play(soundIds[i], LOUD, LOUD, PRIORITY, -1, 1); 221 } 222 Thread.sleep(3000); 223 for (int stream : streamIds) { 224 assertTrue(stream != 0); 225 mSoundPool.stop(stream); 226 } 227 for (int sound : soundIds) { 228 mSoundPool.unload(sound); 229 } 230 mSoundPool.release(); 231 } 232 233 /** 234 * Load a sample and wait until it is ready to be played. 235 * @return The sample ID. 236 * @throws InterruptedException 237 */ 238 private int loadSampleSync(int sampleId, int prio) throws InterruptedException { 239 int sample = mSoundPool.load(mContext, sampleId, prio); 240 waitUntilLoaded(sample); 241 return sample; 242 } 243 244 /** 245 * Wait until the specified sample is loaded. 246 * @param sampleId The sample ID. 247 * @throws InterruptedException 248 */ 249 private void waitUntilLoaded(int sampleId) throws InterruptedException { 250 int stream = 0; 251 while (stream == 0) { 252 Thread.sleep(500); 253 stream = mSoundPool.play(sampleId, SILENT, SILENT, 1, 0, 1); 254 } 255 mSoundPool.stop(stream); 256 } 257 } 258