diff --git a/src/auracast/server/multicast_frontend.py b/src/auracast/server/multicast_frontend.py index e6f0d80..90c4e00 100644 --- a/src/auracast/server/multicast_frontend.py +++ b/src/auracast/server/multicast_frontend.py @@ -198,33 +198,64 @@ else: start_stream, stop_stream = render_stream_controls(is_streaming, "Start Auracast", "Stop Auracast", running_mode, secondary_is_streaming) # Analog gain control (only for Analog mode, placed below start button) -analog_gain_db = 0 # default (dB) +analog_gain_db_left = 0 # default (dB) +analog_gain_db_right = 0 # default (dB) if audio_mode == "Analog": - if '_analog_gain_db' not in st.session_state: - saved_analog_gain_db = saved_settings.get('analog_gain_db_left', 0) - st.session_state['_analog_gain_db'] = max(-12, min(18, int(saved_analog_gain_db))) - analog_gain_db = st.slider( - "Analog Input Gain", - min_value=-12, - max_value=18, - key='_analog_gain_db', - step=1, - format="%d dB", - help="ADC gain level for analog inputs (-12 to 18 dB). Default is 0 dB." + if '_analog_gain_db_left' not in st.session_state: + st.session_state['_analog_gain_db_left'] = max(-12, min(18, int(saved_settings.get('analog_gain_db_left', 0)))) + if '_analog_gain_db_right' not in st.session_state: + st.session_state['_analog_gain_db_right'] = max(-12, min(18, int(saved_settings.get('analog_gain_db_right', 0)))) + if '_gain_link_channels' not in st.session_state: + st.session_state['_gain_link_channels'] = True + + link_channels = st.checkbox( + "Link audio channel gain", + key='_gain_link_channels', + help="When enabled, Ch 2 mirrors Ch 1." ) - # Apply gain live while streaming whenever the slider value changes + _gain_col1, _gain_col2 = st.columns(2) + with _gain_col1: + analog_gain_db_left = st.slider( + "Ch 1 Input Gain", + min_value=-12, + max_value=18, + key='_analog_gain_db_left', + step=1, + format="%d dB", + help="ADC gain for channel 1 (-12 to 18 dB). Default is 0 dB." + ) + with _gain_col2: + if link_channels: + st.session_state['_analog_gain_db_right'] = analog_gain_db_left + elif st.session_state.get('_prev_gain_link_channels', True): + # Transition: just unlinked — seed Ch 2 from Ch 1 so it doesn't jump to min + st.session_state['_analog_gain_db_right'] = analog_gain_db_left + st.session_state['_prev_gain_link_channels'] = link_channels + analog_gain_db_right = st.slider( + "Ch 2 Input Gain", + min_value=-12, + max_value=18, + key='_analog_gain_db_right', + step=1, + format="%d dB", + disabled=link_channels, + help="Uncheck 'Link audio channel gain' to adjust Ch 2 independently." if link_channels else "ADC gain for channel 2 (-12 to 18 dB). Default is 0 dB." + ) + # Apply gain live while streaming whenever either slider value changes if is_streaming: - prev_gain = st.session_state.get('_prev_analog_gain_db') - if prev_gain != analog_gain_db: + prev_left = st.session_state.get('_prev_analog_gain_db_left') + prev_right = st.session_state.get('_prev_analog_gain_db_right') + if prev_left != analog_gain_db_left or prev_right != analog_gain_db_right: try: requests.post( f"{BACKEND_URL}/adc_gain", - json={"gain_db_left": analog_gain_db, "gain_db_right": analog_gain_db}, + json={"gain_db_left": analog_gain_db_left, "gain_db_right": analog_gain_db_right}, timeout=1, ) except Exception: pass - st.session_state['_prev_analog_gain_db'] = analog_gain_db + st.session_state['_prev_analog_gain_db_left'] = analog_gain_db_left + st.session_state['_prev_analog_gain_db_right'] = analog_gain_db_right # Audio level monitor (checkbox, not persisted across reloads) show_level_monitor = st.checkbox("Audio level monitor", value=False, disabled=not is_streaming, @@ -682,8 +713,8 @@ else: 'immediate_rendering': immediate_rendering2, 'presentation_delay_ms': presentation_delay_ms2, 'qos_preset': qos_preset2, - 'analog_gain_db_left': analog_gain_db, - 'analog_gain_db_right': analog_gain_db, + 'analog_gain_db_left': analog_gain_db_left, + 'analog_gain_db_right': analog_gain_db_right, } radio1_cfg = { @@ -699,8 +730,8 @@ else: 'presentation_delay_ms': presentation_delay_ms1, 'qos_preset': qos_preset1, 'stereo_mode': stereo_enabled, - 'analog_gain_db_left': analog_gain_db, - 'analog_gain_db_right': analog_gain_db, + 'analog_gain_db_left': analog_gain_db_left, + 'analog_gain_db_right': analog_gain_db_right, } if audio_mode == "Network - Dante":