1# Using OHAudio for Audio Playback (C/C++) 2 3**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. 4 5## Prerequisites 6 7To use the playback or recording capability of **OHAudio**, you must first import the corresponding header files. 8 9### Linking the Dynamic Library in the CMake Script 10 11``` cmake 12target_link_libraries(sample PUBLIC libohaudio.so) 13``` 14 15### Adding Header Files 16 17To 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)>. 18 19```cpp 20#include <ohaudio/native_audiorenderer.h> 21#include <ohaudio/native_audiostreambuilder.h> 22``` 23 24## Building Audio Streams 25 26**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. 27 28**OH_AudioStream_Type** can be set to either of the following: 29 30- AUDIOSTREAM_TYPE_RENDERER 31- AUDIOSTREAM_TYPE_CAPTURER 32 33The 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: 34 35``` 36OH_AudioStreamBuilder* builder; 37OH_AudioStreamBuilder_Create(&builder, streamType); 38``` 39 40After the audio service is complete, call [OH_AudioStreamBuilder_Destroy](../../reference/apis-audio-kit/_o_h_audio.md#oh_audiostreambuilder_destroy) to destroy the builder. 41 42``` 43OH_AudioStreamBuilder_Destroy(builder); 44``` 45 46## How to Develop 47 48Read [OHAudio](../../reference/apis-audio-kit/_o_h_audio.md) for the API reference. 49 50The following walks you through how to implement simple playback: 51 521. Create an audio stream builder. 53 54 ```c++ 55 OH_AudioStreamBuilder* builder; 56 OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER); 57 ``` 58 592. Set audio stream parameters. 60 61 After creating the builder for audio playback, set the parameters required. 62 63 ```c++ 64 // Set the audio sampling rate. 65 OH_AudioStreamBuilder_SetSamplingRate(builder, 48000); 66 // Set the number of audio channels. 67 OH_AudioStreamBuilder_SetChannelCount(builder, 2); 68 // Set the audio sampling format. 69 OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE); 70 // Set the encoding type of the audio stream. 71 OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW); 72 // Set the usage scenario of the audio renderer. 73 OH_AudioStreamBuilder_SetRendererInfo(builder, AUDIOSTREAM_USAGE_MUSIC); 74 ``` 75 76 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). 77 78 793. Set the callback functions. 80 81 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. 82 83 ```c++ 84 // Customize a data writing function. 85 int32_t MyOnWriteData( 86 OH_AudioRenderer* renderer, 87 void* userData, 88 void* buffer, 89 int32_t length) 90 { 91 // Write the data to be played to the buffer by length. 92 return 0; 93 } 94 // Customize an audio stream event function. 95 int32_t MyOnStreamEvent( 96 OH_AudioRenderer* renderer, 97 void* userData, 98 OH_AudioStream_Event event) 99 { 100 // Update the player status and UI based on the audio stream event information indicated by the event. 101 return 0; 102 } 103 // Customize an audio interruption event function. 104 int32_t MyOnInterruptEvent( 105 OH_AudioRenderer* renderer, 106 void* userData, 107 OH_AudioInterrupt_ForceType type, 108 OH_AudioInterrupt_Hint hint) 109 { 110 // Update the player status and UI based on the audio interruption information indicated by type and hint. 111 return 0; 112 } 113 // Customize an exception callback function. 114 int32_t MyOnError( 115 OH_AudioRenderer* renderer, 116 void* userData, 117 OH_AudioStream_Result error) 118 { 119 // Perform operations based on the audio exception information indicated by error. 120 return 0; 121 } 122 123 OH_AudioRenderer_Callbacks callbacks; 124 // Set the callbacks. 125 callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData; 126 callbacks.OH_AudioRenderer_OnStreamEvent = MyOnStreamEvent; 127 callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent; 128 callbacks.OH_AudioRenderer_OnError = MyOnError; 129 130 // Set callbacks for the audio renderer. 131 OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, nullptr); 132 ``` 133 134 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. 135 136 ```c++ 137 // Customize a data writing function. 138 int32_t MyOnWriteData( 139 OH_AudioRenderer* renderer, 140 void* userData, 141 void* buffer, 142 int32_t length) 143 { 144 // Write the data to be played to the buffer by length. 145 return 0; 146 } 147 // Customize an audio interruption event function. 148 int32_t MyOnInterruptEvent( 149 OH_AudioRenderer* renderer, 150 void* userData, 151 OH_AudioInterrupt_ForceType type, 152 OH_AudioInterrupt_Hint hint) 153 { 154 // Update the player status and UI based on the audio interruption information indicated by type and hint. 155 return 0; 156 } 157 OH_AudioRenderer_Callbacks callbacks; 158 159 // Configure a callback function. If listening is required, assign a value. 160 callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData; 161 callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent; 162 163 // (Mandatory) If listening is not required, use a null pointer for initialization. 164 callbacks.OH_AudioRenderer_OnStreamEvent = nullptr; 165 callbacks.OH_AudioRenderer_OnError = nullptr; 166 ``` 167 1684. Create an audio renderer instance. 169 170 ```c++ 171 OH_AudioRenderer* audioRenderer; 172 OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer); 173 ``` 174 1755. Use the audio renderer. 176 177 You can use the APIs listed below to control the audio streams. 178 179 | API | Description | 180 | ------------------------------------------------------------ | ------------ | 181 | OH_AudioStream_Result OH_AudioRenderer_Start(OH_AudioRenderer* renderer) | Starts the audio renderer. | 182 | OH_AudioStream_Result OH_AudioRenderer_Pause(OH_AudioRenderer* renderer) | Pauses the audio renderer. | 183 | OH_AudioStream_Result OH_AudioRenderer_Stop(OH_AudioRenderer* renderer) | Stops the audio renderer. | 184 | OH_AudioStream_Result OH_AudioRenderer_Flush(OH_AudioRenderer* renderer) | Flushes written audio data.| 185 | OH_AudioStream_Result OH_AudioRenderer_Release(OH_AudioRenderer* renderer) | Releases the audio renderer instance.| 186 1876. Destroy the audio stream builder. 188 189 When the builder is no longer used, release related resources. 190 191 ```c++ 192 OH_AudioStreamBuilder_Destroy(builder); 193 ``` 194 195## Setting the Low Latency Mode 196 197If the device supports the low-latency channel, you can use the low-latency mode to create a player for a higher-quality audio experience. 198 199The 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. 200 201The code snippet is as follows: 202 203```C 204OH_AudioStreamBuilder_SetLatencyMode(builder, AUDIOSTREAM_LATENCY_MODE_FAST); 205``` 206 207## Setting the Audio Channel Layout 208 209In 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. 210 211The 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. 212 213If 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. 214 215If 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. 216 217For audio in HOA format, to obtain the correct rendering and playback effect, you must specify the audio channel layout. 218 219The code snippet is as follows: 220 221```C 222OH_AudioStreamBuilder_SetChannelLayout(builder, CH_LAYOUT_STEREO); 223``` 224 225## Playing Audio Files in AudioVivid Format 226 227In 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. 228 229The 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. 230 231When 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. 232 233The code snippet is as follows: 234 235```C 236// Customize a callback function for simultaneously writing PCM data and metadata. 237int32_t MyOnWriteDataWithMetadata( 238 OH_AudioRenderer* renderer, 239 void* userData, 240 void* audioData, 241 int32_t audioDataSize, 242 void* metadata, 243 int32_t metadataSize) 244{ 245 // Write the PCM data and metadata to be played to the buffer by audioDataSize and metadataSize, respectively. 246 return 0; 247} 248 249// Set the encoding type. 250OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_AUDIOVIVID); 251// Set the callbacks. 252OH_AudioRenderer_WriteDataWithMetadataCallback metadataCallback = MyOnWriteDataWithMetadata; 253// Set the callback function for writing both PCM data and metadata. 254OH_AudioStreamBuilder_SetWriteDataWithMetadataCallback(builder, metadataCallback, nullptr); 255``` 256