1e41f4b71Sopenharmony_ci# Switching from OpenSL ES to OHAudio (C/C++) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciYou are advised to use **OHAudio** APIs instead of OpenSL ES APIs to develop audio services, since the latter may fail to provide extended audio capabilities. This topic describes how to switch the audio service code from the OpenSL ES APIs to the **OHAudio** APIs. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## Differences in Features Supported 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciDifferent from the OpenSL ES APIs, the **OHAudio** APIs support low-latency playback/recording and service change listening. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciThe table below lists the differences in the features supported by the APIs. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci| | OpenSL ES| OHAudio | 12e41f4b71Sopenharmony_ci| --- | --- | --- | 13e41f4b71Sopenharmony_ci| Audio streaming playback| Supported| Supported| 14e41f4b71Sopenharmony_ci| Audio streaming recording| Supported| Supported| 15e41f4b71Sopenharmony_ci| Low-latency audio playback| Not supported| Supported| 16e41f4b71Sopenharmony_ci| Low-latency audio recording| Not supported| Supported| 17e41f4b71Sopenharmony_ci| Switching the state of a playback object| Supported| Supported| 18e41f4b71Sopenharmony_ci| Switching the state of a recording object| Supported| Supported| 19e41f4b71Sopenharmony_ci| Obtaining the state of an audio stream object| Supported| Supported| 20e41f4b71Sopenharmony_ci| Clearing the playback cache| Not supported| Supported| 21e41f4b71Sopenharmony_ci| Listening for audio interruption events| Not supported| Supported| 22e41f4b71Sopenharmony_ci| Listening for audio stream events| Not supported| Supported| 23e41f4b71Sopenharmony_ci| Listening for stream exception events| Not supported| Supported| 24e41f4b71Sopenharmony_ci| Listening for output device update events| Not supported| Supported| 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci## Differences in Development Modes 27e41f4b71Sopenharmony_ci 28e41f4b71Sopenharmony_ciThis section describes the differences between **OHAudio** and OpenSL ES APIs in development modes based on the development procedure of audio playback. The implementation of audio recording is similar. 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ci### Constructing Instances 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ciOpenSL ES: 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ciObtain an **Engine** object through the global interface, and construct an audio playback object based on the **Engine** object and the input and output parameters. 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci```c++ 37e41f4b71Sopenharmony_ci// Generate an Engine object. 38e41f4b71Sopenharmony_ciSLEngineItf engine; 39e41f4b71Sopenharmony_ci// ... 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci// Configure audio input slSource as required. 42e41f4b71Sopenharmony_ciSLDataSource slSource; 43e41f4b71Sopenharmony_ci// ... 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci// Configure audio output slSink as required. 46e41f4b71Sopenharmony_ciSLDataSink slSink; 47e41f4b71Sopenharmony_ci// ... 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci// Generate an audio playback object. 50e41f4b71Sopenharmony_ciSLObjectItf playerObject; 51e41f4b71Sopenharmony_ci(*engine)->CreateAudioPlayer(engine, 52e41f4b71Sopenharmony_ci &playerObject, 53e41f4b71Sopenharmony_ci &slSource, 54e41f4b71Sopenharmony_ci &slSink, 55e41f4b71Sopenharmony_ci 0, 56e41f4b71Sopenharmony_ci nullptr, 57e41f4b71Sopenharmony_ci nullptr); 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci(*playerObject)->Realize(playerObject, 60e41f4b71Sopenharmony_ci SL_BOOLEAN_FALSE); 61e41f4b71Sopenharmony_ci``` 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ciOHAudio: 64e41f4b71Sopenharmony_ci 65e41f4b71Sopenharmony_ciUse the builder mode to generate an audio playback object based on custom parameters. 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ci```c++ 68e41f4b71Sopenharmony_ci// Create a builder. 69e41f4b71Sopenharmony_ciOH_AudioStreamBuilder *builder; 70e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER); 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci// Set custom parameters. Otherwise, the default parameters will be used. 73e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetSamplingRate(builder, 48000); 74e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetChannelCount(builder, 2); 75e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE); 76e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW); 77e41f4b71Sopenharmony_ci// This parameter specifies the audio usage and is supported only by OHAudio. The system implements audio policy adaptation based on the parameter. 78e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetRendererInfo(builder, AUDIOSTREAM_USAGE_MUSIC); 79e41f4b71Sopenharmony_ci// ... 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci// Generate an audio playback object. 82e41f4b71Sopenharmony_ciOH_AudioRenderer *audioRenderer; 83e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer); 84e41f4b71Sopenharmony_ci``` 85e41f4b71Sopenharmony_ci 86e41f4b71Sopenharmony_ci### State Switching 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ciOpenSL ES: 89e41f4b71Sopenharmony_ci 90e41f4b71Sopenharmony_ciObtain the state switching interface based on the audio playback object and use the interface to switch the state. There are three states: **SL_PLAYSTATE_STOPPED**, **SL_PLAYSTATE_PAUSED**, and **SL_PLAYSTATE_PLAYING**. 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci```c++ 93e41f4b71Sopenharmony_ci// Obtain the playback operation interface based on the audio playback object. 94e41f4b71Sopenharmony_ciSLPlayItf playItf = nullptr; 95e41f4b71Sopenharmony_ci(*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playItf); 96e41f4b71Sopenharmony_ci// Switch the state. 97e41f4b71Sopenharmony_ci(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING); 98e41f4b71Sopenharmony_ci(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PAUSED); 99e41f4b71Sopenharmony_ci(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 100e41f4b71Sopenharmony_ci``` 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ciOHAudio: 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ciThere are independent state switching interfaces. The state is switched based on the state machine. There are six states, which are mainly switched between **AUDIOSTREAM_STATE_PREPARED**, **AUDIOSTREAM_STATE_RUNNING**, **AUDIOSTREAM_STATE_STOPPED**, **AUDIOSTREAM_STATE_PAUSED**, and **AUDIOSTREAM_STATE_RELEASED**. 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci```c++ 107e41f4b71Sopenharmony_ci// Switch the state. 108e41f4b71Sopenharmony_ciOH_AudioRenderer_Start(audioRenderer); 109e41f4b71Sopenharmony_ciOH_AudioRenderer_Pause(audioRenderer); 110e41f4b71Sopenharmony_ciOH_AudioRenderer_Stop(audioRenderer); 111e41f4b71Sopenharmony_ci``` 112e41f4b71Sopenharmony_ci 113e41f4b71Sopenharmony_ci### Data Processing 114e41f4b71Sopenharmony_ci 115e41f4b71Sopenharmony_ciOpenSL ES: 116e41f4b71Sopenharmony_ci 117e41f4b71Sopenharmony_ciBased on the extended **OHBufferQueue** APIs, you can register a custom callback function to write audio data to be played to the system buffer. 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci```c++ 120e41f4b71Sopenharmony_cistatic void MyBufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size) 121e41f4b71Sopenharmony_ci{ 122e41f4b71Sopenharmony_ci SLuint8 *buffer = nullptr; 123e41f4b71Sopenharmony_ci SLuint32 bufferSize; 124e41f4b71Sopenharmony_ci // Obtain the buffer provided by the system. 125e41f4b71Sopenharmony_ci (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, &bufferSize); 126e41f4b71Sopenharmony_ci // Write the audio data to be played to the buffer. 127e41f4b71Sopenharmony_ci // ... 128e41f4b71Sopenharmony_ci // Enqueue the buffer. 129e41f4b71Sopenharmony_ci (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, bufferSize); 130e41f4b71Sopenharmony_ci} 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci// Obtain the OHBufferQueue APIs. 133e41f4b71Sopenharmony_ciSLOHBufferQueueItf bufferQueueItf; 134e41f4b71Sopenharmony_ci(*playerObject)->GetInterface(playerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf); 135e41f4b71Sopenharmony_ci// This callback can be used to obtain the custom context information passed in. 136e41f4b71Sopenharmony_civoid *pContext; 137e41f4b71Sopenharmony_ci(*bufferQueueItf)->RegisterCallback(bufferQueueItf, MyBufferQueueCallback, pContext); 138e41f4b71Sopenharmony_ci``` 139e41f4b71Sopenharmony_ci 140e41f4b71Sopenharmony_ciOHAudio: 141e41f4b71Sopenharmony_ci 142e41f4b71Sopenharmony_ciThe callback mode is used. When the audio playback object is constructed, a data input callback is registered to implement custom data filling. During playback, a data request callback is automatically triggered at a proper time based on the system scheduling and delay configuration. 143e41f4b71Sopenharmony_ci 144e41f4b71Sopenharmony_ci```c++ 145e41f4b71Sopenharmony_cistatic int32_t MyOnWriteData( 146e41f4b71Sopenharmony_ci OH_AudioRenderer *renderer, 147e41f4b71Sopenharmony_ci void *userData, 148e41f4b71Sopenharmony_ci void *buffer, 149e41f4b71Sopenharmony_ci int32_t bufferLen) 150e41f4b71Sopenharmony_ci{ 151e41f4b71Sopenharmony_ci // Write the data to be played to the buffer based on the requested buffer length. 152e41f4b71Sopenharmony_ci // After the function is returned, the system automatically fetches data from the buffer. 153e41f4b71Sopenharmony_ci} 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ciOH_AudioRenderer_Callbacks callbacks; 156e41f4b71Sopenharmony_cicallbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData; 157e41f4b71Sopenharmony_ci 158e41f4b71Sopenharmony_ci// Set the callback function for outputting audio streams. The callback function is automatically registered when the audio playback object is generated. 159e41f4b71Sopenharmony_civoid *userData = nullptr; 160e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, userData); 161e41f4b71Sopenharmony_ci``` 162e41f4b71Sopenharmony_ci 163e41f4b71Sopenharmony_ci### Releasing Resources 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ciOpenSL ES: 166e41f4b71Sopenharmony_ci 167e41f4b71Sopenharmony_ciCall **SLObjectItf** to release object resources. 168e41f4b71Sopenharmony_ci 169e41f4b71Sopenharmony_ci```c++ 170e41f4b71Sopenharmony_ci// Release the playback object resources. 171e41f4b71Sopenharmony_ci(*playerObject)->Destroy(playerObject); 172e41f4b71Sopenharmony_ci``` 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ciOHAudio: 175e41f4b71Sopenharmony_ci 176e41f4b71Sopenharmony_ciCall the release interface of the module to release object resources. 177e41f4b71Sopenharmony_ci 178e41f4b71Sopenharmony_ci```c++ 179e41f4b71Sopenharmony_ci// Release the builder resources. 180e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_Destroy(builder); 181e41f4b71Sopenharmony_ci 182e41f4b71Sopenharmony_ci// Release the playback object resources. 183e41f4b71Sopenharmony_ciOH_AudioRenderer_Release(audioRenderer); 184e41f4b71Sopenharmony_ci``` 185