1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // IWYU pragma: private, include "chre_api/chre.h" 18 // IWYU pragma: friend chre/.*\.h 19 20 #ifndef _CHRE_AUDIO_H_ 21 #define _CHRE_AUDIO_H_ 22 23 /** 24 * @file 25 * The API for requesting audio in the Context Hub Runtime Environment. 26 * 27 * This includes the definition of audio data structures and the ability to 28 * request audio streams. 29 */ 30 31 #include <chre/event.h> 32 33 #include <stdint.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 /** 40 * The current compatibility version of the chreAudioDataEvent structure. 41 */ 42 #define CHRE_AUDIO_DATA_EVENT_VERSION UINT8_C(1) 43 44 /** 45 * Produce an event ID in the block of IDs reserved for audio 46 * @param offset Index into audio event ID block; valid range [0,15] 47 */ 48 #define CHRE_AUDIO_EVENT_ID(offset) (CHRE_EVENT_AUDIO_FIRST_EVENT + (offset)) 49 50 /** 51 * nanoappHandleEvent argument: struct chreAudioSourceStatusEvent 52 * 53 * Indicates a change in the format and/or rate of audio data provided to a 54 * nanoapp. 55 */ 56 #define CHRE_EVENT_AUDIO_SAMPLING_CHANGE CHRE_AUDIO_EVENT_ID(0) 57 58 /** 59 * nanoappHandleEvent argument: struct chreAudioDataEvent 60 * 61 * Provides a buffer of audio data to a nanoapp. 62 */ 63 #define CHRE_EVENT_AUDIO_DATA CHRE_AUDIO_EVENT_ID(1) 64 65 /** 66 * The maximum size of the name of an audio source including the 67 * null-terminator. 68 */ 69 #define CHRE_AUDIO_SOURCE_NAME_MAX_SIZE (40) 70 71 /** 72 * Helper values for sample rates. 73 * 74 * @defgroup CHRE_AUDIO_SAMPLE_RATES 75 * @{ 76 */ 77 78 //! 16kHz Audio Sample Data 79 #define CHRE_AUDIO_SAMPLE_RATE_16KHZ (16000) 80 81 /** @} */ 82 83 /** 84 * Formats for audio that can be provided to a nanoapp. 85 */ 86 enum chreAudioDataFormat { 87 /** 88 * Unsigned, 8-bit u-Law encoded data as specified by ITU-T G.711. 89 */ 90 CHRE_AUDIO_DATA_FORMAT_8_BIT_U_LAW = 0, 91 92 /** 93 * Signed, 16-bit linear PCM data. Endianness must be native to the local 94 * processor. 95 */ 96 CHRE_AUDIO_DATA_FORMAT_16_BIT_SIGNED_PCM = 1, 97 }; 98 99 /** 100 * A description of an audio source available to a nanoapp. 101 * 102 * This provides a description of an audio source with a name and a 103 * description of the format of the provided audio data. 104 */ 105 struct chreAudioSource { 106 /** 107 * A human readable name for this audio source. This is a C-style, 108 * null-terminated string. The length must be less than or equal to 109 * CHRE_AUDIO_SOURCE_NAME_MAX_SIZE bytes (including the null-terminator) and 110 * is expected to describe the source of the audio in US English. All 111 * characters must be printable (i.e.: isprint would return true for all 112 * characters in the name for the EN-US locale). The typical use of this field 113 * is for a nanoapp to log the name of the audio source that it is using. 114 * 115 * Example: "Camcorder Microphone" 116 */ 117 const char *name; 118 119 /** 120 * The sampling rate in hertz of this mode. This value is rounded to the 121 * nearest integer. Typical values might include 16000, 44100 and 44800. 122 * 123 * If the requested audio source is preempted by another feature of the system 124 * (e.g. hotword), a gap may occur in received audio data. This is indicated 125 * to the client by posting a CHRE_EVENT_AUDIO_SAMPLING_CHANGE event. The 126 * nanoapp will then receive another CHRE_EVENT_AUDIO_SAMPLING_CHANGE event 127 * once the audio source is available again. 128 */ 129 uint32_t sampleRate; 130 131 /** 132 * The minimum amount of time that this audio source can be buffered, in 133 * nanoseconds. Audio data is delivered to nanoapps in buffers. This specifies 134 * the minimum amount of data that can be delivered to a nanoapp without 135 * losing data. A request for a buffer that is smaller than this will fail. 136 */ 137 uint64_t minBufferDuration; 138 139 /** 140 * The maximum amount of time that this audio source can be buffered, in 141 * nanoseconds. Audio data is delivered to nanoapps in buffers. This specifies 142 * the maximum amount of data that can be stored by the system in one event 143 * without losing data. A request for a buffer that is larger than this will 144 * fail. 145 */ 146 uint64_t maxBufferDuration; 147 148 /** 149 * The format for data provided to the nanoapp. This will be assigned to one 150 * of the enum chreAudioDataFormat values. 151 */ 152 uint8_t format; 153 }; 154 155 /** 156 * The current status of an audio source. 157 */ 158 struct chreAudioSourceStatus { 159 /** 160 * Set to true if the audio source is currently enabled by this nanoapp. If 161 * this struct is provided by a CHRE_EVENT_AUDIO_SAMPLING_CHANGE event, it 162 * must necessarily be set to true because sampling change events are only 163 * sent for sources which this nanoapp has actively subscribed to. If this 164 * struct is obtained from the chreAudioGetStatus API, it may be set to true 165 * or false depending on if audio is currently enabled. 166 */ 167 bool enabled; 168 169 /** 170 * Set to true if the audio source is currently suspended and no audio data 171 * will be received from this source. 172 */ 173 bool suspended; 174 }; 175 176 /** 177 * The nanoappHandleEvent argument for CHRE_EVENT_AUDIO_SAMPLING_CHANGE. 178 */ 179 struct chreAudioSourceStatusEvent { 180 /** 181 * The audio source which has completed a status change. 182 */ 183 uint32_t handle; 184 185 /** 186 * The status of this audio source. 187 */ 188 struct chreAudioSourceStatus status; 189 }; 190 191 /** 192 * The nanoappHandleEvent argument for CHRE_EVENT_AUDIO_DATA. 193 * 194 * One example of the sequence of events for a nanoapp to receive audio data is: 195 * 196 * 1. CHRE_EVENT_AUDIO_SAMPLING_CHANGE - Indicates that audio data is not 197 * suspended. 198 * 2. CHRE_EVENT_AUDIO_DATA - One buffer of audio samples. Potentially repeated. 199 * 3. CHRE_EVENT_AUDIO_SAMPLING_CHANGE - Indicates that audio data has suspended 200 * which indicates a gap in the audio. 201 * 4. CHRE_EVENT_AUDIO_SAMPLING_CHANGE - Indicates that audio data has resumed 202 * and that audio data may be delivered 203 * again if enough samples are buffered. 204 * 5. CHRE_EVENT_AUDIO_DATA - One buffer of audio samples. Potentially repeated. 205 * The nanoapp must tolerate a gap in the timestamps. 206 * 207 * This process repeats for as long as an active request is made for an audio 208 * source. A CHRE_EVENT_AUDIO_SAMPLING_CHANGE does not guarantee that the next 209 * event will be a CHRE_EVENT_AUDIO_DATA event when suspended is set to false. 210 * It may happen that the audio source is suspended before a complete buffer can 211 * be captured. This will cause another CHRE_EVENT_AUDIO_SAMPLING_CHANGE event 212 * to be dispatched with suspended set to true before a buffer is delivered. 213 * 214 * Audio events must be delivered to a nanoapp in order. 215 */ 216 struct chreAudioDataEvent { 217 /** 218 * Indicates the version of the structure, for compatibility purposes. Clients 219 * do not normally need to worry about this field; the CHRE implementation 220 * guarantees that the client only receives the structure version it expects. 221 */ 222 uint8_t version; 223 224 /** 225 * Additional bytes reserved for future use; must be set to 0. 226 */ 227 uint8_t reserved[3]; 228 229 /** 230 * The handle for which this audio data originated from. 231 */ 232 uint32_t handle; 233 234 /** 235 * The base timestamp for this buffer of audio data, from the same time base 236 * as chreGetTime() (in nanoseconds). The audio API does not provide 237 * timestamps for each audio sample. This timestamp corresponds to the first 238 * sample of the buffer. Even though the value is expressed in nanoseconds, 239 * there is an expectation that the sample clock may drift and nanosecond 240 * level accuracy may not be possible. The goal is to be as accurate as 241 * possible within reasonable limitations of a given system. 242 */ 243 uint64_t timestamp; 244 245 /** 246 * The sample rate for this buffer of data in hertz, rounded to the nearest 247 * integer. Fractional sampling rates are not supported. Typical values might 248 * include 16000, 44100 and 48000. 249 */ 250 uint32_t sampleRate; 251 252 /** 253 * The number of samples provided with this buffer. 254 */ 255 uint32_t sampleCount; 256 257 /** 258 * The format of this audio data. This enumeration and union of pointers below 259 * form a tagged struct. The consumer of this API must use this enum to 260 * determine which samples pointer below to dereference. This will be assigned 261 * to one of the enum chreAudioDataFormat values. 262 */ 263 uint8_t format; 264 265 /** 266 * A union of pointers to various formats of sample data. These correspond to 267 * the valid chreAudioDataFormat values. 268 */ 269 union { 270 const uint8_t *samplesULaw8; 271 const int16_t *samplesS16; 272 }; 273 }; 274 275 /** 276 * Retrieves information about an audio source supported by the current CHRE 277 * implementation. The source returned by the runtime must not change for the 278 * entire lifecycle of the Nanoapp and hot-pluggable audio sources are not 279 * supported. 280 * 281 * A simple example of iterating all available audio sources is provided here: 282 * 283 * struct chreAudioSource audioSource; 284 * for (uint32_t i = 0; chreAudioGetSource(i, &audioSource); i++) { 285 * chreLog(CHRE_LOG_INFO, "Found audio source: %s", audioSource.name); 286 * } 287 * 288 * Handles provided to this API must be a stable value for the entire duration 289 * of a nanoapp. Handles for all audio sources must be zero-indexed and 290 * contiguous. The following are examples of handles that could be provided to 291 * this API: 292 * 293 * Valid: 0 294 * Valid: 0, 1, 2, 3 295 * Invalid: 1, 2, 3 296 * Invalid: 0, 2 297 * 298 * @param handle The handle for an audio source to obtain details for. The 299 * range of acceptable handles must be zero-indexed and contiguous. 300 * @param audioSource A struct to populate with details of the audio source. 301 * @return true if the query was successful, false if the provided handle is 302 * invalid or the supplied audioSource is NULL. 303 * 304 * @since v1.2 305 */ 306 bool chreAudioGetSource(uint32_t handle, struct chreAudioSource *audioSource); 307 308 /** 309 * Nanoapps must define CHRE_NANOAPP_USES_AUDIO somewhere in their build 310 * system (e.g. Makefile) if the nanoapp needs to use the following audio APIs. 311 * In addition to allowing access to these APIs, defining this macro will also 312 * ensure CHRE enforces that all host clients this nanoapp talks to have the 313 * required Android permissions needed to listen to audio data by adding 314 * metadata to the nanoapp. 315 */ 316 #if defined(CHRE_NANOAPP_USES_AUDIO) || !defined(CHRE_IS_NANOAPP_BUILD) 317 318 /** 319 * Configures delivery of audio data to the current nanoapp. Note that this may 320 * not fully disable the audio source if it is used by other clients in the 321 * system but it will halt data delivery to the nanoapp. 322 * 323 * The bufferDuration and deliveryInterval parameters as described below are 324 * used together to determine both how much and how often to deliver data to a 325 * nanoapp, respectively. A nanoapp will always be provided the requested 326 * amount of data at the requested interval, even if another nanoapp in CHRE 327 * requests larger/more frequent buffers or smaller/less frequent buffers. 328 * These two buffering parameters allow describing the duty cycle of captured 329 * audio data. If a nanoapp wishes to receive all available audio data, it will 330 * specify a bufferDuration and deliveryInterval that are equal. A 50% duty 331 * cycle would be achieved by specifying a deliveryInterval that is double the 332 * value of the bufferDuration provided. These parameters allow the audio 333 * subsystem to operate at less than 100% duty cycle and permits use of 334 * incomplete audio data without periodic reconfiguration of the source. 335 * 336 * Two examples are illustrated below: 337 * 338 * Target duty cycle: 50% 339 * bufferDuration: 2 340 * deliveryInterval: 4 341 * 342 * Time 0 1 2 3 4 5 6 7 343 * Batch A B 344 * Sample -- -- a1 a2 -- -- b1 b2 345 * Duration [ ] [ ] 346 * Interval [ ] [ ] 347 * 348 * 349 * Target duty cycle: 100% 350 * bufferDuration: 4 351 * deliveryInterval: 4 352 * 353 * Time 0 1 2 3 4 5 6 7 354 * Batch A B 355 * Sample a1 a2 a3 a4 b1 b2 b3 b4 356 * Duration [ ] [ ] 357 * Interval [ ] [ ] 358 * 359 * 360 * This is expected to reduce power overall. 361 * 362 * The first audio buffer supplied to the nanoapp may contain data captured 363 * prior to the request. This could happen if the microphone was already enabled 364 * and reading into a buffer prior to the nanoapp requesting audio data for 365 * itself. The nanoapp must tolerate this. 366 * 367 * It is important to note that multiple logical audio sources (e.g. different 368 * sample rate, format, etc.) may map to one physical audio source. It is 369 * possible for a nanoapp to request audio data from more than one logical 370 * source at a time. Audio data may be suspended for either the current or other 371 * requests. The CHRE_EVENT_AUDIO_SAMPLING_CHANGE will be posted to all clients 372 * if such a change occurs. It is also possible for the request to succeed and 373 * all audio sources are serviced simultaneously. This is implementation defined 374 * but at least one audio source must function correctly if it is advertised, 375 * under normal conditions (e.g. not required for some other system function, 376 * such as hotword). 377 * 378 * @param handle The handle for this audio source. The handle for the desired 379 * audio source can be determined using chreAudioGetSource(). 380 * @param enable true if enabling the source, false otherwise. When passed as 381 * false, the bufferDuration and deliveryInterval parameters are ignored. 382 * @param bufferDuration The amount of time to capture audio samples from this 383 * audio source, in nanoseconds per delivery interval. This value must be 384 * in the range of minBufferDuration/maxBufferDuration for this source or 385 * the request will fail. The number of samples captured per buffer will be 386 * derived from the sample rate of the source and the requested duration and 387 * rounded down to the nearest sample boundary. 388 * @param deliveryInterval Desired time between each CHRE_EVENT_AUDIO_DATA 389 * event. This allows specifying the complete duty cycle of a request 390 * for audio data, in nanoseconds. This value must be greater than or equal 391 * to bufferDuration or the request will fail due to an invalid 392 * configuration. 393 * @return true if the configuration was successful, false if invalid parameters 394 * were provided (non-existent handle, invalid buffering configuration). 395 * 396 * @since v1.2 397 * @note Requires audio permission 398 */ 399 bool chreAudioConfigureSource(uint32_t handle, bool enable, 400 uint64_t bufferDuration, 401 uint64_t deliveryInterval); 402 403 /** 404 * Gets the current chreAudioSourceStatus struct for a given audio handle. 405 * 406 * @param handle The handle for the audio source to query. The provided handle 407 * is obtained from a chreAudioSource which is requested from the 408 * chreAudioGetSource API. 409 * @param status The current status of the supplied audio source. 410 * @return true if the provided handle is valid and the status was obtained 411 * successfully, false if the handle was invalid or status is NULL. 412 * 413 * @since v1.2 414 * @note Requires audio permission 415 */ 416 bool chreAudioGetStatus(uint32_t handle, struct chreAudioSourceStatus *status); 417 418 #else /* defined(CHRE_NANOAPP_USES_AUDIO) || !defined(CHRE_IS_NANOAPP_BUILD) */ 419 #define CHRE_AUDIO_PERM_ERROR_STRING \ 420 "CHRE_NANOAPP_USES_AUDIO must be defined when building this nanoapp in " \ 421 "order to refer to " 422 #define chreAudioConfigureSource(...) \ 423 CHRE_BUILD_ERROR(CHRE_AUDIO_PERM_ERROR_STRING "chreAudioConfigureSource") 424 #define chreAudioGetStatus(...) \ 425 CHRE_BUILD_ERROR(CHRE_AUDIO_PERM_ERROR_STRING "chreAudioGetStatus") 426 #endif /* defined(CHRE_NANOAPP_USES_AUDIO) || !defined(CHRE_IS_NANOAPP_BUILD) */ 427 428 #ifdef __cplusplus 429 } 430 #endif 431 432 #endif /* _CHRE_AUDIO_H_ */ 433