Home | History | Annotate | Download | only in chre
      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  * Configures delivery of audio data to the current nanoapp. Note that this may
    307  * not fully disable the audio source if it is used by other clients in the
    308  * system but it will halt data delivery to the nanoapp.
    309  *
    310  * The bufferDuration and deliveryInterval parameters as described below are
    311  * used together to determine both how much and how often to deliver data to a
    312  * nanoapp, respectively. A nanoapp will always be provided the requested
    313  * amount of data at the requested interval, even if another nanoapp in CHRE
    314  * requests larger/more frequent buffers or smaller/less frequent buffers.
    315  * These two buffering parameters allow describing the duty cycle of captured
    316  * audio data. If a nanoapp wishes to receive all available audio data, it will
    317  * specify a bufferDuration and deliveryInterval that are equal. A 50% duty
    318  * cycle would be achieved by specifying a deliveryInterval that is double the
    319  * value of the bufferDuration provided. These parameters allow the audio
    320  * subsystem to operate at less than 100% duty cycle and permits use of
    321  * incomplete audio data without periodic reconfiguration of the source.
    322  *
    323  * Two examples are illustrated below:
    324  *
    325  * Target duty cycle: 50%
    326  * bufferDuration:    2
    327  * deliveryInterval:  4
    328  *
    329  * Time       0   1   2   3   4   5   6   7
    330  * Batch                  A               B
    331  * Sample    --  --  a1  a2  --  --  b1  b2
    332  * Duration          [    ]          [    ]
    333  * Interval  [            ]  [            ]
    334  *
    335  *
    336  * Target duty cycle: 100%
    337  * bufferDuration:    4
    338  * deliveryInterval:  4
    339  *
    340  * Time       0   1   2   3   4   5   6   7
    341  * Batch                  A               B
    342  * Sample    a1  a2  a3  a4  b1  b2  b3  b4
    343  * Duration  [            ]  [            ]
    344  * Interval  [            ]  [            ]
    345  *
    346  *
    347  * This is expected to reduce power overall.
    348  *
    349  * The first audio buffer supplied to the nanoapp may contain data captured
    350  * prior to the request. This could happen if the microphone was already enabled
    351  * and reading into a buffer prior to the nanoapp requesting audio data for
    352  * itself. The nanoapp must tolerate this.
    353  *
    354  * It is important to note that multiple logical audio sources (e.g. different
    355  * sample rate, format, etc.) may map to one physical audio source. It is
    356  * possible for a nanoapp to request audio data from more than one logical
    357  * source at a time. Audio data may be suspended for either the current or other
    358  * requests. The CHRE_EVENT_AUDIO_SAMPLING_CHANGE will be posted to all clients
    359  * if such a change occurs. It is also possible for the request to succeed and
    360  * all audio sources are serviced simultaneously. This is implementation defined
    361  * but at least one audio source must function correctly if it is advertised,
    362  * under normal conditions (e.g. not required for some other system function,
    363  * such as hotword).
    364  *
    365  * @param handle The handle for this audio source. The handle for the desired
    366  *     audio source can be determined using chreAudioGetSource().
    367  * @param enable true if enabling the source, false otherwise. When passed as
    368  *     false, the bufferDuration and deliveryInterval parameters are ignored.
    369  * @param bufferDuration The amount of time to capture audio samples from this
    370  *     audio source, in nanoseconds per delivery interval. This value must be
    371  *     in the range of minBufferDuration/maxBufferDuration for this source or
    372  *     the request will fail. The number of samples captured per buffer will be
    373  *     derived from the sample rate of the source and the requested duration and
    374  *     rounded down to the nearest sample boundary.
    375  * @param deliveryInterval Desired time between each CHRE_EVENT_AUDIO_DATA
    376  *     event. This allows specifying the commplete duty cycle of a request
    377  *     for audio data, in nanoseconds. This value must be greater than or equal
    378  *     to bufferDuration or the request will fail due to an invalid
    379  *     configuration.
    380  * @return true if the configuration was successful, false if invalid parameters
    381  *     were provided (non-existent handle, invalid buffering configuration).
    382  *
    383  * @since v1.2
    384  */
    385 bool chreAudioConfigureSource(uint32_t handle, bool enable,
    386                               uint64_t bufferDuration,
    387                               uint64_t deliveryInterval);
    388 
    389 /**
    390  * Gets the current chreAudioSourceStatus struct for a given audio handle.
    391  *
    392  * @param handle The handle for the audio source to query. The provided handle
    393  *     is obtained from a chreAudioSource which is requested from the
    394  *     chreAudioGetSource API.
    395  * @param status The current status of the supplied audio source.
    396  * @return true if the provided handle is valid and the status was obtained
    397  *     successfully, false if the handle was invalid or status is NULL.
    398  *
    399  * @since v1.2
    400  */
    401 bool chreAudioGetStatus(uint32_t handle, struct chreAudioSourceStatus *status);
    402 
    403 #ifdef __cplusplus
    404 }
    405 #endif
    406 
    407 #endif  /* _CHRE_AUDIO_H_ */
    408