TB2026-YDS Firmware
Loading...
Searching...
No Matches
Audio pipeline

Real-time task feeding PCM from a source to an Audio sink interface. More...

Collaboration diagram for Audio pipeline:

Files

file  components/services/audio/pipeline.c
 Audio pipeline task: producer->consumer loop from a PCM source to a selectable sink (wired DAC or Bluetooth).

Enumerations

enum  pipeline_end_reason_t { PIPE_END_EOF , PIPE_END_ERROR , PIPE_END_UNSUPPORTED }
 Why a file playback ended, reported to the track-end callback. More...

Functions

esp_err_t pipeline_init (void)
 Create the pinned audio task and its command queue.
void pipeline_set_track_end_cb (void(*cb)(pipeline_end_reason_t reason))
 Register the callback fired when a file playback ends on its own (EOF or error).
esp_err_t pipeline_play_file (const char *path)
 Play an audio file: decode it to the current sink at the file's own format.
esp_err_t pipeline_pause (void)
 Pause file playback: stop feeding the sink while keeping the stream position.
esp_err_t pipeline_resume (void)
 Resume a playback paused with pipeline_pause(): restart the sink and keep decoding.
void pipeline_set_sink (const audio_sink_t *sink)
 Select the output backend used by the next playback.
esp_err_t pipeline_switch_sink (void)
 Re-route the current playback onto the sink last set by pipeline_set_sink().
void pipeline_get_position (uint32_t *elapsed_ms, uint32_t *total_ms)
 Read a tear-free snapshot of the current playback position.
esp_err_t pipeline_play_tone (uint32_t freq_hz)
 Bring-up/diagnostic: stream a continuous sine to the current sink.
esp_err_t pipeline_stop (void)
 Stop playback and power the output path down. Safe to call when already idle.

Detailed Description

Real-time task feeding PCM from a source to an Audio sink interface.

Enumeration Type Documentation

◆ pipeline_end_reason_t

Why a file playback ended, reported to the track-end callback.

Enumerator
PIPE_END_EOF 

The decoder reached end of file: play the next track.

PIPE_END_ERROR 

Open or decode failed: stop and surface the error.

PIPE_END_UNSUPPORTED 

The active sink refused the file's format (e.g. a non-44.1 kHz file over Bluetooth, which has no resampler): stop and tell the user the track is not playable on this output.

Function Documentation

◆ pipeline_get_position()

void pipeline_get_position ( uint32_t * elapsed_ms,
uint32_t * total_ms )

Read a tear-free snapshot of the current playback position.

Filled from the file being decoded: elapsed_ms advances as PCM frames are played (frozen while paused), total_ms is the track duration (0 if unknown, e.g. a headerless VBR MP3). Both read back 0 when nothing is playing. Safe to call from the UI task while the audio task decodes: each field is an atomic 32-bit word, so no lock is taken.

Parameters
[out]elapsed_msElapsed playback time in ms; may be NULL.
[out]total_msTrack duration in ms, or 0 if unknown; may be NULL.

◆ pipeline_init()

esp_err_t pipeline_init ( void )

Create the pinned audio task and its command queue.

Call once at startup, after sink_i2s_dac_init() (the pipeline drives the wired sink but does not own the I2S bus). Idempotent.

Returns
ESP_OK; ESP_ERR_NO_MEM if the queue or task cannot be created.

◆ pipeline_pause()

esp_err_t pipeline_pause ( void )

Pause file playback: stop feeding the sink while keeping the stream position.

Powers the output path down (no I2S underrun, minimal draw) and leaves the decoder open at its current position; the audio task sleeps until pipeline_resume() or pipeline_stop(). No effect on the diagnostic tone.

Returns
ESP_OK; ESP_ERR_INVALID_STATE if pipeline_init() has not run; ESP_FAIL if full.

◆ pipeline_play_file()

esp_err_t pipeline_play_file ( const char * path)

Play an audio file: decode it to the current sink at the file's own format.

Opens path, reads its real PCM format (44.1k/16, 48k/24, ...) and starts the sink for it, then streams until end of file, pipeline_stop(), or a decode error. The pipeline does NOT set the volume here: the volume service owns the pot->output mapping during playback. On natural end (EOF or error) the track-end callback fires.

Parameters
pathPOSIX path under the SD mount, e.g. "/sdcard/track.mp3".
Returns
ESP_OK; ESP_ERR_INVALID_STATE if pipeline_init() has not run; ESP_ERR_INVALID_ARG if path is NULL or too long; ESP_FAIL if the queue is full.

◆ pipeline_play_tone()

esp_err_t pipeline_play_tone ( uint32_t freq_hz)

Bring-up/diagnostic: stream a continuous sine to the current sink.

Plays until pipeline_stop(). Not part of normal playback; it validates the real-time path (task scheduling, buffering, sink start/write/stop sequencing) with a synthetic source while no file source is available.

Parameters
freq_hzTone frequency, 20..PIPE_FS/2 Hz. The exact tone is rounded to a whole number of samples per period so buffers loop seamlessly.
Returns
ESP_OK; ESP_ERR_INVALID_STATE if pipeline_init() has not run; ESP_ERR_INVALID_ARG if freq_hz is out of range; ESP_FAIL if the queue is full.

◆ pipeline_resume()

esp_err_t pipeline_resume ( void )

Resume a playback paused with pipeline_pause(): restart the sink and keep decoding.

Returns
ESP_OK; ESP_ERR_INVALID_STATE if pipeline_init() has not run; ESP_FAIL if full.

◆ pipeline_set_sink()

void pipeline_set_sink ( const audio_sink_t * sink)

Select the output backend used by the next playback.

Defaults to the wired DAC (set in pipeline_init). Pass sink_bluetooth_get() to route audio to a connected speaker, or sink_i2s_dac_get() for the jack. Takes effect on the next playback; changing it mid-playback does not interrupt the current tone.

Parameters
sinkSink vtable to use; ignored if NULL.

◆ pipeline_set_track_end_cb()

void pipeline_set_track_end_cb ( void(* cb )(pipeline_end_reason_t reason))

Register the callback fired when a file playback ends on its own (EOF or error).

The transport service (player) registers this to chain to the next track. The callback runs in the audio task's context right after the stream closes, so it must not block; the intended body just picks the next track and calls pipeline_play_file() (which only enqueues a command). A user-initiated pipeline_stop() does NOT fire it.

Parameters
cbCallback, or NULL to clear.

◆ pipeline_stop()

esp_err_t pipeline_stop ( void )

Stop playback and power the output path down. Safe to call when already idle.

Returns
ESP_OK; ESP_ERR_INVALID_STATE if pipeline_init() has not run; ESP_FAIL if the queue is full.

◆ pipeline_switch_sink()

esp_err_t pipeline_switch_sink ( void )

Re-route the current playback onto the sink last set by pipeline_set_sink().

Stops the old sink and starts the new one at the running track's format, keeping the decoder open so playback continues from its current position (no restart, no seek). A no-op unless a file is streaming. If the new sink refuses the format (e.g. a non-44.1 kHz file over Bluetooth) the track-end callback fires with PIPE_END_UNSUPPORTED, as on the play path.

Returns
ESP_OK; ESP_ERR_INVALID_STATE if pipeline_init() has not run; ESP_FAIL if the queue is full.