[sendspin] Use sendspin-cpp to v0.4.0 to reduce stuttering (#16178)

This commit is contained in:
Kevin Ahrendt
2026-04-30 21:43:24 -04:00
committed by GitHub
parent 9999913d07
commit faa61696e0
4 changed files with 32 additions and 5 deletions
+26 -4
View File
@@ -24,6 +24,7 @@ CONF_SENDSPIN_ID = "sendspin_id"
CONF_INITIAL_STATIC_DELAY = "initial_static_delay"
CONF_FIXED_DELAY = "fixed_delay"
CONF_DECODE_MEMORY = "decode_memory"
# sendspin-cpp library lives in the global `sendspin` namespace.
sendspin_library_ns = cg.global_ns.namespace("sendspin")
@@ -39,6 +40,18 @@ CODEC_FORMAT_UNSUPPORTED = SendspinCodecFormat.enum("UNSUPPORTED")
AudioSupportedFormatObject = sendspin_library_ns.struct("AudioSupportedFormatObject")
PlayerRoleConfig = sendspin_library_ns.struct("PlayerRoleConfig")
# MemoryLocation enum (from sendspin/types.h) controls SPIRAM-vs-internal-RAM placement
# preference for the player role's transfer buffers.
SendspinMemoryLocation = sendspin_library_ns.enum("MemoryLocation", is_class=True)
MEMORY_PSRAM = "psram"
MEMORY_INTERNAL = "internal"
MEMORY_LOCATIONS = [MEMORY_PSRAM, MEMORY_INTERNAL]
MEMORY_LOCATION_ENUM = {
MEMORY_PSRAM: SendspinMemoryLocation.PREFER_EXTERNAL,
MEMORY_INTERNAL: SendspinMemoryLocation.PREFER_INTERNAL,
}
# Trailing underscore avoids clashing with sendspin-cpp's global `sendspin` namespace.
# Analysis tools strip the trailing underscore (same pattern as `template_`).
sendspin_ns = cg.esphome_ns.namespace("sendspin_")
@@ -193,7 +206,7 @@ async def to_code(config: ConfigType) -> None:
)
# sendspin-cpp library
esp32.add_idf_component(name="sendspin/sendspin-cpp", ref="0.3.1")
esp32.add_idf_component(name="sendspin/sendspin-cpp", ref="0.4.0")
cg.add_define("USE_SENDSPIN", True) # for MDNS
@@ -249,14 +262,23 @@ async def to_code(config: ConfigType) -> None:
"CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY", True
)
player_config_struct = cg.StructInitializer(
PlayerRoleConfig,
# Library defaults: priority 18 (one above httpd_priority 17 so the decoder is not
# starved by the HTTP server during the initial encoded-audio burst at stream start),
# interpolation/decode buffer locations PREFER_EXTERNAL.
player_struct_fields = [
("audio_formats", audio_format_structs),
("audio_buffer_capacity", player_cfg[CONF_BUFFER_SIZE]),
("fixed_delay_us", player_cfg[CONF_FIXED_DELAY]),
("initial_static_delay_ms", player_cfg[CONF_INITIAL_STATIC_DELAY]),
("psram_stack", psram_stack),
("priority", 2),
]
if (decode_memory := player_cfg.get(CONF_DECODE_MEMORY)) is not None:
player_struct_fields.append(
("decode_buffer_location", MEMORY_LOCATION_ENUM[decode_memory])
)
player_config_struct = cg.StructInitializer(
PlayerRoleConfig,
*player_struct_fields,
)
cg.add(var.set_player_config(player_config_struct))
else:
@@ -13,9 +13,11 @@ from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
from .. import (
CONF_DECODE_MEMORY,
CONF_FIXED_DELAY,
CONF_INITIAL_STATIC_DELAY,
CONF_SENDSPIN_ID,
MEMORY_LOCATIONS,
SendspinHub,
_validate_task_stack_in_psram,
register_player_config,
@@ -57,6 +59,7 @@ def _register(config: ConfigType) -> ConfigType:
CONF_INITIAL_STATIC_DELAY: config[CONF_INITIAL_STATIC_DELAY],
CONF_FIXED_DELAY: config[CONF_FIXED_DELAY],
CONF_TASK_STACK_IN_PSRAM: config.get(CONF_TASK_STACK_IN_PSRAM, False),
CONF_DECODE_MEMORY: config.get(CONF_DECODE_MEMORY),
}
)
return config
@@ -82,6 +85,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_SAMPLE_RATE, default=48000): cv.int_range(
min=16000, max=96000
),
cv.Optional(CONF_DECODE_MEMORY): cv.one_of(*MEMORY_LOCATIONS, lower=True),
}
),
cv.only_on_esp32,
+1 -1
View File
@@ -92,6 +92,6 @@ dependencies:
esp32async/asynctcp:
version: 3.4.91
sendspin/sendspin-cpp:
version: 0.3.1
version: 0.4.0
lvgl/lvgl:
version: 9.5.0
@@ -7,3 +7,4 @@ media_source:
initial_static_delay: 5ms
static_delay_adjustable: true
fixed_delay: 480us
decode_memory: internal