Adds stereo for analog.
This commit is contained in:
@@ -395,6 +395,14 @@ else:
|
||||
with st.container(border=True):
|
||||
st.subheader("Radio 1")
|
||||
|
||||
# Stereo mode toggle for analog
|
||||
stereo_enabled = st.checkbox(
|
||||
"🎧 Stereo Mode",
|
||||
value=bool(saved_settings.get('analog_stereo_mode', False)),
|
||||
help="Enable stereo streaming for analog inputs. When enabled, ch1 becomes left channel and ch2 becomes right channel in a single stereo stream. Radio 2 will be disabled in stereo mode.",
|
||||
disabled=is_streaming
|
||||
)
|
||||
|
||||
# Always-enabled checkbox for Radio 1
|
||||
st.checkbox(
|
||||
"Radio 1 always enabled",
|
||||
@@ -501,38 +509,69 @@ else:
|
||||
|
||||
if not is_streaming:
|
||||
if analog_names:
|
||||
default_r1_idx = 0
|
||||
input_device1 = st.selectbox(
|
||||
"Input Device (Radio 1)",
|
||||
analog_names,
|
||||
index=default_r1_idx,
|
||||
)
|
||||
if stereo_enabled:
|
||||
# In stereo mode, only show ch1 and automatically select it
|
||||
if 'ch1' in analog_names:
|
||||
input_device1 = 'ch1'
|
||||
st.selectbox(
|
||||
"Input Device (Radio 1) - Stereo",
|
||||
['ch1 + ch2 (Stereo: Left+Right channels)'],
|
||||
index=0,
|
||||
help="Stereo mode: Captures both ch1 (left) and ch2 (right) as a single stereo stream"
|
||||
)
|
||||
st.info("🎧 Stereo mode enabled - both ch1 and ch2 will be captured as left/right channels")
|
||||
else:
|
||||
st.error("ch1 not available for stereo mode")
|
||||
input_device1 = None
|
||||
else:
|
||||
# Mono mode: show all available channels
|
||||
default_r1_idx = 0
|
||||
input_device1 = st.selectbox(
|
||||
"Input Device (Radio 1)",
|
||||
analog_names,
|
||||
index=default_r1_idx,
|
||||
)
|
||||
else:
|
||||
input_device1 = None
|
||||
else:
|
||||
input_device1 = saved_settings.get('input_device')
|
||||
st.selectbox(
|
||||
"Input Device (Radio 1)",
|
||||
[input_device1 or "No device selected"],
|
||||
index=0,
|
||||
disabled=True,
|
||||
help="Stop the stream to change the input device."
|
||||
)
|
||||
if stereo_enabled:
|
||||
st.selectbox(
|
||||
"Input Device (Radio 1) - Stereo",
|
||||
[f"{input_device1 or 'ch1'} (Left+Right channels)" if input_device1 else "No device selected"],
|
||||
index=0,
|
||||
disabled=True,
|
||||
help="Stop the stream to change the input device."
|
||||
)
|
||||
else:
|
||||
st.selectbox(
|
||||
"Input Device (Radio 1)",
|
||||
[input_device1 or "No device selected"],
|
||||
index=0,
|
||||
disabled=True,
|
||||
help="Stop the stream to change the input device."
|
||||
)
|
||||
|
||||
# --- Radio 2 controls ---
|
||||
with st.container(border=True):
|
||||
st.subheader("Radio 2")
|
||||
# If the backend reports that the secondary radio is currently streaming,
|
||||
# initialize the checkbox to checked so the UI reflects the active state
|
||||
# when the frontend is loaded.
|
||||
radio2_enabled_default = secondary_is_streaming
|
||||
radio2_enabled = st.checkbox(
|
||||
"Enable Radio 2",
|
||||
value=radio2_enabled_default,
|
||||
help="Activate a second analog radio with its own quality and timing settings."
|
||||
)
|
||||
|
||||
# Disable Radio 2 in stereo mode
|
||||
if stereo_enabled:
|
||||
st.info("🎧 Radio 2 is automatically disabled in stereo mode")
|
||||
radio2_enabled = False
|
||||
else:
|
||||
# If the backend reports that the secondary radio is currently streaming,
|
||||
# initialize the checkbox to checked so the UI reflects the active state
|
||||
# when the frontend is loaded.
|
||||
radio2_enabled_default = secondary_is_streaming
|
||||
radio2_enabled = st.checkbox(
|
||||
"Enable Radio 2",
|
||||
value=radio2_enabled_default,
|
||||
help="Activate a second analog radio with its own quality and timing settings."
|
||||
)
|
||||
|
||||
if radio2_enabled:
|
||||
if radio2_enabled and not stereo_enabled:
|
||||
# Use analog-specific defaults for Radio 2
|
||||
default_name_r2 = "Analog_Radio_2"
|
||||
default_program_info_r2 = "Analog Radio Broadcast"
|
||||
@@ -644,6 +683,7 @@ else:
|
||||
'immediate_rendering': immediate_rendering1,
|
||||
'presentation_delay_ms': presentation_delay_ms1,
|
||||
'qos_preset': qos_preset1,
|
||||
'stereo_mode': stereo_enabled, # Add stereo mode setting
|
||||
}
|
||||
|
||||
if audio_mode == "Network - Dante":
|
||||
@@ -1258,6 +1298,11 @@ if start_stream:
|
||||
if not cfg or not cfg.get('input_device'):
|
||||
return None
|
||||
q = QUALITY_MAP[cfg['quality']]
|
||||
|
||||
# Determine if this is stereo mode (only applicable for analog)
|
||||
stereo_mode = cfg.get('stereo_mode', False)
|
||||
channels = 2 if stereo_mode else 1
|
||||
|
||||
return auracast_config.AuracastConfigGroup(
|
||||
auracast_sampling_rate_hz=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
@@ -1274,10 +1319,11 @@ if start_stream:
|
||||
program_info=cfg['program_info'],
|
||||
language=cfg['language'],
|
||||
audio_source=f"device:{cfg['input_device']}",
|
||||
input_format=f"int16le,{q['rate']},1",
|
||||
input_format=f"int16le,{q['rate']},{channels}",
|
||||
iso_que_len=1,
|
||||
sampling_frequency=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
num_bis=channels, # 1=mono, 2=stereo - this determines the behavior
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
@@ -359,12 +359,25 @@ async def init_radio(transport: str, conf: auracast_config.AuracastConfigGroup,
|
||||
continue
|
||||
|
||||
if sel in ('ch1', 'ch2'):
|
||||
# Analog channels: mono at 48kHz
|
||||
device_index = resolve_input_device_index(sel)
|
||||
if device_index is None:
|
||||
raise HTTPException(status_code=400, detail=f"Audio device '{sel}' not found.")
|
||||
big.audio_source = f'device:{device_index}'
|
||||
big.input_format = f"int16le,{hardware_capture_rate},1"
|
||||
# Analog channels: check if this should be stereo based on num_bis
|
||||
is_stereo = getattr(big, 'num_bis', 1) == 2
|
||||
|
||||
if is_stereo and sel == 'ch1':
|
||||
# Stereo mode: use ALSA directly to capture both channels from hardware
|
||||
# ch1=left (channel 0), ch2=right (channel 1)
|
||||
big.audio_source = 'alsa:hw:CARD=i2s,DEV=0'
|
||||
big.input_format = f"int16le,{hardware_capture_rate},2"
|
||||
log.info("Configured analog stereo input: using ALSA hw:CARD=i2s,DEV=0 with ch1=left, ch2=right")
|
||||
elif is_stereo and sel == 'ch2':
|
||||
# Skip ch2 in stereo mode as it's already captured as part of stereo pair
|
||||
continue
|
||||
else:
|
||||
# Mono mode: individual channel capture
|
||||
device_index = resolve_input_device_index(sel)
|
||||
if device_index is None:
|
||||
raise HTTPException(status_code=400, detail=f"Audio device '{sel}' not found.")
|
||||
big.audio_source = f'device:{device_index}'
|
||||
big.input_format = f"int16le,{hardware_capture_rate},1"
|
||||
continue
|
||||
|
||||
if sel and sel.isdigit():
|
||||
@@ -456,6 +469,7 @@ async def init_radio(transport: str, conf: auracast_config.AuracastConfigGroup,
|
||||
'qos_preset': _resolve_qos_preset_name(conf.qos_config),
|
||||
'immediate_rendering': getattr(conf, 'immediate_rendering', False),
|
||||
'assisted_listening_stream': getattr(conf, 'assisted_listening_stream', False),
|
||||
'analog_stereo_mode': getattr(conf.bigs[0], 'analog_stereo_mode', False) if conf.bigs else False,
|
||||
'stream_password': (conf.bigs[0].code if conf.bigs and getattr(conf.bigs[0], 'code', None) else None),
|
||||
'big_ids': [getattr(big, 'id', DEFAULT_BIG_ID) for big in conf.bigs],
|
||||
'big_random_addresses': [getattr(big, 'random_address', DEFAULT_RANDOM_ADDRESS) for big in conf.bigs],
|
||||
@@ -643,6 +657,9 @@ async def _autostart_from_settings():
|
||||
presentation_delay_us=pres_delay if pres_delay is not None else 40000,
|
||||
bigs=bigs,
|
||||
)
|
||||
# Set num_bis for stereo mode if needed
|
||||
if conf.bigs and settings.get('analog_stereo_mode', False):
|
||||
conf.bigs[0].num_bis = 2
|
||||
conf.qos_config = QOS_PRESET_MAP.get(saved_qos_preset, QOS_PRESET_MAP["Fast"])
|
||||
log.info("[AUTOSTART][PRIMARY] Scheduling demo init_radio in 2s")
|
||||
await asyncio.sleep(2)
|
||||
@@ -707,6 +724,9 @@ async def _autostart_from_settings():
|
||||
presentation_delay_us=pres_delay if pres_delay is not None else 40000,
|
||||
bigs=bigs,
|
||||
)
|
||||
# Set num_bis for stereo mode if needed
|
||||
if conf.bigs and settings.get('analog_stereo_mode', False):
|
||||
conf.bigs[0].num_bis = 2
|
||||
conf.qos_config = QOS_PRESET_MAP.get(saved_qos_preset, QOS_PRESET_MAP["Fast"])
|
||||
log.info("[AUTOSTART][PRIMARY] Scheduling device init_radio in 2s")
|
||||
await asyncio.sleep(2)
|
||||
|
||||
Reference in New Issue
Block a user