Shadowtrance bdb50505e7
Improvements and fixes (#655)
USB Audio Class (UAC) output
Audio codec re-binding
Keyboard / Bluetooth HID
HID Consumer Control (media keys)
Symbol exports
Other fixes
IMU-based screen auto-rotate

See PR for details: https://github.com/TactilityProject/Tactility/pull/655
2026-09-22 19:19:53 +02:00

233 lines
13 KiB
C

/*
* Espressif Modified MIT License
*
* Copyright (c) 2025 Espressif Systems (Shanghai) CO., LTD
*
* Permission is hereby granted for use EXCLUSIVELY with Espressif Systems products.
* This includes the right to use, copy, modify, merge, publish, distribute, and sublicense
* the Software, subject to the following conditions:
*
* 1. This Software MUST BE USED IN CONJUNCTION WITH ESPRESSIF SYSTEMS PRODUCTS.
* 2. The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
* 3. Redistribution of the Software in source or binary form FOR USE WITH NON-ESPRESSIF PRODUCTS
* is strictly prohibited.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* SPDX-License-Identifier: LicenseRef-Espressif-Modified-MIT
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_audio_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Audio simple decoder handle
*
* @note Most audio decoder can only process frame data.
* To support playback simply, simple decoder is imported.
* In simple playback scenario, like play MP3, AAC, WAV etc.
* User need only provide the original audio data, simple decoder will filter out frame data,
* send frame data to decoder, then return decoded data to user directly.
*/
typedef void *esp_audio_simple_dec_handle_t;
/**
* @brief Recovery strategy for tht current frame
*/
typedef enum {
ESP_AUDIO_SIMPLE_DEC_RECOVERY_NONE = 0, /*!< The current frame is a normal decoded frame */
ESP_AUDIO_SIMPLE_DEC_RECOVERY_PLC = 1, /*!< The current frame is recovered through the packet loss concealment (PLC) mechanism */
} esp_audio_simple_dec_recovery_t;
/**
* @brief Audio simple decoder type
*/
typedef enum {
ESP_AUDIO_SIMPLE_DEC_TYPE_NONE = 0, /*!< Invalid simple decoder type */
ESP_AUDIO_SIMPLE_DEC_TYPE_AAC = ESP_AUDIO_TYPE_AAC, /*!< Simple decoder for AAC, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_MP3 = ESP_AUDIO_TYPE_MP3, /*!< Simple decoder for MP3, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_AMRNB = ESP_AUDIO_TYPE_AMRNB, /*!< Simple decoder for AMR-NB, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_AMRWB = ESP_AUDIO_TYPE_AMRWB, /*!< Simple decoder for AMR-WB, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_FLAC = ESP_AUDIO_TYPE_FLAC, /*!< Simple decoder for FLAC, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_WAV = ESP_AUDIO_FOURCC_TO_INT('W', 'A', 'V', ' '), /*!< Simple decoder for WAV, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_M4A = ESP_AUDIO_FOURCC_TO_INT('M', '4', 'A', 'A'), /*!< Simple decoder for M4A, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_TS = ESP_AUDIO_FOURCC_TO_INT('M', '2', 'T', 'S'), /*!< Simple decoder for TS, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_RAW_OPUS = ESP_AUDIO_TYPE_OPUS, /*!< Simple decoder for OPUS (raw data with no extra header),
only supports input data with a size of one encoded frame */
ESP_AUDIO_SIMPLE_DEC_TYPE_G711A = ESP_AUDIO_TYPE_G711A, /*!< Simple decoder for G711A, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_G711U = ESP_AUDIO_TYPE_G711U, /*!< Simple decoder for G711U, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_PCM = ESP_AUDIO_TYPE_PCM, /*!< Simple decoder for PCM, support input data of any size */
ESP_AUDIO_SIMPLE_DEC_TYPE_ADPCM = ESP_AUDIO_TYPE_ADPCM, /*!< Simple decoder for IMA-ADPCM,
only supports input data with a size of one encoded frame */
ESP_AUDIO_SIMPLE_DEC_TYPE_SBC = ESP_AUDIO_TYPE_SBC, /*!< Simple decoder for SBC,
only supports input data with a size of one or multi encoded frame */
ESP_AUDIO_SIMPLE_DEC_TYPE_LC3 = ESP_AUDIO_TYPE_LC3, /*!< Simple decoder for LC3,
in vbr and no len_prefixed case, only supports input data with a size of one encoded frame,
other cases, support input data with a size of one or multi encoded frame */
ESP_AUDIO_SIMPLE_DEC_TYPE_ALAC = ESP_AUDIO_TYPE_ALAC, /*!< Simple decoder for ALAC,
only supports input data with a size of one encoded frame */
ESP_AUDIO_SIMPLE_DEC_TYPE_VORBIS = ESP_AUDIO_TYPE_VORBIS, /*!< Simple decoder for Vorbis (raw data with no extra header),
only supports input data with a size of one encoded frame */
ESP_AUDIO_SIMPLE_DEC_TYPE_CUSTOM = 0x1, /*!< Customized simple decoder type start */
ESP_AUDIO_SIMPLE_DEC_TYPE_CUSTOM_MAX = 0x10, /*!< Customized simple decoder type end */
} esp_audio_simple_dec_type_t;
/**
* @brief Audio simple decoder configuration
*/
typedef struct {
esp_audio_simple_dec_type_t dec_type; /*!< Simple decoder type */
void *dec_cfg; /*!< Decoder specified configuration data (check decoder header file for details)
Ex: When use internal aac decoder can refer `esp_aac_dec.h`
If user want to enable AAC_PLUS can set it to pointer to
`esp_aac_dec_cfg_t` */
int cfg_size; /*!< Decoder specified configuration size */
bool use_frame_dec; /*!< The flag of whether use frame decoder without parse
If set to true, means that the input data is a complete frame and can be decoded directly
If set to false, for decoders with parser, will parse to obtain the complete frame and then decode it */
} esp_audio_simple_dec_cfg_t;
/**
* @brief Input data information to be decoded
*/
typedef struct {
uint8_t *buffer; /*!< Raw data to be decoded */
uint32_t len; /*!< Raw data length */
bool eos; /*!< Whether end of stream (some parser like FLAC need eos flag to flush cached data) */
uint32_t consumed; /*!< Consumed size of input raw data */
esp_audio_simple_dec_recovery_t frame_recover; /*!< Recovery strategy for current frame */
} esp_audio_simple_dec_raw_t;
/**
* @brief Audio simple decoder output frame
*/
typedef struct {
uint8_t *buffer; /*!< Output buffer to hold decoded PCM data */
uint32_t len; /*!< Output buffer size */
uint32_t needed_size; /*!< Set when output buffer size not enough (output) */
uint32_t decoded_size; /*!< Decoded PCM data size (output) */
} esp_audio_simple_dec_out_t;
/**
* @brief Audio simple decoder information
*/
typedef struct {
uint32_t sample_rate; /*!< Audio sample rate */
uint8_t bits_per_sample; /*!< Bits per sample */
uint8_t channel; /*!< Audio channel*/
uint32_t bitrate; /*!< Audio bitrate (bits per second) */
uint32_t frame_size; /*!< Audio frame size */
} esp_audio_simple_dec_info_t;
/**
* @brief Query whether the simple decoder type is supported
*
* @param[in] dec_type Simple decoder type
*
* @return
* - ESP_AUDIO_ERR_OK On success
* - ESP_AUDIO_ERR_NOT_SUPPORT Not support the audio type
*/
esp_audio_err_t esp_audio_simple_check_audio_type(esp_audio_simple_dec_type_t dec_type);
/**
* @brief Open audio simple decoder
*
* @param[in] cfg Decoder configuration
* @param[out] dec_handle Pointer to output simple decoder handle
*
* @return
* - ESP_AUDIO_ERR_OK Open decoder success
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid input argument
* - ESP_AUDIO_ERR_MEM_LACK No memory for decoder instance
* - ESP_AUDIO_ERR_NOT_SUPPORT Not supported parse type
*/
esp_audio_err_t esp_audio_simple_dec_open(esp_audio_simple_dec_cfg_t *cfg, esp_audio_simple_dec_handle_t *dec_handle);
/**
* @brief Decode input raw data to PCM data
*
* @param[in] dec_handle Simple decoder handle
* @param[in,out] raw Raw data to be decoded
* @param[in,out] frame Decoded PCM frame
*
* @return
* - ESP_AUDIO_ERR_OK Decode success or data feed into cached buffer
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid input argument
* - ESP_AUDIO_ERR_BUFF_NOT_ENOUGH Output frame buffer not enough need reallocated and try again
* - ESP_AUDIO_ERR_NOT_SUPPORT Decoder not supported
*/
esp_audio_err_t esp_audio_simple_dec_process(esp_audio_simple_dec_handle_t dec_handle, esp_audio_simple_dec_raw_t *raw,
esp_audio_simple_dec_out_t *frame);
/**
* @brief Get audio simple decoder information
*
* @note Audio decoder information contain 2 parts:
* 1. Basic information which can be used for play (`sample_rate`, `channel`, `bits`)
* This information is ready when decoder decode output PCM data
* When `esp_audio_simple_dec_process` return `decoded_size` have value
* User no need frequently call this API to get it for it almost unchanged
* 2. Frame related information such as (`frame_size`) which may differ for each frame
* User can use it to estimate duration and play position.
*
* @param[in] dec_handle Simple decoder handle
* @param[out] info Decoder information
*
* @return
* - ESP_AUDIO_ERR_OK Open decoder success
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid input argument
* - ESP_AUDIO_ERR_NOT_FOUND Decode information not ready yet
*/
esp_audio_err_t esp_audio_simple_dec_get_info(esp_audio_simple_dec_handle_t dec_handle, esp_audio_simple_dec_info_t *info);
/**
* @brief Reset audio simple decoder
* Reset action will reset both of the internal parser and decoder to initial state
* It allows the handle to be reused efficiently, avoiding the overhead of closing and recreating the handle
* Typical use cases include:
* - Replay the same audio stream
* - Seek when use frame decoder
*
* @note 1. This function is not thread-safe. The user must ensure proper call sequencing
* and avoid invoking this function while the process is running
* 2. Work as a frame decoder: After calling the `esp_audio_simple_dec_reset`, playback can
* start from any frame of the audio stream. The audio file can be the same or different but keeping
* 3. Work as a non-frame decoder: After calling the `esp_audio_simple_dec_reset`,
* playback must starts from the beginning of the audio stream.
* The audio file can be the same or different from the previous one but keeping format unchanged
*
* @param[in] dec_handle Simple decoder handle
*
* @return
* - ESP_AUDIO_ERR_OK On success
* - ESP_AUDIO_ERR_FAIL Fail to reset
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid parameter
*/
esp_audio_err_t esp_audio_simple_dec_reset(esp_audio_simple_dec_handle_t dec_handle);
/**
* @brief Close audio simple decoder
*
* @param[in] dec_handle Decoder handle
*
*/
void esp_audio_simple_dec_close(esp_audio_simple_dec_handle_t dec_handle);
#ifdef __cplusplus
}
#endif