From 9bf569d317e6fb6add4204576fb5232fa93409c6 Mon Sep 17 00:00:00 2001 From: pstruebi Date: Thu, 6 Feb 2025 12:01:43 +0100 Subject: [PATCH] make dualcast work --- auracast/auracast.py | 4 +-- auracast/auracast_config.py | 2 +- auracast/dualcast.py | 53 ++++++++++++++++++++++++++----------- auracast/multicast.py | 4 +-- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/auracast/auracast.py b/auracast/auracast.py index 2dbcc04..8baa881 100644 --- a/auracast/auracast.py +++ b/auracast/auracast.py @@ -126,7 +126,7 @@ async def run_broadcast( logger.info('Frame rate of .wav file is: %s', wav.getframerate()) encoder = lc3.Encoder( frame_duration_us=global_config.frame_duration_us, - sample_rate_hz=global_config.auracast_sampling_rate_khz, + sample_rate_hz=global_config.auracast_sampling_rate_hz, num_channels=1, input_sample_rate_hz=wav.getframerate(), ) @@ -139,7 +139,7 @@ async def run_broadcast( print('Encoding complete.') # Config advertising set - bap_sampling_freq = getattr(bap.SamplingFrequency, f"FREQ_{global_config.auracast_sampling_rate_khz}") + bap_sampling_freq = getattr(bap.SamplingFrequency, f"FREQ_{global_config.auracast_sampling_rate_hz}") basic_audio_announcement = bap.BasicAudioAnnouncement( presentation_delay=global_config.presentation_delay_us, subgroups=[ diff --git a/auracast/auracast_config.py b/auracast/auracast_config.py index cbfc8e6..fd6ac8c 100644 --- a/auracast/auracast_config.py +++ b/auracast/auracast_config.py @@ -8,7 +8,7 @@ class AuracastGlobalConfig: device_name: str = 'Auracaster' transport: str = '' auracast_device_address: hci.Address = hci.Address('F0:F1:F2:F3:F4:F5') - auracast_sampling_rate_khz: int =24000 + auracast_sampling_rate_hz: int = 24000 octets_per_frame: int = 100 # bitrate = octets_per_frame * 8 / frame len frame_duration_us: int = 10000 presentation_delay_us: int = 40000 diff --git a/auracast/dualcast.py b/auracast/dualcast.py index 66a8af0..ccf9b0a 100644 --- a/auracast/dualcast.py +++ b/auracast/dualcast.py @@ -112,10 +112,13 @@ def run_async(async_command: Coroutine) -> None: color('!!! An error occurred while executing the command:', 'red'), message ) +handle0 = None +handle1 = None + async def run_broadcast( global_config : auracast_config.AuracastGlobalConfig, big_config: List[auracast_config.AuracastBigConfig] - + ) -> None: async with create_device(global_config) as device: if not device.supports_le_periodic_advertising: @@ -128,7 +131,7 @@ async def run_broadcast( logger.info('Frame rate of .wav file is: %s', wav.getframerate()) encoder = lc3.Encoder( frame_duration_us=global_config.frame_duration_us, - sample_rate_hz=global_config.auracast_sampling_rate_khz, + sample_rate_hz=global_config.auracast_sampling_rate_hz, num_channels=1, input_sample_rate_hz=wav.getframerate(), ) @@ -141,7 +144,7 @@ async def run_broadcast( print('Encoding complete.') # Config advertising set - bap_sampling_freq = getattr(bap.SamplingFrequency, f"FREQ_{global_config.auracast_sampling_rate_khz}") + bap_sampling_freq = getattr(bap.SamplingFrequency, f"FREQ_{global_config.auracast_sampling_rate_hz}") basic_audio_announcement0 = bap.BasicAudioAnnouncement( presentation_delay=global_config.presentation_delay_us, subgroups=[ @@ -150,7 +153,7 @@ async def run_broadcast( codec_specific_configuration=bap.CodecSpecificConfiguration( sampling_frequency=bap_sampling_freq, frame_duration=bap.FrameDuration.DURATION_10000_US, - octets_per_codec_frame=global_config.octets_per_frame, + octets_per_codec_frame=global_config.octets_per_frame, ), metadata=le_audio.Metadata( [ @@ -184,7 +187,7 @@ async def run_broadcast( codec_specific_configuration=bap.CodecSpecificConfiguration( sampling_frequency=bap_sampling_freq, frame_duration=bap.FrameDuration.DURATION_10000_US, - octets_per_codec_frame=global_config.octets_per_frame, + octets_per_codec_frame=global_config.octets_per_frame, ), metadata=le_audio.Metadata( [ @@ -321,18 +324,36 @@ async def run_broadcast( direction=bis_link.Direction.HOST_TO_CONTROLLER ) - frames_iterator = itertools.cycle(frames) + frames_iterator0 = itertools.cycle(frames) + frames_iterator1 = itertools.cycle(frames) + frame0 = next(frames_iterator0) + frame1 = next(frames_iterator1) + + # Get the corresponding handles first + logging.info("Determine broadcast handles") + + # Define on packet complete function to get the handle for each broadcast + handle0 = big0.bis_links[0].handle + handle1 = big1.bis_links[0].handle + logging.info("Broadcasting...") def on_packet_complete(event): - frame = next(frames_iterator) - big0.bis_links[0].write(frame) + + event_handle = event.connection_handles[0] + if event_handle == handle0: + frame0 = next(frames_iterator0) + big0.bis_links[0].write(frame0) + elif event_handle == handle1: + frame1 = next(frames_iterator1) + big1.bis_links[0].write(frame1) + else: + raise NotImplementedError('Unkown connection handle') device.host.on('hci_number_of_completed_packets_event', on_packet_complete) - - on_packet_complete('') # Send the first packet, to get the event loop running - - + # Send the first packets, to get the event loop running + big0.bis_links[0].write(frame0) + big1.bis_links[0].write(frame1) while True: await asyncio.sleep(1) @@ -367,10 +388,10 @@ if __name__ == "__main__": bigs = [ auracast_config.broadcast_de ] - global_conf.auracast_sampling_rate_khz=16000 - global_conf.octets_per_frame=40 # 16kbps@8kHz - - #global_conf.octets_per_frame=60# 48kbps@24kHz + #global_conf.auracast_sampling_rate_khz=16000 + #global_conf.octets_per_frame=40 # 16kbps@8kHz + + global_conf.octets_per_frame=60# 48kbps@24kHz broadcast( global_conf, diff --git a/auracast/multicast.py b/auracast/multicast.py index 241cd76..3e9f1d2 100644 --- a/auracast/multicast.py +++ b/auracast/multicast.py @@ -125,7 +125,7 @@ async def run_broadcast( logger.error(color('Periodic advertising not supported', 'red')) return - bap_sampling_freq = getattr(bap.SamplingFrequency, f"FREQ_{global_config.auracast_sampling_rate_khz}") + bap_sampling_freq = getattr(bap.SamplingFrequency, f"FREQ_{global_config.auracast_sampling_rate_hz}") bigs = {} for i, conf in enumerate(big_config): bigs[f'big{i}'] = {} @@ -134,7 +134,7 @@ async def run_broadcast( logger.info('Frame rate of .wav file is: %s', wav.getframerate()) encoder = lc3.Encoder( frame_duration_us=global_config.frame_duration_us, - sample_rate_hz=global_config.auracast_sampling_rate_khz, + sample_rate_hz=global_config.auracast_sampling_rate_hz, num_channels=1, input_sample_rate_hz=wav.getframerate(), )