1e41f4b71Sopenharmony_ci# Using OHAudio for Audio Playback (C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci**OHAudio** is a set of C APIs introduced in API version 10. These APIs are normalized in design and support both common and low-latency audio channels. They support the PCM format only. They are suitable for playback applications that implement audio output at the native layer.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci## Prerequisites
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciTo use the playback or recording capability of **OHAudio**, you must first import the corresponding header files.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci### Linking the Dynamic Library in the CMake Script
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci``` cmake
12e41f4b71Sopenharmony_citarget_link_libraries(sample PUBLIC libohaudio.so)
13e41f4b71Sopenharmony_ci```
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci### Adding Header Files
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ciTo use APIs for audio playback, import <[native_audiostreambuilder.h](../../reference/apis-audio-kit/native__audiostreambuilder_8h.md)> and <[native_audiorenderer.h](../../reference/apis-audio-kit/native__audiorenderer_8h.md)>.
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci```cpp
20e41f4b71Sopenharmony_ci#include <ohaudio/native_audiorenderer.h>
21e41f4b71Sopenharmony_ci#include <ohaudio/native_audiostreambuilder.h>
22e41f4b71Sopenharmony_ci```
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci## Building Audio Streams
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci**OHAudio** provides the **OH_AudioStreamBuilder** class, which complies with the builder design pattern and is used to build audio streams. You need to specify [OH_AudioStream_Type](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostream_type) based on your service scenarios.
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci**OH_AudioStream_Type** can be set to either of the following:
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci- AUDIOSTREAM_TYPE_RENDERER
31e41f4b71Sopenharmony_ci- AUDIOSTREAM_TYPE_CAPTURER
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ciThe following code snippet shows how to use [OH_AudioStreamBuilder_Create](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_create) to create a builder:
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci```
36e41f4b71Sopenharmony_ciOH_AudioStreamBuilder* builder;
37e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_Create(&builder, streamType);
38e41f4b71Sopenharmony_ci```
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ciAfter the audio service is complete, call [OH_AudioStreamBuilder_Destroy](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_destroy) to destroy the builder.
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci```
43e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_Destroy(builder);
44e41f4b71Sopenharmony_ci```
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci## How to Develop
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ciRead [OHAudio](../../reference/apis-audio-kit/_o_h_audio.md) for the API reference.
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ciThe following walks you through how to implement simple playback:
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci1. Create an audio stream builder.
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci    ```c++
55e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder* builder;
56e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER);
57e41f4b71Sopenharmony_ci    ```
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci2. Set audio stream parameters.
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci    After creating the builder for audio playback, set the parameters required.
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci    ```c++
64e41f4b71Sopenharmony_ci    // Set the audio sampling rate.
65e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_SetSamplingRate(builder, 48000);
66e41f4b71Sopenharmony_ci    // Set the number of audio channels.
67e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_SetChannelCount(builder, 2);
68e41f4b71Sopenharmony_ci    // Set the audio sampling format.
69e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
70e41f4b71Sopenharmony_ci    // Set the encoding type of the audio stream.
71e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
72e41f4b71Sopenharmony_ci    // Set the usage scenario of the audio renderer.
73e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_SetRendererInfo(builder, AUDIOSTREAM_USAGE_MUSIC);
74e41f4b71Sopenharmony_ci    ```
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci    Note that the audio data to play is written through callbacks. You must call **OH_AudioStreamBuilder_SetRendererCallback** to implement the callbacks. For details about the declaration of the callback functions, see [OH_AudioRenderer_Callbacks](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiorenderer_callbacks).
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci3. Set the callback functions.
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci    For details about concurrent processing of multiple audio streams, see [Processing Audio Interruption Events](audio-playback-concurrency.md). The procedure is similar, and the only difference is the API programming language in use.
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci    ```c++
84e41f4b71Sopenharmony_ci    // Customize a data writing function.
85e41f4b71Sopenharmony_ci    int32_t MyOnWriteData(
86e41f4b71Sopenharmony_ci        OH_AudioRenderer* renderer,
87e41f4b71Sopenharmony_ci        void* userData,
88e41f4b71Sopenharmony_ci        void* buffer,
89e41f4b71Sopenharmony_ci        int32_t length)
90e41f4b71Sopenharmony_ci    {
91e41f4b71Sopenharmony_ci        // Write the data to be played to the buffer by length.
92e41f4b71Sopenharmony_ci        return 0;
93e41f4b71Sopenharmony_ci    }
94e41f4b71Sopenharmony_ci    // Customize an audio stream event function.
95e41f4b71Sopenharmony_ci    int32_t MyOnStreamEvent(
96e41f4b71Sopenharmony_ci        OH_AudioRenderer* renderer,
97e41f4b71Sopenharmony_ci        void* userData,
98e41f4b71Sopenharmony_ci        OH_AudioStream_Event event)
99e41f4b71Sopenharmony_ci    {
100e41f4b71Sopenharmony_ci        // Update the player status and UI based on the audio stream event information indicated by the event.
101e41f4b71Sopenharmony_ci        return 0;
102e41f4b71Sopenharmony_ci    }
103e41f4b71Sopenharmony_ci    // Customize an audio interruption event function.
104e41f4b71Sopenharmony_ci    int32_t MyOnInterruptEvent(
105e41f4b71Sopenharmony_ci        OH_AudioRenderer* renderer,
106e41f4b71Sopenharmony_ci        void* userData,
107e41f4b71Sopenharmony_ci        OH_AudioInterrupt_ForceType type,
108e41f4b71Sopenharmony_ci        OH_AudioInterrupt_Hint hint)
109e41f4b71Sopenharmony_ci    {
110e41f4b71Sopenharmony_ci        // Update the player status and UI based on the audio interruption information indicated by type and hint.
111e41f4b71Sopenharmony_ci        return 0;
112e41f4b71Sopenharmony_ci    }
113e41f4b71Sopenharmony_ci    // Customize an exception callback function.
114e41f4b71Sopenharmony_ci    int32_t MyOnError(
115e41f4b71Sopenharmony_ci        OH_AudioRenderer* renderer,
116e41f4b71Sopenharmony_ci        void* userData,
117e41f4b71Sopenharmony_ci        OH_AudioStream_Result error)
118e41f4b71Sopenharmony_ci    {
119e41f4b71Sopenharmony_ci        // Perform operations based on the audio exception information indicated by error.
120e41f4b71Sopenharmony_ci        return 0;
121e41f4b71Sopenharmony_ci    }
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci    OH_AudioRenderer_Callbacks callbacks;
124e41f4b71Sopenharmony_ci    // Set the callbacks.
125e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
126e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnStreamEvent = MyOnStreamEvent;
127e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent;
128e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnError = MyOnError;
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_ci    // Set callbacks for the audio renderer.
131e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, nullptr);
132e41f4b71Sopenharmony_ci    ```
133e41f4b71Sopenharmony_ci
134e41f4b71Sopenharmony_ci    To avoid unexpected behavior, ensure that each callback of [OH_AudioRenderer_Callbacks](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiorenderer_callbacks) is initialized by a custom callback method or null pointer when being set.
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci    ```c++
137e41f4b71Sopenharmony_ci    // Customize a data writing function.
138e41f4b71Sopenharmony_ci    int32_t MyOnWriteData(
139e41f4b71Sopenharmony_ci        OH_AudioRenderer* renderer,
140e41f4b71Sopenharmony_ci        void* userData,
141e41f4b71Sopenharmony_ci        void* buffer,
142e41f4b71Sopenharmony_ci        int32_t length)
143e41f4b71Sopenharmony_ci    {
144e41f4b71Sopenharmony_ci        // Write the data to be played to the buffer by length.
145e41f4b71Sopenharmony_ci        return 0;
146e41f4b71Sopenharmony_ci    }
147e41f4b71Sopenharmony_ci    // Customize an audio interruption event function.
148e41f4b71Sopenharmony_ci    int32_t MyOnInterruptEvent(
149e41f4b71Sopenharmony_ci        OH_AudioRenderer* renderer,
150e41f4b71Sopenharmony_ci        void* userData,
151e41f4b71Sopenharmony_ci        OH_AudioInterrupt_ForceType type,
152e41f4b71Sopenharmony_ci        OH_AudioInterrupt_Hint hint)
153e41f4b71Sopenharmony_ci    {
154e41f4b71Sopenharmony_ci        // Update the player status and UI based on the audio interruption information indicated by type and hint.
155e41f4b71Sopenharmony_ci        return 0;
156e41f4b71Sopenharmony_ci    }
157e41f4b71Sopenharmony_ci    OH_AudioRenderer_Callbacks callbacks;
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci    // Configure a callback function. If listening is required, assign a value.
160e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
161e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent;
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ci    // (Mandatory) If listening is not required, use a null pointer for initialization.
164e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnStreamEvent = nullptr;
165e41f4b71Sopenharmony_ci    callbacks.OH_AudioRenderer_OnError = nullptr;
166e41f4b71Sopenharmony_ci    ```
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci4. Create an audio renderer instance.
169e41f4b71Sopenharmony_ci
170e41f4b71Sopenharmony_ci    ```c++
171e41f4b71Sopenharmony_ci    OH_AudioRenderer* audioRenderer;
172e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
173e41f4b71Sopenharmony_ci    ```
174e41f4b71Sopenharmony_ci
175e41f4b71Sopenharmony_ci5. Use the audio renderer.
176e41f4b71Sopenharmony_ci
177e41f4b71Sopenharmony_ci    You can use the APIs listed below to control the audio streams.
178e41f4b71Sopenharmony_ci    
179e41f4b71Sopenharmony_ci    | API                                                        | Description        |
180e41f4b71Sopenharmony_ci    | ------------------------------------------------------------ | ------------ |
181e41f4b71Sopenharmony_ci    | OH_AudioStream_Result OH_AudioRenderer_Start(OH_AudioRenderer* renderer) | Starts the audio renderer.    |
182e41f4b71Sopenharmony_ci    | OH_AudioStream_Result OH_AudioRenderer_Pause(OH_AudioRenderer* renderer) | Pauses the audio renderer.    |
183e41f4b71Sopenharmony_ci    | OH_AudioStream_Result OH_AudioRenderer_Stop(OH_AudioRenderer* renderer) | Stops the audio renderer.    |
184e41f4b71Sopenharmony_ci    | OH_AudioStream_Result OH_AudioRenderer_Flush(OH_AudioRenderer* renderer) | Flushes written audio data.|
185e41f4b71Sopenharmony_ci    | OH_AudioStream_Result OH_AudioRenderer_Release(OH_AudioRenderer* renderer) | Releases the audio renderer instance.|
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ci6. Destroy the audio stream builder.
188e41f4b71Sopenharmony_ci
189e41f4b71Sopenharmony_ci    When the builder is no longer used, release related resources.
190e41f4b71Sopenharmony_ci
191e41f4b71Sopenharmony_ci    ```c++
192e41f4b71Sopenharmony_ci    OH_AudioStreamBuilder_Destroy(builder);
193e41f4b71Sopenharmony_ci    ```
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ci## Setting the Low Latency Mode
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ciIf the device supports the low-latency channel, you can use the low-latency mode to create a player for a higher-quality audio experience.
198e41f4b71Sopenharmony_ci
199e41f4b71Sopenharmony_ciThe development process is similar to that in the common playback scenario. The only difference is that you need to set the low delay mode by calling [OH_AudioStreamBuilder_SetLatencyMode()](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_setlatencymode) when creating an audio stream builder.
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ciThe code snippet is as follows:
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci```C
204e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetLatencyMode(builder, AUDIOSTREAM_LATENCY_MODE_FAST);
205e41f4b71Sopenharmony_ci```
206e41f4b71Sopenharmony_ci
207e41f4b71Sopenharmony_ci## Setting the Audio Channel Layout
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ciIn the case of audio file playback, you can set the audio channel layout to specify the speaker position during rendering or playing for a better audio experience.
210e41f4b71Sopenharmony_ci
211e41f4b71Sopenharmony_ciThe development process is similar to that in the common playback scenario. The only difference is that you need to set the audio channel layout by calling [OH_AudioStreamBuilder_SetChannelLayout()](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_setchannellayout) when creating an audio stream builder.
212e41f4b71Sopenharmony_ci
213e41f4b71Sopenharmony_ciIf the audio channel layout does not match the number of audio channels, audio streams fail to be created. Therefore, you must ensure that the audio channel layout setting is correct.
214e41f4b71Sopenharmony_ci
215e41f4b71Sopenharmony_ciIf you do not know the accurate audio channel layout or you want to use the default audio channel layout, do not call the API to set the audio channel layout. Alternatively, deliver **CH_LAYOUT_UNKNOWN** to use the default audio channel layout, which is specific to the number of audio channels.
216e41f4b71Sopenharmony_ci
217e41f4b71Sopenharmony_ciFor audio in HOA format, to obtain the correct rendering and playback effect, you must specify the audio channel layout.
218e41f4b71Sopenharmony_ci
219e41f4b71Sopenharmony_ciThe code snippet is as follows:
220e41f4b71Sopenharmony_ci
221e41f4b71Sopenharmony_ci```C
222e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetChannelLayout(builder, CH_LAYOUT_STEREO);
223e41f4b71Sopenharmony_ci```
224e41f4b71Sopenharmony_ci
225e41f4b71Sopenharmony_ci## Playing Audio Files in AudioVivid Format
226e41f4b71Sopenharmony_ci
227e41f4b71Sopenharmony_ciIn the case of audio file playback in AudioVivid format, the callback function used for writing data is different from that in the common playback scenario. This callback function can write PCM data and metadata at the same time.
228e41f4b71Sopenharmony_ci
229e41f4b71Sopenharmony_ciThe development process is similar to that in the common playback scenario. The only difference is that you need to call [OH_AudioStreamBuilder_SetWriteDataWithMetadataCallback()](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_setwritedatawithmetadatacallback) to set the callback function and call [OH_AudioStreamBuilder_SetEncodingType()](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_setencodingtype) to set the encoding type to **AUDIOSTREAM_ENCODING_TYPE_AUDIOVIVID** when creating an audio stream builder.
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ciWhen an audio file in AudioVivid format is played, the frame size is fixed. Therefore, do not call [OH_AudioStreamBuilder_SetFrameSizeInCallback()](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_setframesizeincallback) to set the frame size in the callback. In addition, when setting the number of audio channels and the audio channel layout, use the sum of the number of sound beds written into the audio source and the number of objects.
232e41f4b71Sopenharmony_ci
233e41f4b71Sopenharmony_ciThe code snippet is as follows:
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ci```C
236e41f4b71Sopenharmony_ci// Customize a callback function for simultaneously writing PCM data and metadata.
237e41f4b71Sopenharmony_ciint32_t MyOnWriteDataWithMetadata(
238e41f4b71Sopenharmony_ci    OH_AudioRenderer* renderer,
239e41f4b71Sopenharmony_ci    void* userData,
240e41f4b71Sopenharmony_ci    void* audioData,
241e41f4b71Sopenharmony_ci    int32_t audioDataSize,
242e41f4b71Sopenharmony_ci    void* metadata,
243e41f4b71Sopenharmony_ci    int32_t metadataSize)
244e41f4b71Sopenharmony_ci{
245e41f4b71Sopenharmony_ci    // Write the PCM data and metadata to be played to the buffer by audioDataSize and metadataSize, respectively.
246e41f4b71Sopenharmony_ci    return 0;
247e41f4b71Sopenharmony_ci}
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci// Set the encoding type.
250e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_AUDIOVIVID);
251e41f4b71Sopenharmony_ci// Set the callbacks.
252e41f4b71Sopenharmony_ciOH_AudioRenderer_WriteDataWithMetadataCallback metadataCallback = MyOnWriteDataWithMetadata;
253e41f4b71Sopenharmony_ci// Set the callback function for writing both PCM data and metadata.
254e41f4b71Sopenharmony_ciOH_AudioStreamBuilder_SetWriteDataWithMetadataCallback(builder, metadataCallback, nullptr);
255e41f4b71Sopenharmony_ci```
256