1# Using SoundPool for Audio Playback (ArkTS) 2 3The **SoundPool** class provides APIs to implement low-latency playback of short sounds. 4 5Short sound effects (such as the camera shutter sound effect and system notification sound effect) are often required during application development. You can call the APIs provided by **SoundPool** to implement one-time loading of short sounds and multiple times of low-latency playback. 6 7Currently, the **SoundPool** APIs can be used to play an audio file that is less than 1 MB. If the size of an audio file exceeds 1 MB, 1 MB data is captured and played. 8 9This topic walks you through on how to use the **SoundPool** APIs to implement low-latency playback. For details about the API, see [SoundPool](../reference/apis-media-kit/js-apis-inner-multimedia-soundPool.md). 10 11The full process includes creating a **SoundPool** instance, loading a sound (including decapsulation and decoding), setting playback parameters (loop mode, and playback priority), playing the sound, stopping the playback, and releasing the instance. (For details about the decoding formats, see [Audio Decoding](audio-decoding.md).) 12 13During application development, you must subscribe to playback state changes and call the APIs in the defined sequence. Otherwise, an exception or undefined behavior may occur. 14 15## How to Develop 16 171. Call **createSoundPool()** to create a **SoundPool** instance. 18 19 ```ts 20 import media from '@ohos.multimedia.media'; 21 import audio from '@ohos.multimedia.audio'; 22 import { BusinessError } from '@ohos.base'; 23 24 let soundPool: media.SoundPool; 25 let audioRendererInfo: audio.AudioRendererInfo = { 26 usage : audio.StreamUsage.STREAM_USAGE_MUSIC, 27 rendererFlags : 0 28 } 29 30 media.createSoundPool(5, audioRendererInfo).then((soundpool_: media.SoundPool) => { 31 if (soundpool_ != null) { 32 soundPool = soundpool_; 33 console.info('create SoundPool success'); 34 } else { 35 console.error('create SoundPool fail'); 36 } 37 }).catch((error: BusinessError) => { 38 console.error(`soundpool catchCallback, error message:${error.message}`); 39 }); 40 ``` 41 422. Call **load()** to load a sound. 43 You can pass in a URI or an FD to load the sound. The following uses the URI as an example. For more methods, see [SoundPool](../reference/apis-media-kit/js-apis-inner-multimedia-soundPool.md#load). 44 45 ```ts 46 import { BusinessError } from '@ohos.base'; 47 import fs from '@ohos.file.fs'; 48 49 let soundID: number; 50 let uri: string; 51 async function load() { 52 await fs.open('/test_01.mp3', fs.OpenMode.READ_ONLY).then((file: fs.File) => { 53 console.info("file fd: " + file.fd); 54 uri = 'fd://' + (file.fd).toString() 55 }); // '/test_01.mp3' here is only an example. You need to pass in the actual URI. 56 soundPool.load(uri).then((soundId: number) => { 57 console.info('soundPool load uri success'); 58 soundID = soundId; 59 }).catch((err: BusinessError) => { 60 console.error('soundPool load failed and catch error is ' + err.message); 61 }) 62 } 63 ``` 64 653. Call **on('loadComplete')** to listen for the completion of sound loading. 66 67 ```ts 68 soundPool.on('loadComplete', (soundId: number) => { 69 console.info('loadComplete, soundId: ' + soundId); 70 }); 71 ``` 72 734. Call **on('playFinished')** to listen for the completion of sound playing. 74 75 ```ts 76 soundPool.on('playFinished', () => { 77 console.info("receive play finished message"); 78 }); 79 ``` 80 815. Call **on('error')** to listen for errors that may occur. 82 83 ```ts 84 soundPool.on('error', (error) => { 85 console.info('error happened,message is :' + error.message); 86 }); 87 ``` 88 896. Set the playback parameters and call **play()** to play the sound. If **play()** with the same sound ID passed in is called for multiple times, the sound is played only once. 90 91 ```ts 92 let soundID: number; 93 let streamID: number; 94 let playParameters: media.PlayParameters = { 95 loop: 0, // The sound does not loop. It is played once. 96 rate: 2, // The sound is played at twice its original frequency. 97 leftVolume: 0.5, // range = 0.0-1.0 98 rightVolume: 0.5, // range = 0.0-1.0 99 priority: 0, // The sound playback has the lowest priority. 100 } 101 soundPool.play(soundID, playParameters, (error, streamId: number) => { 102 if (error) { 103 console.info(`play sound Error: errCode is ${error.code}, errMessage is ${error.message}`) 104 } else { 105 streamID = streamId; 106 console.info('play success soundid:' + streamId); 107 } 108 }); 109 ``` 110 1117. Call **setLoop()** to set the number of loops. 112 113 ```ts 114 import { BusinessError } from '@ohos.base'; 115 116 let streamID: number; 117 soundPool.setLoop(streamID, 1).then(() => { 118 console.info('setLoop success streamID:' + streamID); 119 }).catch((err: BusinessError) => { 120 console.error('soundpool setLoop failed and catch error is ' + err.message); 121 }); 122 ``` 123 1248. Call **setPriority()** to set the playback priority. 125 126 ```ts 127 let streamID: number; 128 soundPool.setPriority(streamID, 1); 129 ``` 130 1319. Call **setVolume()** to set the playback volume. 132 133 ```ts 134 import { BusinessError } from '@ohos.base'; 135 136 let streamID: number; 137 // Call play() to obtain the stream ID. 138 139 soundPool.setVolume(streamID, 0.5, 0.5).then(() => { 140 console.info('setVolume success'); 141 }).catch((err: BusinessError) => { 142 console.error('soundpool setVolume failed and catch error is ' + err.message); 143 }); 144 ``` 145 14610. Call **stop()** to stop the playback. 147 148 ```ts 149 import { BusinessError } from '@ohos.base'; 150 151 let streamID: number; 152 // Call play() to obtain the stream ID. 153 154 soundPool.stop(streamID).then(() => { 155 console.info('stop success'); 156 }).catch((err: BusinessError) => { 157 console.error('soundpool load stop and catch error is ' + err.message); 158 }); 159 ``` 160 16111. Call **unload()** to unload a sound. 162 163 ```ts 164 import { BusinessError } from '@ohos.base'; 165 166 let soundID: number; 167 // Call load() to obtain the sound ID. 168 169 soundPool.unload(soundID).then(() => { 170 console.info('unload success'); 171 }).catch((err: BusinessError) => { 172 console.error('soundpool unload failed and catch error is ' + err.message); 173 }); 174 ``` 175 17612. Call **off('loadComplete')** to stop listening for the completion of sound loading. 177 178 ```ts 179 soundPool.off('loadComplete'); 180 ``` 181 18213. Call **off('playFinished')** to stop listening for the completion of sound playing. 183 184 ```ts 185 soundPool.off('playFinished'); 186 ``` 187 18814. Call **off('error')** to stop listening for errors. 189 190 ```ts 191 soundPool.off('error'); 192 ``` 193 19415. Call **release()** to release the **SoundPool** instance. 195 196 ```ts 197 import { BusinessError } from '@ohos.base'; 198 199 soundPool.release().then(() => { 200 console.info('release success'); 201 }).catch((err: BusinessError) => { 202 console.error('soundpool release failed and catch error is ' + err.message); 203 }); 204 ``` 205 206## Sample Code 207 208The following sample code implements low-latency playback using **SoundPool**. 209 210```ts 211import audio from '@ohos.multimedia.audio'; 212import media from '@ohos.multimedia.media'; 213import fs from '@ohos.file.fs' 214 215let soundPool: media.SoundPool; 216let streamId: number = 0; 217let soundId: number = 0; 218let audioRendererInfo: audio.AudioRendererInfo = { 219 usage: audio.StreamUsage.STREAM_USAGE_MUSIC, 220 rendererFlags: 1 221} 222let PlayParameters: media.PlayParameters = { 223 loop: 3, // The sound is played four times (three loops). 224 rate: audio.AudioRendererRate.RENDER_RATE_NORMAL, // The sound is played at the original frequency. 225 leftVolume: 0.5, // range = 0.0-1.0 226 rightVolume: 0.5, // range = 0.0-1.0 227 priority: 0, // The sound playback has the lowest priority. 228} 229let uri: string = ""; 230async function create() { 231 // Create a SoundPool instance. 232 soundPool = await media.createSoundPool(5, audioRendererInfo); 233 // Register listeners. 234 loadCallback(); 235 finishPlayCallback(); 236 setErrorCallback(); 237 // Load a sound. 238 await fs.open('/test_01.mp3', fs.OpenMode.READ_ONLY).then((file: fs.File) => { 239 console.info("file fd: " + file.fd); 240 uri = 'fd://' + (file.fd).toString() 241 }); // '/test_01.mp3' here is only an example. You need to pass in the actual URI. 242 soundId = await soundPool.load(uri); 243} 244async function loadCallback() { 245 // Callback invoked when the sound finishes loading. 246 soundPool.on('loadComplete', (soundId_: number) => { 247 console.info('loadComplete, soundId: ' + soundId_); 248 }) 249} 250// Set the listener when the sound finishes playing. 251async function finishPlayCallback() { 252 // Callback invoked when the sound finishes playing. 253 soundPool.on('playFinished', () => { 254 console.info("recive play finished message"); 255 // The sound can be played again. 256 }) 257} 258// Set the listener for errors. 259function setErrorCallback() { 260 soundPool.on('error', (error) => { 261 console.info('error happened,message is :' + error.message); 262 }) 263} 264async function PlaySoundPool() { 265 // Start playback. PlayParameters can be carried in the play() API. 266 streamId = await soundPool.play(soundId); 267 // Set the number of loops. 268 soundPool.setLoop (streamId, 2); // The sound is played three times (two loops). 269 // Set the priority. 270 soundPool.setPriority(streamId, 1); 271 // Set the volume. 272 soundPool.setVolume(streamId, 0.5, 0.5); 273} 274async function release() { 275 // Stop the playback of the stream. 276 soundPool.stop(streamId); 277 // Unload the sound. 278 await soundPool.unload(soundId); 279 // Unregister the listeners. 280 setOffCallback(); 281 // Release the SoundPool instance. 282 await soundPool.release(); 283} 284// Unregister the listeners. 285function setOffCallback() { 286 soundPool.off('loadComplete'); 287 soundPool.off('playFinished'); 288 soundPool.off('error'); 289} 290``` 291