This PR updates two dependency libraries to their latest versions: ## espressif/button: v3.5.0 to v4.1.5 [Version 4](https://components.espressif.com/components/espressif/button/versions/4.1.5/changelog?language=en) changed the API. This code makes use of the new API, with no change to the existing behavior. ## chmorgan/esp-audio-player: v1.0.7 to v1.1.0 [Version 1.1.0](https://github.com/chmorgan/esp-audio-player/releases/tag/v1.1.0) introduces the possibility of multiple simultaneous audio streams. This feature is as yet unused by KTag. Co-authored-by: Joe Kearney <joe@clubk.club> Reviewed-on: #16
188 lines
5.1 KiB
C
188 lines
5.1 KiB
C
/**
|
|
* @file audio_stream.h
|
|
* @brief Stream API — create/delete logical playback streams and control them.
|
|
* These streams own their decode task and submit PCM to the mixer.
|
|
*/
|
|
#pragma once
|
|
|
|
#include "audio_player.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct audio_stream;
|
|
/**
|
|
* @brief Audio stream handle
|
|
*/
|
|
typedef struct audio_stream* audio_stream_handle_t;
|
|
|
|
/**
|
|
* @brief Macro to check if a stream handle is valid
|
|
*/
|
|
#define CHECK_STREAM(s) \
|
|
ESP_RETURN_ON_FALSE(s != NULL, ESP_ERR_INVALID_ARG, "audio_stream", "stream is NULL")
|
|
|
|
/**
|
|
* @brief Audio stream types
|
|
*/
|
|
typedef enum {
|
|
AUDIO_STREAM_TYPE_UNKNOWN = 0, /**< Unknown stream type */
|
|
AUDIO_STREAM_TYPE_DECODER, /**< Stream that decodes audio (e.g., MP3, WAV) */
|
|
AUDIO_STREAM_TYPE_RAW /**< Stream that accepts raw PCM data */
|
|
} audio_stream_type_t;
|
|
|
|
/**
|
|
* @brief Configuration structure for an audio stream
|
|
*/
|
|
typedef struct {
|
|
audio_stream_type_t type; /**< Type of stream */
|
|
char name[16]; /**< Optional: Name of the stream (e.g. "sfx", "bgm"). Auto-generated if empty. */
|
|
UBaseType_t priority; /**< FreeRTOS task priority for the stream's decoder task (if applicable) */
|
|
BaseType_t coreID; /**< ESP32 core ID for the stream's decoder task (if applicable) */
|
|
} audio_stream_config_t;
|
|
|
|
/**
|
|
* @brief Default configuration for an audio decoder stream
|
|
*
|
|
* @param _name Name of the stream
|
|
*/
|
|
#define DEFAULT_AUDIO_STREAM_CONFIG(_name) { \
|
|
.type = AUDIO_STREAM_TYPE_DECODER, \
|
|
.name = _name, \
|
|
.priority = tskIDLE_PRIORITY + 1, \
|
|
.coreID = tskNO_AFFINITY \
|
|
}
|
|
|
|
/**
|
|
* @brief Get the current state of a stream
|
|
*
|
|
* @param h Handle of the stream
|
|
* @return Current audio_player_state_t of the stream
|
|
*/
|
|
audio_player_state_t audio_stream_get_state(audio_stream_handle_t h);
|
|
|
|
/**
|
|
* @brief Get the type of a stream
|
|
*
|
|
* @param h Handle of the stream
|
|
* @return audio_stream_type_t of the stream
|
|
*/
|
|
audio_stream_type_t audio_stream_get_type(audio_stream_handle_t h);
|
|
|
|
/**
|
|
* @brief Play an audio file on a stream
|
|
*
|
|
* Only supported for DECODER type streams.
|
|
*
|
|
* @param h Handle of the stream
|
|
* @param fp File pointer to the audio file
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
|
* - Others: Fail
|
|
*/
|
|
esp_err_t audio_stream_play(audio_stream_handle_t h, FILE *fp);
|
|
|
|
/**
|
|
* @brief Queue an audio file to be played on a stream
|
|
*
|
|
* Only supported for DECODER type streams.
|
|
*
|
|
* @param h Handle of the stream
|
|
* @param fp File pointer to the audio file
|
|
* @param play_now If true, start playing immediately (interrupting current playback)
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
|
* - Others: Fail
|
|
*/
|
|
esp_err_t audio_stream_queue(audio_stream_handle_t h, FILE *fp, bool play_now);
|
|
|
|
/**
|
|
* @brief Stop playback on a stream
|
|
*
|
|
* @param h Handle of the stream
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - Others: Fail
|
|
*/
|
|
esp_err_t audio_stream_stop(audio_stream_handle_t h);
|
|
|
|
/**
|
|
* @brief Pause playback on a stream
|
|
*
|
|
* Only supported for DECODER type streams.
|
|
*
|
|
* @param h Handle of the stream
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
|
* - Others: Fail
|
|
*/
|
|
esp_err_t audio_stream_pause(audio_stream_handle_t h);
|
|
|
|
/**
|
|
* @brief Resume playback on a stream
|
|
*
|
|
* Only supported for DECODER type streams.
|
|
*
|
|
* @param h Handle of the stream
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - ESP_ERR_NOT_SUPPORTED: Stream is not a decoder stream
|
|
* - Others: Fail
|
|
*/
|
|
esp_err_t audio_stream_resume(audio_stream_handle_t h);
|
|
|
|
/**
|
|
* @brief Direct write raw PCM data to a stream
|
|
*
|
|
* Only supported for RAW type streams.
|
|
* Data format must match the mixer configuration (e.g. 44.1kHz, 16-bit, mono/stereo).
|
|
*
|
|
* @param h Handle of the stream
|
|
* @param data Pointer to the PCM data
|
|
* @param size Size of the data in bytes
|
|
* @param timeout_ms Timeout in milliseconds to wait for space in the stream's buffer
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - ESP_ERR_NOT_SUPPORTED: Stream is not a raw stream
|
|
* - Others: Fail
|
|
*/
|
|
esp_err_t audio_stream_write_pcm(audio_stream_handle_t h, void *data, size_t size, uint32_t timeout_ms);
|
|
|
|
/**
|
|
* @brief Send an event to a raw stream's callback
|
|
*
|
|
* Allows manual state management for raw streams.
|
|
*
|
|
* @param h Handle of the stream
|
|
* @param event Event to send
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - ESP_ERR_NOT_SUPPORTED: Stream is not a raw stream
|
|
*/
|
|
esp_err_t audio_stream_raw_send_event(audio_stream_handle_t h, audio_player_callback_event_t event);
|
|
|
|
/**
|
|
* @brief Create a new audio stream
|
|
*
|
|
* @param cfg Pointer to the stream configuration structure
|
|
* @return Handle to the new stream, or NULL if failed
|
|
*/
|
|
audio_stream_handle_t audio_stream_new(audio_stream_config_t *cfg);
|
|
|
|
/**
|
|
* @brief Delete an audio stream and free its resources
|
|
*
|
|
* @param h Handle of the stream to delete
|
|
* @return
|
|
* - ESP_OK: Success
|
|
* - Others: Fail
|
|
*/
|
|
esp_err_t audio_stream_delete(audio_stream_handle_t h);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|