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