Implement a demo mode
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# frontend/app.py
|
||||
import os
|
||||
import time
|
||||
import streamlit as st
|
||||
import requests
|
||||
from auracast import auracast_config
|
||||
@@ -12,6 +13,13 @@ if 'stream_started' not in st.session_state:
|
||||
# Global: desired packetization time in ms for Opus (should match backend)
|
||||
PTIME = 40
|
||||
BACKEND_URL = "http://localhost:5000"
|
||||
TRANSPORT1 = "auto" #'serial:/dev/ttyAMA3,1000000,rtscts', # transport for raspberry pi gpio header
|
||||
QUALITY_MAP = {
|
||||
"High (48kHz)": {"rate": 48000, "octets": 120},
|
||||
"Good (32kHz)": {"rate": 32000, "octets": 80},
|
||||
"Medium (24kHz)": {"rate": 24000, "octets": 60},
|
||||
"Fair (16kHz)": {"rate": 16000, "octets": 40},
|
||||
}
|
||||
|
||||
# Try loading persisted settings from backend
|
||||
saved_settings = {}
|
||||
@@ -25,7 +33,7 @@ except Exception:
|
||||
st.title("🎙️ Auracast Audio Mode Control")
|
||||
|
||||
# Audio mode selection with persisted default
|
||||
options = ["Webapp", "USB"]
|
||||
options = ["Webapp", "USB", "Demo"]
|
||||
saved_audio_mode = saved_settings.get("audio_mode", "Webapp")
|
||||
if saved_audio_mode not in options:
|
||||
saved_audio_mode = "Webapp"
|
||||
@@ -34,18 +42,108 @@ audio_mode = st.selectbox(
|
||||
"Audio Mode",
|
||||
options,
|
||||
index=options.index(saved_audio_mode),
|
||||
help="Select the audio input source. Choose 'Webapp' for browser microphone or 'USB' for a connected hardware device."
|
||||
help="Select the audio input source. Choose 'Webapp' for browser microphone, 'USB' for a connected hardware device, or 'Demo' for a simulated stream."
|
||||
)
|
||||
|
||||
if audio_mode in ["Webapp", "USB"]:
|
||||
# Stream quality selection (now enabled)
|
||||
quality_map = {
|
||||
"High (48kHz)": {"rate": 48000, "octets": 120},
|
||||
"Good (32kHz)": {"rate": 32000, "octets": 80},
|
||||
"Medium (24kHz)": {"rate": 24000, "octets": 60},
|
||||
"Fair (16kHz)": {"rate": 16000, "octets": 40},
|
||||
if audio_mode == "Demo":
|
||||
demo_stream_map = {
|
||||
"1 × 48kHz": {"quality": "High (48kHz)", "streams": 1,},
|
||||
"2 × 24kHz": {"quality": "Medium (24kHz)", "streams": 2,},
|
||||
"3 × 16kHz": {"quality": "Fair (16kHz)", "streams": 3,},
|
||||
}
|
||||
quality_options = list(quality_map.keys())
|
||||
demo_options = list(demo_stream_map.keys())
|
||||
default_demo = demo_options[0]
|
||||
demo_selected = st.selectbox(
|
||||
"Demo Stream Type",
|
||||
demo_options,
|
||||
index=0,
|
||||
help="Select the demo stream configuration."
|
||||
)
|
||||
#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:
|
||||
st.session_state['demo_stream_started'] = False
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
start_demo = st.button("Start Demo Stream")
|
||||
with col2:
|
||||
stop_demo = st.button("Stop Demo Stream")
|
||||
if start_demo:
|
||||
# Always stop any running stream for clean state
|
||||
try:
|
||||
requests.post(f"{BACKEND_URL}/stop_audio").json()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(1)
|
||||
demo_cfg = demo_stream_map[demo_selected]
|
||||
# Octets per frame logic matches quality_map
|
||||
q = QUALITY_MAP[demo_cfg['quality']]
|
||||
|
||||
if demo_cfg['streams'] >= 1:
|
||||
bigs = [
|
||||
auracast_config.AuracastBigConfigDeu(
|
||||
audio_source=f'file:../testdata/wave_particle_5min_de_{int(q["rate"]/1000)}kHz_mono.wav',
|
||||
iso_que_len=32,
|
||||
sampling_frequency=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
)
|
||||
]
|
||||
if demo_cfg['streams'] >= 2:
|
||||
bigs += [
|
||||
auracast_config.AuracastBigConfigEng(
|
||||
audio_source=f'file:../testdata/wave_particle_5min_en_{int(q["rate"]/1000)}kHz_mono.wav',
|
||||
iso_que_len=32,
|
||||
sampling_frequency=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
),
|
||||
]
|
||||
if demo_cfg['streams'] >= 3:
|
||||
bigs += [
|
||||
auracast_config.AuracastBigConfigFra(
|
||||
audio_source=f'file:../testdata/wave_particle_5min_fr_{int(q["rate"]/1000)}kHz_mono.wav',
|
||||
iso_que_len=32,
|
||||
sampling_frequency=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
),
|
||||
]
|
||||
|
||||
config = auracast_config.AuracastConfigGroup(
|
||||
auracast_sampling_rate_hz=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
transport=TRANSPORT1, # transport for raspberry pi gpio header
|
||||
bigs = bigs
|
||||
)
|
||||
|
||||
try:
|
||||
r = requests.post(f"{BACKEND_URL}/init", json=config.model_dump())
|
||||
if r.status_code == 200:
|
||||
st.session_state['demo_stream_started'] = True
|
||||
st.success(f"Demo stream started: {demo_selected}")
|
||||
else:
|
||||
st.session_state['demo_stream_started'] = False
|
||||
st.error(f"Failed to initialize demo: {r.text}")
|
||||
except Exception as e:
|
||||
st.session_state['demo_stream_started'] = False
|
||||
st.error(f"Error: {e}")
|
||||
elif stop_demo:
|
||||
try:
|
||||
r = requests.post(f"{BACKEND_URL}/stop_audio").json()
|
||||
st.session_state['demo_stream_started'] = False
|
||||
if r.get('was_running'):
|
||||
st.info("Demo stream stopped.")
|
||||
else:
|
||||
st.info("Demo stream was not running.")
|
||||
except Exception as e:
|
||||
st.error(f"Error: {e}")
|
||||
elif st.session_state['demo_stream_started']:
|
||||
st.success(f"Demo stream running: {demo_selected}")
|
||||
else:
|
||||
st.info("Demo stream not running.")
|
||||
quality = None # Not used in demo mode
|
||||
else:
|
||||
# Stream quality selection (now enabled)
|
||||
|
||||
quality_options = list(QUALITY_MAP.keys())
|
||||
default_quality = "Medium (24kHz)" if "Medium (24kHz)" in quality_options else quality_options[0]
|
||||
quality = st.selectbox(
|
||||
"Stream Quality (Sampling Rate)",
|
||||
@@ -119,7 +217,7 @@ if audio_mode in ["Webapp", "USB"]:
|
||||
input_device = selected_option.split(":", 1)[0] if ":" in selected_option else selected_option
|
||||
else:
|
||||
input_device = None
|
||||
import time
|
||||
|
||||
start_stream = st.button("Start Auracast")
|
||||
stop_stream = st.button("Stop Auracast")
|
||||
|
||||
@@ -164,13 +262,13 @@ if audio_mode in ["Webapp", "USB"]:
|
||||
st.success("Stream Stopped!")
|
||||
|
||||
# Small pause lets backend fully release audio devices before re-init
|
||||
import time; time.sleep(1)
|
||||
time.sleep(1)
|
||||
# Prepare config using the model (do NOT send qos_config, only relevant fields)
|
||||
q = quality_map[quality]
|
||||
q = QUALITY_MAP[quality]
|
||||
config = auracast_config.AuracastConfigGroup(
|
||||
auracast_sampling_rate_hz=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
transport='serial:/dev/ttyAMA3,1000000,rtscts', # transport for raspberry pi gpio header
|
||||
transport=TRANSPORT1, # transport for raspberry pi gpio header
|
||||
bigs = [
|
||||
auracast_config.AuracastBigConfig(
|
||||
name=stream_name,
|
||||
@@ -254,9 +352,9 @@ if audio_mode in ["Webapp", "USB"]:
|
||||
"""
|
||||
st.components.v1.html(component, height=0)
|
||||
st.session_state['stream_started'] = True
|
||||
else:
|
||||
st.header("Advertised Streams (Cloud Announcements)")
|
||||
st.info("This feature requires backend support to list advertised streams.")
|
||||
#else:
|
||||
# st.header("Advertised Streams (Cloud Announcements)")
|
||||
# st.info("This feature requires backend support to list advertised streams.")
|
||||
# Placeholder for future implementation
|
||||
# Example: r = requests.get(f"{BACKEND_URL}/advertised_streams")
|
||||
# if r.status_code == 200:
|
||||
|
||||
Reference in New Issue
Block a user