Compare commits
6 Commits
0.5.3
...
feature/1k
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d8418f670 | |||
| 03d54eaddf | |||
| 5f7fd1c0ff | |||
| f82de89ce3 | |||
| e35b8aa2f9 | |||
| 85532b034c |
@@ -62,7 +62,7 @@ class AuracastBigConfigDeu(AuracastBigConfig):
|
||||
name: str = 'Hörsaal A'
|
||||
language: str ='deu'
|
||||
program_info: str = 'Vorlesung DE'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_de.wav'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_de.lc3'
|
||||
|
||||
class AuracastBigConfigEng(AuracastBigConfig):
|
||||
id: int = 123
|
||||
@@ -70,7 +70,7 @@ class AuracastBigConfigEng(AuracastBigConfig):
|
||||
name: str = 'Lecture Hall A'
|
||||
language: str ='eng'
|
||||
program_info: str = 'Lecture EN'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_en.wav'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_en.lc3'
|
||||
|
||||
class AuracastBigConfigFra(AuracastBigConfig):
|
||||
id: int = 1234
|
||||
@@ -79,7 +79,7 @@ class AuracastBigConfigFra(AuracastBigConfig):
|
||||
name: str = 'Auditoire A'
|
||||
language: str ='fra'
|
||||
program_info: str = 'Auditoire FR'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_fr.wav'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_fr.lc3'
|
||||
|
||||
class AuracastBigConfigSpa(AuracastBigConfig):
|
||||
id: int =12345
|
||||
@@ -87,7 +87,7 @@ class AuracastBigConfigSpa(AuracastBigConfig):
|
||||
name: str = 'Auditorio A'
|
||||
language: str ='spa'
|
||||
program_info: str = 'Auditorio ES'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_es.wav'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_es.lc3'
|
||||
|
||||
class AuracastBigConfigIta(AuracastBigConfig):
|
||||
id: int =1234567
|
||||
@@ -95,7 +95,7 @@ class AuracastBigConfigIta(AuracastBigConfig):
|
||||
name: str = 'Aula A'
|
||||
language: str ='ita'
|
||||
program_info: str = 'Aula IT'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_it.wav'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_it.lc3'
|
||||
|
||||
|
||||
class AuracastBigConfigPol(AuracastBigConfig):
|
||||
@@ -104,7 +104,7 @@ class AuracastBigConfigPol(AuracastBigConfig):
|
||||
name: str = 'Sala Wykładowa'
|
||||
language: str ='pol'
|
||||
program_info: str = 'Sala Wykładowa PL'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_pl.wav'
|
||||
audio_source: str = 'file:./testdata/wave_particle_5min_pl.lc3'
|
||||
|
||||
|
||||
class AuracastConfigGroup(AuracastGlobalConfig):
|
||||
|
||||
@@ -602,6 +602,29 @@ async def init_broadcast(
|
||||
return bigs
|
||||
|
||||
|
||||
def _lc3_file_byte_gen(filename: str, loop: bool = False):
|
||||
"""Stream LC3 frames from disk as individual bytes, with optional looping.
|
||||
|
||||
Yields one byte (int) at a time so it is compatible with the existing
|
||||
``bytes(itertools.islice(gen, bytes_per_frame))`` consumer without loading
|
||||
the whole file into memory.
|
||||
"""
|
||||
while True:
|
||||
with open(filename, 'rb') as f:
|
||||
f.read(18) # skip 18-byte LC3 header
|
||||
while True:
|
||||
size_b = f.read(2)
|
||||
if len(size_b) < 2:
|
||||
break
|
||||
frame_size = struct.unpack('=H', size_b)[0]
|
||||
frame = f.read(frame_size)
|
||||
if len(frame) < frame_size:
|
||||
break
|
||||
yield from frame
|
||||
if not loop:
|
||||
return
|
||||
|
||||
|
||||
class Streamer():
|
||||
"""
|
||||
Streamer class that supports multiple input formats. See bumble for streaming from wav or device
|
||||
@@ -757,13 +780,7 @@ class Streamer():
|
||||
big['precoded'] = True
|
||||
big['lc3_bytes_per_frame'] = global_config.octets_per_frame
|
||||
filename = big_config[i].audio_source.replace('file:', '')
|
||||
|
||||
lc3_bytes = read_lc3_file(filename)
|
||||
lc3_frames = iter(lc3_bytes)
|
||||
|
||||
if big_config[i].loop:
|
||||
lc3_frames = itertools.cycle(lc3_frames)
|
||||
big['lc3_frames'] = lc3_frames
|
||||
big['lc3_frames'] = _lc3_file_byte_gen(filename, loop=big_config[i].loop)
|
||||
|
||||
# use wav files and code them entirely before streaming
|
||||
elif big_config[i].precode_wav and big_config[i].audio_source.endswith('.wav'):
|
||||
@@ -880,6 +897,9 @@ class Streamer():
|
||||
if lc3_frame == b'': # Not all streams may stop at the same time
|
||||
stream_finished[i] = True
|
||||
continue
|
||||
|
||||
for q_idx in range(big.get('num_bis', 1)):
|
||||
await big['iso_queues'][q_idx].write(lc3_frame)
|
||||
else: # code lc3 on the fly with perf counters
|
||||
# Ensure frames generator exists (so we can aclose() on stop)
|
||||
frames_gen = big.get('frames_gen')
|
||||
|
||||
@@ -351,6 +351,17 @@ if audio_mode == "Demo":
|
||||
disabled=is_streaming,
|
||||
help="Select the demo stream configuration."
|
||||
)
|
||||
demo_content_options = ["Program material", "1 kHz test tone"]
|
||||
saved_demo_content = saved_settings.get('demo_content', 'Program material')
|
||||
if saved_demo_content not in demo_content_options:
|
||||
saved_demo_content = 'Program material'
|
||||
demo_content = st.selectbox(
|
||||
"Demo Content",
|
||||
demo_content_options,
|
||||
index=demo_content_options.index(saved_demo_content),
|
||||
disabled=is_streaming,
|
||||
help="Select whether demo streams use program audio files or a continuous 1 kHz test tone."
|
||||
)
|
||||
# Stream password and flags (same as USB/AES67)
|
||||
saved_pwd = saved_settings.get('stream_password', '') or ''
|
||||
stream_passwort = st.text_input(
|
||||
@@ -1537,12 +1548,22 @@ if start_stream:
|
||||
bigs1 = []
|
||||
for i in range(demo_cfg['streams']):
|
||||
cfg_cls, lang = lang_cfgs[i % len(lang_cfgs)]
|
||||
if demo_content == "1 kHz test tone":
|
||||
source_file = f'../testdata/test_tone_1k_{int(q["rate"]/1000)}kHz_mono.lc3'
|
||||
big_kwargs = {
|
||||
'name': 'test tone',
|
||||
'program_info': '1khz',
|
||||
}
|
||||
else:
|
||||
source_file = f'../testdata/wave_particle_5min_{lang}_{int(q["rate"]/1000)}kHz_mono.lc3'
|
||||
big_kwargs = {}
|
||||
bigs1.append(cfg_cls(
|
||||
code=(stream_passwort.strip() or None),
|
||||
audio_source=f'file:../testdata/wave_particle_5min_{lang}_{int(q["rate"]/1000)}kHz_mono.wav',
|
||||
audio_source=f'file:{source_file}',
|
||||
iso_que_len=32,
|
||||
sampling_frequency=q['rate'],
|
||||
octets_per_frame=q['octets'],
|
||||
**big_kwargs,
|
||||
))
|
||||
|
||||
max_per_mc = {48000: 1, 24000: 2, 16000: 3}
|
||||
|
||||
@@ -564,6 +564,13 @@ async def init_radio(transport: str, conf: auracast_config.AuracastConfigGroup,
|
||||
demo_count = sum(1 for big in conf.bigs if isinstance(big.audio_source, str) and big.audio_source.startswith('file:'))
|
||||
demo_rate = int(conf.auracast_sampling_rate_hz or 0)
|
||||
demo_type = None
|
||||
demo_sources = [
|
||||
str(b.audio_source)
|
||||
for b in conf.bigs
|
||||
if isinstance(b.audio_source, str) and b.audio_source.startswith('file:')
|
||||
]
|
||||
is_demo_tone = bool(demo_sources) and all('test_tone_1k_' in src for src in demo_sources)
|
||||
demo_content = '1 kHz test tone' if is_demo_tone else 'Program material'
|
||||
if demo_count > 0 and demo_rate > 0:
|
||||
if demo_rate in (48000, 24000, 16000):
|
||||
demo_type = f"{demo_count} × {demo_rate//1000}kHz"
|
||||
@@ -590,8 +597,9 @@ async def init_radio(transport: str, conf: auracast_config.AuracastConfigGroup,
|
||||
'big_random_addresses': [getattr(big, 'random_address', DEFAULT_RANDOM_ADDRESS) for big in conf.bigs],
|
||||
'demo_total_streams': demo_count,
|
||||
'demo_stream_type': demo_type,
|
||||
'demo_content': demo_content,
|
||||
'is_streaming': auto_started,
|
||||
'demo_sources': [str(b.audio_source) for b in conf.bigs if isinstance(b.audio_source, str) and b.audio_source.startswith('file:')],
|
||||
'demo_sources': demo_sources,
|
||||
}
|
||||
return mc, persisted
|
||||
except HTTPException:
|
||||
|
||||
BIN
src/auracast/testdata/announcement_de.lc3
vendored
Normal file
BIN
src/auracast/testdata/announcement_de.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/announcement_de.wav
vendored
BIN
src/auracast/testdata/announcement_de.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/announcement_en.lc3
vendored
Normal file
BIN
src/auracast/testdata/announcement_en.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/announcement_en.wav
vendored
BIN
src/auracast/testdata/announcement_en.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/announcement_es.lc3
vendored
Normal file
BIN
src/auracast/testdata/announcement_es.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/announcement_es.wav
vendored
BIN
src/auracast/testdata/announcement_es.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/announcement_es_stereo.lc3
vendored
Normal file
BIN
src/auracast/testdata/announcement_es_stereo.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/announcement_es_stereo.wav
vendored
BIN
src/auracast/testdata/announcement_es_stereo.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/announcement_fr.lc3
vendored
Normal file
BIN
src/auracast/testdata/announcement_fr.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/announcement_fr.wav
vendored
BIN
src/auracast/testdata/announcement_fr.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/announcement_it.lc3
vendored
Normal file
BIN
src/auracast/testdata/announcement_it.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/announcement_it.wav
vendored
BIN
src/auracast/testdata/announcement_it.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/test_tone_1k_16kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/test_tone_1k_16kHz_mono.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/test_tone_1k_24kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/test_tone_1k_24kHz_mono.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/test_tone_1k_48kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/test_tone_1k_48kHz_mono.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_de.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_de.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_de.wav
vendored
BIN
src/auracast/testdata/wave_particle_5min_de.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_de_16kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_de_16kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_de_24kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_de_24kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_de_48kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_de_48kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_en.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_en.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_en.wav
vendored
BIN
src/auracast/testdata/wave_particle_5min_en.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_en_16kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_en_16kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_en_24kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_en_24kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_en_48kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_en_48kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_es.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_es.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_es.wav
vendored
BIN
src/auracast/testdata/wave_particle_5min_es.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_es_16kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_es_16kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_es_24kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_es_24kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_es_48kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_es_48kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_fr.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_fr.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_fr.wav
vendored
BIN
src/auracast/testdata/wave_particle_5min_fr.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_fr_16kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_fr_16kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_fr_24kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_fr_24kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_fr_48kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_fr_48kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_it.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_it.lc3
vendored
Normal file
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_it.wav
vendored
BIN
src/auracast/testdata/wave_particle_5min_it.wav
vendored
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_it_16kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_it_16kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_it_24kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_it_24kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_it_48kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_it_48kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_pl_16kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_pl_16kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_pl_24kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_pl_24kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/auracast/testdata/wave_particle_5min_pl_48kHz_mono.lc3
vendored
Normal file
BIN
src/auracast/testdata/wave_particle_5min_pl_48kHz_mono.lc3
vendored
Normal file
Binary file not shown.
Binary file not shown.
@@ -21,12 +21,12 @@ def read_lc3_file(filepath):
|
||||
logging.info('frame_duration %s', frame_duration)
|
||||
logging.info('stream_length %s', stream_length)
|
||||
|
||||
lc3_bytes= b''
|
||||
chunks = []
|
||||
while True:
|
||||
b = f_lc3.read(2)
|
||||
if b == b'':
|
||||
break
|
||||
lc3_frame_size = struct.unpack('=H', b)[0]
|
||||
lc3_bytes += f_lc3.read(lc3_frame_size)
|
||||
chunks.append(f_lc3.read(lc3_frame_size))
|
||||
|
||||
return lc3_bytes
|
||||
return b''.join(chunks)
|
||||
Reference in New Issue
Block a user