make multicast with 3 @16khz work.
This commit is contained in:
BIN
auracast/announcement_48_10_96_es.wav
Normal file
BIN
auracast/announcement_48_10_96_es.wav
Normal file
Binary file not shown.
BIN
auracast/announcement_48_10_96_it.wav
Normal file
BIN
auracast/announcement_48_10_96_it.wav
Normal file
Binary file not shown.
@@ -19,7 +19,7 @@ class AuracastBigConfig:
|
|||||||
broadcast_id: int =123456,
|
broadcast_id: int =123456,
|
||||||
broadcast_random_address: hci.Address = hci.Address('F1:F1:F2:F3:F4:F5')
|
broadcast_random_address: hci.Address = hci.Address('F1:F1:F2:F3:F4:F5')
|
||||||
broadcast_code: str = None # a hexstr
|
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_name: str = 'Broadcast0'
|
||||||
broadcast_program_info: str = 'Some Announcements'
|
broadcast_program_info: str = 'Some Announcements'
|
||||||
broacast_wav_file_path: str = './auracast/announcement_48_10_96000_en.wav'
|
broacast_wav_file_path: str = './auracast/announcement_48_10_96000_en.wav'
|
||||||
@@ -52,4 +52,22 @@ broadcast_fr = AuracastBigConfig(
|
|||||||
broadcast_language='fra',
|
broadcast_language='fra',
|
||||||
broadcast_program_info = 'Announcements French',
|
broadcast_program_info = 'Announcements French',
|
||||||
broacast_wav_file_path = './auracast/announcement_48_10_96000_fr.wav',
|
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',
|
||||||
)
|
)
|
||||||
@@ -112,12 +112,13 @@ def run_async(async_command: Coroutine) -> None:
|
|||||||
color('!!! An error occurred while executing the command:', 'red'), message
|
color('!!! An error occurred while executing the command:', 'red'), message
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ADVERTISING_SLOWDOWN_FACTOR=1
|
||||||
PKGS_COUNT = 0
|
PKGS_COUNT = 0
|
||||||
|
|
||||||
async def run_broadcast(
|
async def run_broadcast(
|
||||||
global_config : auracast_config.AuracastGlobalConfig,
|
global_config : auracast_config.AuracastGlobalConfig,
|
||||||
big_config: List[auracast_config.AuracastBigConfig]
|
big_config: List[auracast_config.AuracastBigConfig]
|
||||||
|
|
||||||
) -> None:
|
) -> None:
|
||||||
async with create_device(global_config) as device:
|
async with create_device(global_config) as device:
|
||||||
if not device.supports_le_periodic_advertising:
|
if not device.supports_le_periodic_advertising:
|
||||||
@@ -157,7 +158,7 @@ async def run_broadcast(
|
|||||||
codec_specific_configuration=bap.CodecSpecificConfiguration(
|
codec_specific_configuration=bap.CodecSpecificConfiguration(
|
||||||
sampling_frequency=bap_sampling_freq,
|
sampling_frequency=bap_sampling_freq,
|
||||||
frame_duration=bap.FrameDuration.DURATION_10000_US,
|
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(
|
metadata=le_audio.Metadata(
|
||||||
[
|
[
|
||||||
@@ -191,10 +192,11 @@ async def run_broadcast(
|
|||||||
advertising_event_properties=bumble.device.AdvertisingEventProperties(
|
advertising_event_properties=bumble.device.AdvertisingEventProperties(
|
||||||
is_connectable=False
|
is_connectable=False
|
||||||
),
|
),
|
||||||
primary_advertising_interval_min=100,
|
primary_advertising_interval_min=round(100*ADVERTISING_SLOWDOWN_FACTOR),
|
||||||
primary_advertising_interval_max=200,
|
primary_advertising_interval_max=round(200*ADVERTISING_SLOWDOWN_FACTOR),
|
||||||
advertising_sid=i
|
advertising_sid=i,
|
||||||
# TODO: use 2mbit phy
|
#primary_advertising_phy=hci.Phy.LE_2M, TODO: 2m phy config throws error
|
||||||
|
#secondary_advertising_phy=hci.Phy.LE_2M,
|
||||||
),
|
),
|
||||||
advertising_data=(
|
advertising_data=(
|
||||||
bigs[f'big{i}']['broadcast_audio_announcement'].get_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_parameters=bumble.device.PeriodicAdvertisingParameters(
|
||||||
periodic_advertising_interval_min=80,
|
periodic_advertising_interval_min=round(80*ADVERTISING_SLOWDOWN_FACTOR),
|
||||||
periodic_advertising_interval_max=160,
|
periodic_advertising_interval_max=round(160*ADVERTISING_SLOWDOWN_FACTOR),
|
||||||
),
|
),
|
||||||
periodic_advertising_data=bigs[f'big{i}']['basic_audio_announcement'].get_advertising_data(),
|
periodic_advertising_data=bigs[f'big{i}']['basic_audio_announcement'].get_advertising_data(),
|
||||||
auto_restart=True,
|
auto_restart=True,
|
||||||
@@ -240,29 +242,37 @@ async def run_broadcast(
|
|||||||
)
|
)
|
||||||
|
|
||||||
bigs[f'big{i}']['frames_iterator'] = itertools.cycle(frames)
|
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
|
LOOP_FINITE_PKGS = -1 # set -1 to loop infinitely
|
||||||
|
|
||||||
logging.info("Broadcasting...")
|
|
||||||
def on_packet_complete(event):
|
def on_packet_complete(event):
|
||||||
global PKGS_COUNT
|
global PKGS_COUNT
|
||||||
PKGS_COUNT = PKGS_COUNT + 1
|
PKGS_COUNT = PKGS_COUNT + 1
|
||||||
|
|
||||||
event_handle = event.connection_handles[0]
|
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():
|
for big in bigs.values():
|
||||||
if big['big'].bis_links[0].handle == event_handle:
|
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)
|
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)
|
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
|
# Send the first packet for each big, to get the event loop running
|
||||||
for big in bigs.values():
|
for big in bigs.values():
|
||||||
frame = next(big['frames_iterator'] )
|
frame = next(big['frames_iterator'] )
|
||||||
big['big'].bis_links[0].write(frame)
|
big['big'].bis_links[0].write(frame)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
@@ -286,23 +296,26 @@ if __name__ == "__main__":
|
|||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
global_conf = auracast_config.global_base_config
|
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-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_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
|
global_conf.transport='serial:/dev/serial/by-id/usb-SEGGER_J-Link_001057705357-if02,1000000,rtscts' # transport for nrf54l15dk
|
||||||
|
|
||||||
|
|
||||||
bigs = [
|
bigs = [
|
||||||
auracast_config.broadcast_de,
|
auracast_config.broadcast_de,
|
||||||
auracast_config.broadcast_en,
|
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.auracast_sampling_rate_hz = 16000
|
||||||
#global_conf.octets_per_frame = 40 # 32kbps@16kHz
|
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(
|
broadcast(
|
||||||
global_conf,
|
global_conf,
|
||||||
|
|||||||
Reference in New Issue
Block a user