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