xref: /aosp_15_r20/system/chre/chre_api/include/chre_api/chre/audio.h (revision 84e339476a462649f82315436d70fd732297a399)
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