feat: add QoS controls for presentation delay and retransmission settings
This commit is contained in:
@@ -154,7 +154,7 @@ if audio_mode == "Demo":
|
||||
type=("password"),
|
||||
help="Optional: Set a broadcast code to protect your stream. Leave empty for an open (uncoded) broadcast."
|
||||
)
|
||||
col_flags1, col_flags2, col_placeholder = st.columns([1, 1, 2])
|
||||
col_flags1, col_flags2, col_pdelay, col_rtn = st.columns([1, 1, 1, 1], gap="small")
|
||||
with col_flags1:
|
||||
assisted_listening = st.checkbox(
|
||||
"Assistive listening",
|
||||
@@ -165,6 +165,20 @@ if audio_mode == "Demo":
|
||||
"Immediate rendering",
|
||||
value=bool(saved_settings.get('immediate_rendering', False))
|
||||
)
|
||||
# QoS/presentation controls inline with flags
|
||||
default_pdelay = int(saved_settings.get('presentation_delay_us', 40000) or 40000)
|
||||
with col_pdelay:
|
||||
presentation_delay_us = st.number_input(
|
||||
"Presentation delay (µs)",
|
||||
min_value=10000, max_value=200000, step=1000, value=default_pdelay,
|
||||
help="Delay between capture and presentation for receivers."
|
||||
)
|
||||
default_rtn = int(saved_settings.get('rtn', 4) or 4)
|
||||
with col_rtn:
|
||||
rtn = st.selectbox(
|
||||
"Retransmissions (RTN)", options=[0,1,2,3,4], index=[0,1,2,3,4].index(default_rtn),
|
||||
help="Number of ISO retransmissions (higher improves robustness at cost of airtime)."
|
||||
)
|
||||
#st.info(f"Demo mode selected: {demo_selected} (Streams: {demo_stream_map[demo_selected]['streams']}, Rate: {demo_stream_map[demo_selected]['rate']} Hz)")
|
||||
# Start/Stop buttons for demo mode
|
||||
if 'demo_stream_started' not in st.session_state:
|
||||
@@ -215,9 +229,15 @@ if audio_mode == "Demo":
|
||||
config1 = auracast_config.AuracastConfigGroup(
|
||||
auracast_sampling_rate_hz=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
transport='', # is set in backend
|
||||
transport='', # is set in baccol_qoskend
|
||||
assisted_listening_stream=assisted_listening,
|
||||
immediate_rendering=immediate_rendering,
|
||||
presentation_delay_us=presentation_delay_us,
|
||||
qos_config=auracast_config.AuracastQoSConfig(
|
||||
iso_int_multiple_10ms=1,
|
||||
number_of_retransmissions=int(rtn),
|
||||
max_transport_latency_ms=int(rtn)*10 + 3,
|
||||
),
|
||||
bigs=bigs1
|
||||
)
|
||||
config2 = None
|
||||
@@ -228,6 +248,12 @@ if audio_mode == "Demo":
|
||||
transport='', # is set in backend
|
||||
assisted_listening_stream=assisted_listening,
|
||||
immediate_rendering=immediate_rendering,
|
||||
presentation_delay_us=presentation_delay_us,
|
||||
qos_config=auracast_config.AuracastQoSConfig(
|
||||
iso_int_multiple_10ms=1,
|
||||
number_of_retransmissions=int(rtn),
|
||||
max_transport_latency_ms=int(rtn)*10 + 3,
|
||||
),
|
||||
bigs=bigs2
|
||||
)
|
||||
# Call /init and /init2
|
||||
@@ -306,8 +332,8 @@ else:
|
||||
type="password",
|
||||
help="Optional: Set a broadcast code to protect your stream. Leave empty for an open (uncoded) broadcast."
|
||||
)
|
||||
# Flags: Assistive Listening and Immediate Rendering (one row)
|
||||
col_flags1, col_flags2, col_placeholder = st.columns([1, 1, 2])
|
||||
# Flags and QoS row (compact, four columns)
|
||||
col_flags1, col_flags2, col_pdelay, col_rtn = st.columns([1, 1, 1, 1], gap="small")
|
||||
with col_flags1:
|
||||
assisted_listening = st.checkbox(
|
||||
"Assistive listening",
|
||||
@@ -318,6 +344,20 @@ else:
|
||||
"Immediate rendering",
|
||||
value=bool(saved_settings.get('immediate_rendering', False))
|
||||
)
|
||||
# QoS/presentation controls inline with flags
|
||||
default_pdelay = int(saved_settings.get('presentation_delay_us', 40000) or 40000)
|
||||
with col_pdelay:
|
||||
presentation_delay_us = st.number_input(
|
||||
"Presentation delay (µs)",
|
||||
min_value=10000, max_value=200000, step=1000, value=default_pdelay,
|
||||
help="Delay between capture and presentation for receivers."
|
||||
)
|
||||
default_rtn = int(saved_settings.get('rtn', 4) or 4)
|
||||
with col_rtn:
|
||||
rtn = st.selectbox(
|
||||
"Retransmissions (RTN)", options=[0,1,2,3,4], index=[0,1,2,3,4].index(default_rtn),
|
||||
help="Number of ISO retransmissions (higher improves robustness at cost of airtime)."
|
||||
)
|
||||
# Gain slider for Webapp mode
|
||||
if audio_mode == "Webapp":
|
||||
mic_gain = st.slider("Microphone Gain", 0.0, 2.0, 1.0, 0.1, help="Adjust microphone volume sent to Auracast")
|
||||
@@ -464,7 +504,12 @@ else:
|
||||
transport='', # is set in backend
|
||||
assisted_listening_stream=assisted_listening,
|
||||
immediate_rendering=immediate_rendering,
|
||||
presentation_delay_us=40000,
|
||||
presentation_delay_us=presentation_delay_us,
|
||||
qos_config=auracast_config.AuracastQoSConfig(
|
||||
iso_int_multiple_10ms=1,
|
||||
number_of_retransmissions=int(rtn),
|
||||
max_transport_latency_ms=int(rtn)*10 + 3,
|
||||
),
|
||||
bigs = [
|
||||
auracast_config.AuracastBigConfig(
|
||||
code=(stream_passwort.strip() or None),
|
||||
|
||||
@@ -200,6 +200,10 @@ class StreamerWorker:
|
||||
for big in conf.bigs:
|
||||
big.input_format = f"int16le,{capture_rate},{channels}"
|
||||
|
||||
# Coerce QoS: compute max_transport_latency from RTN if qos_config present
|
||||
if getattr(conf, 'qos_config', None) and getattr(conf.qos_config, 'number_of_retransmissions', None) is not None:
|
||||
conf.qos_config.max_transport_latency_ms = int(conf.qos_config.number_of_retransmissions) * 10 + 3
|
||||
|
||||
# Create and init multicaster1
|
||||
self._multicaster1 = multicast_control.Multicaster(conf, conf.bigs)
|
||||
await reset_nrf54l(1)
|
||||
@@ -219,6 +223,8 @@ class StreamerWorker:
|
||||
'gain': [getattr(big, 'input_gain', 1.0) for big in conf.bigs],
|
||||
'auracast_sampling_rate_hz': conf.auracast_sampling_rate_hz,
|
||||
'octets_per_frame': conf.octets_per_frame,
|
||||
'presentation_delay_us': getattr(conf, 'presentation_delay_us', None),
|
||||
'rtn': getattr(getattr(conf, 'qos_config', None), 'number_of_retransmissions', None),
|
||||
'immediate_rendering': getattr(conf, 'immediate_rendering', False),
|
||||
'assisted_listening_stream': getattr(conf, 'assisted_listening_stream', False),
|
||||
'stream_password': (conf.bigs[0].code if conf.bigs and getattr(conf.bigs[0], 'code', None) else None),
|
||||
@@ -241,6 +247,11 @@ class StreamerWorker:
|
||||
if device_index is None:
|
||||
raise HTTPException(status_code=400, detail=f"Audio device '{device_name}' not found.")
|
||||
big.audio_source = f'device:{device_index}'
|
||||
# Coerce QoS: compute max_transport_latency from RTN if qos_config present
|
||||
if getattr(conf, 'qos_config', None) and getattr(conf.qos_config, 'number_of_retransmissions', None) is not None:
|
||||
conf.qos_config.max_transport_latency_ms = int(conf.qos_config.number_of_retransmissions) * 10 + 3
|
||||
|
||||
|
||||
self._multicaster2 = multicast_control.Multicaster(conf, conf.bigs)
|
||||
await reset_nrf54l(0)
|
||||
await self._multicaster2.init_broadcast()
|
||||
@@ -379,6 +390,8 @@ async def _autostart_from_settings():
|
||||
input_device_name = settings.get('input_device')
|
||||
rate = settings.get('auracast_sampling_rate_hz')
|
||||
octets = settings.get('octets_per_frame')
|
||||
pres_delay = settings.get('presentation_delay_us')
|
||||
saved_rtn = settings.get('rtn')
|
||||
immediate_rendering = settings.get('immediate_rendering', False)
|
||||
assisted_listening_stream = settings.get('assisted_listening_stream', False)
|
||||
channel_names = settings.get('channel_names') or ["Broadcast0"]
|
||||
@@ -442,8 +455,16 @@ async def _autostart_from_settings():
|
||||
transport=TRANSPORT1,
|
||||
immediate_rendering=immediate_rendering,
|
||||
assisted_listening_stream=assisted_listening_stream,
|
||||
presentation_delay_us=pres_delay if pres_delay is not None else 40000,
|
||||
bigs=bigs,
|
||||
)
|
||||
# Attach QoS if saved_rtn present
|
||||
conf.qos_config = auracast_config.AuracastQoSConfig(
|
||||
iso_int_multiple_10ms=1,
|
||||
number_of_retransmissions=int(saved_rtn),
|
||||
max_transport_latency_ms=int(saved_rtn) * 10 + 3,
|
||||
)
|
||||
|
||||
# Initialize and start
|
||||
await asyncio.sleep(0.5)
|
||||
await initialize(conf)
|
||||
|
||||
Reference in New Issue
Block a user