1e41f4b71Sopenharmony_ci# Using OpenSL ES for Audio Playback (C/C++) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciOpenSL ES, short for Open Sound Library for Embedded Systems, is an embedded, cross-platform audio processing library that is free of charge. It provides high-performance and low-latency APIs for you to develop applications running on embedded mobile multimedia devices. OpenHarmony has implemented certain native APIs based on [OpenSL ES](https://www.khronos.org/opensles/) 1.0.1 API specifications developed by the [Khronos Group](https://www.khronos.org/). You can use these APIs through <OpenSLES.h\> and <OpenSLES_OpenHarmony.h\>. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## Using OHAudio to Replace OpenSL ES 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciOpenHarmony provides the OpenSL ES APIs for audio development at the native layer since SDK8. As the version evolves, these APIs fail to meet the capability expansion requirements of the audio system and therefore are no longer recommended. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciIn SDK 10, OpenHarmony provides the **OHAudio** APIs, which open up all audio functions of the system. The **OHAudio** APIs cover all the capabilities provided by OpenSL ES in OpenHarmony. They also support new features such as audio focus events and low latency. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ciFor details about how to use the **OHAudio** APIs for audio development, see [Using OHAudio for Audio Playback (C/C++)](using-ohaudio-for-playback.md). 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ciIf you have used the OpenSL ES APIs in your code, you can switch them to the **OHAudio** APIs. For details, see [Switching from OpenSL ES to OHAudio (C/C++)](replace-opensles-by-ohaudio.md). 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci## OpenSL ES on OpenHarmony 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ciCurrently, OpenHarmony implements parts of [OpenSL ES APIs](https://gitee.com/openharmony/third_party_opensles/blob/master/api/1.0.1/OpenSLES.h) to implement basic audio playback functionalities. 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ciIf an API that has not been implemented on OpenHarmony is called, **SL_RESULT_FEATURE_UNSUPPORTED** is returned. 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ciThe following lists the OpenSL ES APIs that have been implemented on OpenHarmony. For details, see the [OpenSL ES](https://www.khronos.org/opensles/) specifications. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci- **SLInterfaceID implemented on OpenHarmony** 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci | SLInterfaceID | Description | 26e41f4b71Sopenharmony_ci | -------- | -------- | 27e41f4b71Sopenharmony_ci | SL_IID_ENGINE | Universal engine, which provides the interface for creating player objects. | 28e41f4b71Sopenharmony_ci | SL_IID_PLAY | Provides the player status interface. | 29e41f4b71Sopenharmony_ci | SL_IID_VOLUME | Provides interfaces for adjusting and reading the volume of audio playback streams. | 30e41f4b71Sopenharmony_ci | SL_IID_OH_BUFFERQUEUE | Provides the callback registration interface for audio playback stream data. | 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci- **Engine APIs implemented on OpenHarmony** 33e41f4b71Sopenharmony_ci - SLresult (\*CreateAudioPlayer) (SLEngineItf self, SLObjectItf \* pPlayer, SLDataSource \*pAudioSrc, SLDataSink \*pAudioSnk, SLuint32 numInterfaces, const SLInterfaceID \* pInterfaceIds, const SLboolean \* pInterfaceRequired) 34e41f4b71Sopenharmony_ci - SLresult (\*CreateAudioRecorder) (SLEngineItf self, SLObjectItf \* pRecorder, SLDataSource \*pAudioSrc, SLDataSink \*pAudioSnk, SLuint32 numInterfaces, const SLInterfaceID \* pInterfaceIds, const SLboolean \* pInterfaceRequired) 35e41f4b71Sopenharmony_ci - SLresult (\*CreateOutputMix) (SLEngineItf self, SLObjectItf \* pMix, SLuint32 numInterfaces, const SLInterfaceID \* pInterfaceIds, const SLboolean \* pInterfaceRequired) 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci- **Object APIs implemented on OpenHarmony** 38e41f4b71Sopenharmony_ci - SLresult (\*Realize) (SLObjectItf self, SLboolean async) 39e41f4b71Sopenharmony_ci - SLresult (\*GetState) (SLObjectItf self, SLuint32 \* pState) 40e41f4b71Sopenharmony_ci - SLresult (\*GetInterface) (SLObjectItf self, const SLInterfaceID iid, void \* pInterface) 41e41f4b71Sopenharmony_ci - void (\*Destroy) (SLObjectItf self) 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci- **Playback APIs implemented on OpenHarmony** 44e41f4b71Sopenharmony_ci - SLresult (\*SetPlayState) (SLPlayItf self, SLuint32 state) 45e41f4b71Sopenharmony_ci - SLresult (\*GetPlayState) (SLPlayItf self, SLuint32 \*pState) 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci- **Volume control APIs implemented on OpenHarmony** 48e41f4b71Sopenharmony_ci - SLresult (\*SetVolumeLevel) (SLVolumeItf self, SLmillibel level) 49e41f4b71Sopenharmony_ci - SLresult (\*GetVolumeLevel) (SLVolumeItf self, SLmillibel \*pLevel) 50e41f4b71Sopenharmony_ci - SLresult (\*GetMaxVolumeLevel) (SLVolumeItf self, SLmillibel \*pMaxLevel) 51e41f4b71Sopenharmony_ci 52e41f4b71Sopenharmony_ci- **BufferQueue APIs implemented on OpenHarmony** 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci The APIs listed below can be used only after <OpenSLES_OpenHarmony.h\> is introduced. 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci | API | Description | 57e41f4b71Sopenharmony_ci | -------- | -------- | 58e41f4b71Sopenharmony_ci | SLresult (\*Enqueue) (SLOHBufferQueueItf self, const void \*buffer, SLuint32 size) | Adds a buffer to the corresponding queue.<br>For an audio playback operation, this API adds the buffer with audio data to the **filledBufferQ_** queue. For an audio recording operation, this API adds the idle buffer after recording data storage to the **freeBufferQ_** queue.<br>The **self** parameter indicates the **BufferQueue** object that calls this API.<br>The **buffer** parameter indicates the pointer to the buffer with audio data or the pointer to the idle buffer after the recording data is stored.<br>The **size** parameter indicates the size of the buffer. | 59e41f4b71Sopenharmony_ci | SLresult (\*Clear) (SLOHBufferQueueItf self) | Releases a **BufferQueue** object.<br>The **self** parameter indicates the **BufferQueue** object that calls this API. | 60e41f4b71Sopenharmony_ci | SLresult (\*GetState) (SLOHBufferQueueItf self, SLOHBufferQueueState \*state) | Obtains the state of a **BufferQueue** object.<br>The **self** parameter indicates the **BufferQueue** object that calls this API.<br>The **state** parameter indicates the pointer to the state of the **BufferQueue** object. | 61e41f4b71Sopenharmony_ci | SLresult (\*RegisterCallback) (SLOHBufferQueueItf self, SlOHBufferQueueCallback callback, void\* pContext) | Registers a callback.<br>The **self** parameter indicates the **BufferQueue** object that calls this API.<br>The **callback** parameter indicates the callback to be registered for the audio playback or recording operation.<br>The **pContext** parameter indicates the pointer to the audio file to be played for an audio playback operation or the pointer to the audio file to be recorded for an audio recording operation. | 62e41f4b71Sopenharmony_ci | SLresult (\*GetBuffer) (SLOHBufferQueueItf self, SLuint8\*\* buffer, SLuint32\* size) | Obtains a buffer.<br>For an audio playback operation, this API obtains an idle buffer from the **freeBufferQ_** queue. For an audio recording operation, this API obtains the buffer that carries recording data from the **filledBufferQ_** queue.<br>The **self** parameter indicates the **BufferQueue** object that calls this API.<br>The **buffer** parameter indicates the double pointer to the idle buffer or the buffer carrying recording data.<br>The **size** parameter indicates the size of the buffer. | 63e41f4b71Sopenharmony_ci 64e41f4b71Sopenharmony_ci## Sample Code 65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ci### Linking the Dynamic Library in the CMake Script 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci``` cmake 69e41f4b71Sopenharmony_citarget_link_libraries(sample PUBLIC libOpenSLES.so) 70e41f4b71Sopenharmony_ci``` 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ciRefer to the sample code below to play an audio file. 73e41f4b71Sopenharmony_ci 74e41f4b71Sopenharmony_ci1. Add the header files. 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci ```c++ 77e41f4b71Sopenharmony_ci #include "SLES/OpenSLES.h" 78e41f4b71Sopenharmony_ci #include "SLES/OpenSLES_OpenHarmony.h" 79e41f4b71Sopenharmony_ci #include "SLES/OpenSLES_Platform.h" 80e41f4b71Sopenharmony_ci ``` 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci2. Use the **slCreateEngine** API to obtain an **engine** instance. 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci ```c++ 85e41f4b71Sopenharmony_ci SLObjectItf engineObject = nullptr; 86e41f4b71Sopenharmony_ci slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr); 87e41f4b71Sopenharmony_ci (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 88e41f4b71Sopenharmony_ci ``` 89e41f4b71Sopenharmony_ci 90e41f4b71Sopenharmony_ci3. Obtain the **engineEngine** instance of the **SL_IID_ENGINE** API. 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci ```c++ 93e41f4b71Sopenharmony_ci SLEngineItf engineEngine = nullptr; 94e41f4b71Sopenharmony_ci (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 95e41f4b71Sopenharmony_ci ``` 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci4. Configure the player and create an **AudioPlayer** instance. 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci ```c++ 100e41f4b71Sopenharmony_ci SLDataLocator_BufferQueue slBufferQueue = { 101e41f4b71Sopenharmony_ci SL_DATALOCATOR_BUFFERQUEUE, 102e41f4b71Sopenharmony_ci 1 103e41f4b71Sopenharmony_ci }; 104e41f4b71Sopenharmony_ci 105e41f4b71Sopenharmony_ci // Configure the parameters based on the audio file format. 106e41f4b71Sopenharmony_ci SLDataFormat_PCM pcmFormat = { 107e41f4b71Sopenharmony_ci SL_DATAFORMAT_PCM, 108e41f4b71Sopenharmony_ci 2, // Number of channels. 109e41f4b71Sopenharmony_ci SL_SAMPLINGRATE_48, // Sampling rate. 110e41f4b71Sopenharmony_ci SL_PCMSAMPLEFORMAT_FIXED_16, // Audio sample format. 111e41f4b71Sopenharmony_ci 16, 112e41f4b71Sopenharmony_ci SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, 113e41f4b71Sopenharmony_ci SL_BYTEORDER_LITTLEENDIAN 114e41f4b71Sopenharmony_ci }; 115e41f4b71Sopenharmony_ci SLDataSource slSource = { 116e41f4b71Sopenharmony_ci &slBufferQueue, 117e41f4b71Sopenharmony_ci &pcmFormat 118e41f4b71Sopenharmony_ci }; 119e41f4b71Sopenharmony_ci SLObjectItf pcmPlayerObject = nullptr; 120e41f4b71Sopenharmony_ci (*engineEngine)->CreateAudioPlayer(engineEngine, 121e41f4b71Sopenharmony_ci &pcmPlayerObject, 122e41f4b71Sopenharmony_ci &slSource, 123e41f4b71Sopenharmony_ci &slSink, 124e41f4b71Sopenharmony_ci 0, 125e41f4b71Sopenharmony_ci nullptr, 126e41f4b71Sopenharmony_ci nullptr); 127e41f4b71Sopenharmony_ci (*pcmPlayerObject)->Realize(pcmPlayerObject, SL_BOOLEAN_FALSE); 128e41f4b71Sopenharmony_ci ``` 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci5. Obtain the **bufferQueueItf** instance of the **SL_IID_OH_BUFFERQUEUE** API. 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci ```c++ 133e41f4b71Sopenharmony_ci SLOHBufferQueueItf bufferQueueItf; 134e41f4b71Sopenharmony_ci (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf); 135e41f4b71Sopenharmony_ci ``` 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci6. Open an audio file and register the **BufferQueueCallback** function. 138e41f4b71Sopenharmony_ci 139e41f4b71Sopenharmony_ci ```c++ 140e41f4b71Sopenharmony_ci static void BufferQueueCallback (SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size) 141e41f4b71Sopenharmony_ci { 142e41f4b71Sopenharmony_ci SLuint8 *buffer = nullptr; 143e41f4b71Sopenharmony_ci SLuint32 pSize; 144e41f4b71Sopenharmony_ci (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, &pSize); 145e41f4b71Sopenharmony_ci // Write the audio data to be played to the buffer. 146e41f4b71Sopenharmony_ci (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size); 147e41f4b71Sopenharmony_ci } 148e41f4b71Sopenharmony_ci void *pContext; // This callback can be used to obtain the custom context information passed in. 149e41f4b71Sopenharmony_ci (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, pContext); 150e41f4b71Sopenharmony_ci ``` 151e41f4b71Sopenharmony_ci 152e41f4b71Sopenharmony_ci7. Obtain the **playItf** instance of the **SL_PLAYSTATE_PLAYING** API and start playing. 153e41f4b71Sopenharmony_ci 154e41f4b71Sopenharmony_ci ```c++ 155e41f4b71Sopenharmony_ci SLPlayItf playItf = nullptr; 156e41f4b71Sopenharmony_ci (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &playItf); 157e41f4b71Sopenharmony_ci (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING); 158e41f4b71Sopenharmony_ci ``` 159e41f4b71Sopenharmony_ci 160e41f4b71Sopenharmony_ci8. Stop playing. 161e41f4b71Sopenharmony_ci 162e41f4b71Sopenharmony_ci ```c++ 163e41f4b71Sopenharmony_ci (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 164e41f4b71Sopenharmony_ci (*pcmPlayerObject)->Destroy(pcmPlayerObject); 165e41f4b71Sopenharmony_ci (*engineObject)->Destroy(engineObject); 166e41f4b71Sopenharmony_ci ``` 167