5#if defined(USE_ESP32) && defined(USE_I2S_AUDIO_SPDIF_MODE)
10#include <freertos/FreeRTOS.h>
17static constexpr uint8_t SPDIF_BITS_PER_SAMPLE = 64;
19static constexpr uint16_t SPDIF_BLOCK_SAMPLES = 192;
22static constexpr uint8_t EMULATED_BMC_BITS_PER_SAMPLE = SPDIF_BITS_PER_SAMPLE * 2;
23static constexpr uint16_t SPDIF_BLOCK_SIZE_BYTES = SPDIF_BLOCK_SAMPLES * (EMULATED_BMC_BITS_PER_SAMPLE / 8);
24static constexpr uint32_t SPDIF_BLOCK_SIZE_U32 = SPDIF_BLOCK_SIZE_BYTES /
sizeof(
uint32_t);
26static constexpr uint32_t SPDIF_BLOCK_I2S_FRAMES = SPDIF_BLOCK_SIZE_BYTES / 8;
80 esp_err_t
write(
const uint8_t *src,
size_t size, TickType_t ticks_to_wait,
uint32_t *blocks_sent =
nullptr,
81 size_t *bytes_consumed =
nullptr);
107 template<u
int8_t Bps>
109 size_t *bytes_consumed);
uint32_t * spdif_block_ptr_
std::unique_ptr< uint32_t[]> spdif_block_buf_
bool is_preload_mode() const
Check if currently in preload mode.
esp_err_t send_block_(TickType_t ticks_to_wait)
Send the completed block via the appropriate callback.
uint32_t get_sample_rate() const
Get the currently configured sample rate.
void set_bytes_per_sample(uint8_t bytes_per_sample)
Set input PCM width: 2 = 16-bit, 3 = 24-bit, 4 = 32-bit (truncated to 24-bit on the wire).
std::array< uint8_t, 24 > channel_status_
void * preload_callback_ctx_
esp_err_t write(const uint8_t *src, size_t size, TickType_t ticks_to_wait, uint32_t *blocks_sent=nullptr, size_t *bytes_consumed=nullptr)
Convert PCM audio data to SPDIF BMC encoded data.
uint8_t get_bytes_per_sample() const
Get the configured input PCM width in bytes per sample.
void set_sample_rate(uint32_t sample_rate)
Set the sample rate for Channel Status Block encoding.
void encode_silence_frame_()
Encode a single stereo silence frame at the current block position.
uint8_t bytes_per_sample_
bool block_buf_is_silence_block_
SPDIFBlockCallback write_callback_
esp_err_t flush_with_silence_typed_(TickType_t ticks_to_wait)
Templated flush-with-silence.
SPDIFBlockCallback preload_callback_
void reset()
Reset the SPDIF block buffer and position tracking, discarding any partial block.
void build_channel_status_()
Build the channel status block from current configuration.
HOT esp_err_t write_typed_(const uint8_t *src, size_t size, TickType_t ticks_to_wait, uint32_t *blocks_sent, size_t *bytes_consumed)
Templated write loop. Called from the public write() via runtime dispatch on bytes_per_sample_.
esp_err_t flush_with_silence(TickType_t ticks_to_wait)
Emit one complete SPDIF block: pad any pending partial block with silence and send,...
bool setup()
Initialize the SPDIF working buffer.
void set_write_callback(SPDIFBlockCallback callback, void *user_ctx)
Set callback for normal writes (used when channel is running)
void * write_callback_ctx_
void set_preload_callback(SPDIFBlockCallback callback, void *user_ctx)
Set callback for preload writes (used when preloading to DMA before enabling channel)
void set_preload_mode(bool preload)
Enable or disable preload mode When in preload mode, completed blocks use the preload callback instea...
esp_err_t(*)(void *user_ctx, uint32_t *data, size_t size, TickType_t ticks_to_wait) SPDIFBlockCallback
Callback signature for block completion (raw function pointer for minimal overhead)