1# Switching from OpenSL ES to OHAudio (C/C++)
2
3You 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.
4
5## Differences in Features Supported
6
7Different from the OpenSL ES APIs, the **OHAudio** APIs support low-latency playback/recording and service change listening.
8
9The table below lists the differences in the features supported by the APIs.
10
11| | OpenSL ES| OHAudio |
12| --- | --- | --- |
13| Audio streaming playback| Supported| Supported|
14| Audio streaming recording| Supported| Supported|
15| Low-latency audio playback| Not supported| Supported|
16| Low-latency audio recording| Not supported| Supported|
17| Switching the state of a playback object| Supported| Supported|
18| Switching the state of a recording object| Supported| Supported|
19| Obtaining the state of an audio stream object| Supported| Supported|
20| Clearing the playback cache| Not supported| Supported|
21| Listening for audio interruption events| Not supported| Supported|
22| Listening for audio stream events| Not supported| Supported|
23| Listening for stream exception events| Not supported| Supported|
24| Listening for output device update events| Not supported| Supported|
25
26## Differences in Development Modes
27
28This 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.
29
30### Constructing Instances
31
32OpenSL ES:
33
34Obtain an **Engine** object through the global interface, and construct an audio playback object based on the **Engine** object and the input and output parameters.
35
36```c++
37// Generate an Engine object.
38SLEngineItf engine;
39// ...
40
41// Configure audio input slSource as required.
42SLDataSource slSource;
43// ...
44
45// Configure audio output slSink as required.
46SLDataSink slSink;
47// ...
48
49// Generate an audio playback object.
50SLObjectItf playerObject;
51(*engine)->CreateAudioPlayer(engine,
52                             &playerObject,
53                             &slSource,
54                             &slSink,
55                             0,
56                             nullptr,
57                             nullptr);
58
59(*playerObject)->Realize(playerObject,
60                         SL_BOOLEAN_FALSE);
61```
62
63OHAudio:
64
65Use the builder mode to generate an audio playback object based on custom parameters.
66
67```c++
68// Create a builder.
69OH_AudioStreamBuilder *builder;
70OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER);
71
72// Set custom parameters. Otherwise, the default parameters will be used.
73OH_AudioStreamBuilder_SetSamplingRate(builder, 48000);
74OH_AudioStreamBuilder_SetChannelCount(builder, 2);
75OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
76OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
77// This parameter specifies the audio usage and is supported only by OHAudio. The system implements audio policy adaptation based on the parameter.
78OH_AudioStreamBuilder_SetRendererInfo(builder, AUDIOSTREAM_USAGE_MUSIC);
79// ...
80
81// Generate an audio playback object.
82OH_AudioRenderer *audioRenderer;
83OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
84```
85
86### State Switching
87
88OpenSL ES:
89
90Obtain 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**.
91
92```c++
93// Obtain the playback operation interface based on the audio playback object.
94SLPlayItf playItf = nullptr;
95(*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playItf);
96// Switch the state.
97(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
98(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PAUSED);
99(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
100```
101
102OHAudio:
103
104There 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**.
105
106```c++
107// Switch the state.
108OH_AudioRenderer_Start(audioRenderer);
109OH_AudioRenderer_Pause(audioRenderer);
110OH_AudioRenderer_Stop(audioRenderer);
111```
112
113### Data Processing
114
115OpenSL ES:
116
117Based on the extended **OHBufferQueue** APIs, you can register a custom callback function to write audio data to be played to the system buffer.
118
119```c++
120static void MyBufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size)
121{
122    SLuint8 *buffer = nullptr;
123    SLuint32 bufferSize;
124    // Obtain the buffer provided by the system.
125    (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, &bufferSize);
126    // Write the audio data to be played to the buffer.
127    // ...
128    // Enqueue the buffer.
129    (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, bufferSize);
130}
131
132// Obtain the OHBufferQueue APIs.
133SLOHBufferQueueItf bufferQueueItf;
134(*playerObject)->GetInterface(playerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
135// This callback can be used to obtain the custom context information passed in.
136void *pContext;
137(*bufferQueueItf)->RegisterCallback(bufferQueueItf, MyBufferQueueCallback, pContext);
138```
139
140OHAudio:
141
142The 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.
143
144```c++
145static int32_t MyOnWriteData(
146    OH_AudioRenderer *renderer,
147    void *userData,
148    void *buffer,
149    int32_t bufferLen)
150{
151    // Write the data to be played to the buffer based on the requested buffer length.
152    // After the function is returned, the system automatically fetches data from the buffer.
153}
154
155OH_AudioRenderer_Callbacks callbacks;
156callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
157
158// Set the callback function for outputting audio streams. The callback function is automatically registered when the audio playback object is generated.
159void *userData = nullptr;
160OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, userData);
161```
162
163### Releasing Resources
164
165OpenSL ES:
166
167Call **SLObjectItf** to release object resources.
168
169```c++
170// Release the playback object resources.
171(*playerObject)->Destroy(playerObject);
172```
173
174OHAudio:
175
176Call the release interface of the module to release object resources.
177
178```c++
179// Release the builder resources.
180OH_AudioStreamBuilder_Destroy(builder);
181
182// Release the playback object resources.
183OH_AudioRenderer_Release(audioRenderer);
184```
185