diff --git a/auracast/announcement_48_10_96_es.wav b/auracast/announcement_48_10_96_es.wav new file mode 100644 index 0000000..181b38a Binary files /dev/null and b/auracast/announcement_48_10_96_es.wav differ diff --git a/auracast/announcement_48_10_96_it.wav b/auracast/announcement_48_10_96_it.wav new file mode 100644 index 0000000..7c800b1 Binary files /dev/null and b/auracast/announcement_48_10_96_it.wav differ diff --git a/auracast/auracast_config.py b/auracast/auracast_config.py index af08829..f9b70f5 100644 --- a/auracast/auracast_config.py +++ b/auracast/auracast_config.py @@ -19,7 +19,7 @@ class AuracastBigConfig: broadcast_id: int =123456, broadcast_random_address: hci.Address = hci.Address('F1:F1:F2:F3:F4:F5') broadcast_code: str = None # a hexstr - broadcast_language: str = 'en' # See: https://en.wikipedia.org/wiki/ISO_639-3 + broadcast_language: str = 'eng' # See: https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes broadcast_name: str = 'Broadcast0' broadcast_program_info: str = 'Some Announcements' broacast_wav_file_path: str = './auracast/announcement_48_10_96000_en.wav' @@ -52,4 +52,22 @@ broadcast_fr = AuracastBigConfig( broadcast_language='fra', broadcast_program_info = 'Announcements French', broacast_wav_file_path = './auracast/announcement_48_10_96000_fr.wav', +) + +broadcast_es = AuracastBigConfig( + broadcast_id=12345, + broadcast_random_address=hci.Address('F4:F1:F2:F3:F4:F5'), + broadcast_name = 'Broadcast3', + broadcast_language='spa', + broadcast_program_info = 'Announcements Spanish', + broacast_wav_file_path = './auracast/announcement_48_10_96_es.wav', +) + +broadcast_it = AuracastBigConfig( + broadcast_id=123456, + broadcast_random_address=hci.Address('F5:F1:F2:F3:F4:F5'), + broadcast_name = 'Broadcast4', + broadcast_language='ita', + broadcast_program_info = 'Announcements Italian', + broacast_wav_file_path = './auracast/announcement_48_10_96_it.wav', ) \ No newline at end of file diff --git a/auracast/multicast.py b/auracast/multicast.py index 648aca6..9d9ab7c 100644 --- a/auracast/multicast.py +++ b/auracast/multicast.py @@ -112,12 +112,13 @@ def run_async(async_command: Coroutine) -> None: color('!!! An error occurred while executing the command:', 'red'), message ) +ADVERTISING_SLOWDOWN_FACTOR=1 PKGS_COUNT = 0 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: @@ -157,7 +158,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( [ @@ -191,10 +192,11 @@ async def run_broadcast( advertising_event_properties=bumble.device.AdvertisingEventProperties( is_connectable=False ), - primary_advertising_interval_min=100, - primary_advertising_interval_max=200, - advertising_sid=i - # TODO: use 2mbit phy + primary_advertising_interval_min=round(100*ADVERTISING_SLOWDOWN_FACTOR), + primary_advertising_interval_max=round(200*ADVERTISING_SLOWDOWN_FACTOR), + advertising_sid=i, + #primary_advertising_phy=hci.Phy.LE_2M, TODO: 2m phy config throws error + #secondary_advertising_phy=hci.Phy.LE_2M, ), advertising_data=( bigs[f'big{i}']['broadcast_audio_announcement'].get_advertising_data() @@ -205,8 +207,8 @@ async def run_broadcast( ) ), periodic_advertising_parameters=bumble.device.PeriodicAdvertisingParameters( - periodic_advertising_interval_min=80, - periodic_advertising_interval_max=160, + periodic_advertising_interval_min=round(80*ADVERTISING_SLOWDOWN_FACTOR), + periodic_advertising_interval_max=round(160*ADVERTISING_SLOWDOWN_FACTOR), ), periodic_advertising_data=bigs[f'big{i}']['basic_audio_announcement'].get_advertising_data(), auto_restart=True, @@ -240,29 +242,37 @@ async def run_broadcast( ) bigs[f'big{i}']['frames_iterator'] = itertools.cycle(frames) - + + await asyncio.sleep(3) # Wait for advertising to set up + LOOP_FINITE_PKGS = -1 # set -1 to loop infinitely - - logging.info("Broadcasting...") + def on_packet_complete(event): global PKGS_COUNT PKGS_COUNT = PKGS_COUNT + 1 event_handle = event.connection_handles[0] - - if PKGS_COUNT < LOOP_FINITE_PKGS or LOOP_FINITE_PKGS == -1 : + + if PKGS_COUNT < LOOP_FINITE_PKGS or LOOP_FINITE_PKGS == -1: + event_found = False for big in bigs.values(): if big['big'].bis_links[0].handle == event_handle: - frame = next(big['frames_iterator'] ) + frame = next(big['frames_iterator']) big['big'].bis_links[0].write(frame) - + event_found = True + if not event_found: + logging.warning('unknown event on packet complete with handle: %s', event_handle) + else: + logging.warning("Stopping iso loop") + + logging.info("Broadcasting...") device.host.on('hci_number_of_completed_packets_event', on_packet_complete) # Send the first packet for each big, to get the event loop running for big in bigs.values(): frame = next(big['frames_iterator'] ) big['big'].bis_links[0].write(frame) - + while True: await asyncio.sleep(1) @@ -286,23 +296,26 @@ if __name__ == "__main__": logging.basicConfig(level=logging.INFO) global_conf = auracast_config.global_base_config - + #global_conf.transport='serial:/dev/serial/by-id/usb-ZEPHYR_Zephyr_HCI_UART_sample_81BD14B8D71B5662-if00,1000000,rtscts' # transport for nrf52 dongle #global_conf.transport='serial:/dev/serial/by-id/usb-SEGGER_J-Link_001050076061-if02,1000000,rtscts' # transport for nrf53dk global_conf.transport='serial:/dev/serial/by-id/usb-SEGGER_J-Link_001057705357-if02,1000000,rtscts' # transport for nrf54l15dk - - + + bigs = [ auracast_config.broadcast_de, auracast_config.broadcast_en, - #auracast_config.broadcast_fr, + auracast_config.broadcast_fr, + auracast_config.broadcast_es, #TODO: spanish not appearing as auracast + # auracast_config.broadcast_it, #TODO: with more than three broadcasts, not advertising at all is present, regardless the adv. interval ] - #global_conf.auracast_sampling_rate_hz = 16000 - #global_conf.octets_per_frame = 40 # 32kbps@16kHz + global_conf.auracast_sampling_rate_hz = 16000 + global_conf.octets_per_frame = 40 # 32kbps@16kHz - + # Note: 24kHz is only working with 2 streams - so this may be a host->controller interface bottleneck + # TODO: use thread usage debugger on controller to check actual cpu load broadcast( global_conf,