1515LOG_MODULE_REGISTER (bt_service , CONFIG_SOF_LOG_LEVEL );
1616
1717#define ESP32P4_GPIO_C6_EN_BIT (1U << 22) /* GPIO 54 = 32 + 22 */
18- #define BT_AUDIO_FRAME_MS 10
19- #define BT_AUDIO_FRAME_SAMPLES 480 /* 10ms at 48kHz */
20- #define BT_AUDIO_FRAME_BYTES (BT_AUDIO_FRAME_SAMPLES * 2 * sizeof(int16_t)) /* 1920 bytes */
18+
19+ static const struct bt_audio_format_desc s_formats [BT_AUDIO_FMT_COUNT ] = {
20+ [BT_AUDIO_FMT_48K_STD ] = {
21+ .format = BT_AUDIO_FMT_48K_STD ,
22+ .name = "48k_std" ,
23+ .codec_name = "LC3" ,
24+ .sample_rate = 48000 ,
25+ .bit_depth = 16 ,
26+ .frame_duration_us = 10000 ,
27+ .frame_duration_ms = 10 ,
28+ .octets_per_codec_frame = 100 ,
29+ .bitrate_kbps = 160 ,
30+ .frame_samples = 480 ,
31+ .frame_bytes = 1920 ,
32+ },
33+ [BT_AUDIO_FMT_48K_HQ ] = {
34+ .format = BT_AUDIO_FMT_48K_HQ ,
35+ .name = "48k_hq" ,
36+ .codec_name = "LC3" ,
37+ .sample_rate = 48000 ,
38+ .bit_depth = 16 ,
39+ .frame_duration_us = 10000 ,
40+ .frame_duration_ms = 10 ,
41+ .octets_per_codec_frame = 120 ,
42+ .bitrate_kbps = 192 ,
43+ .frame_samples = 480 ,
44+ .frame_bytes = 1920 ,
45+ },
46+ [BT_AUDIO_FMT_48K_MAX ] = {
47+ .format = BT_AUDIO_FMT_48K_MAX ,
48+ .name = "48k_max" ,
49+ .codec_name = "LC3" ,
50+ .sample_rate = 48000 ,
51+ .bit_depth = 24 ,
52+ .frame_duration_us = 10000 ,
53+ .frame_duration_ms = 10 ,
54+ .octets_per_codec_frame = 240 ,
55+ .bitrate_kbps = 384 ,
56+ .frame_samples = 480 ,
57+ .frame_bytes = 1920 ,
58+ },
59+ [BT_AUDIO_FMT_44K ] = {
60+ .format = BT_AUDIO_FMT_44K ,
61+ .name = "44k" ,
62+ .codec_name = "LC3" ,
63+ .sample_rate = 44100 ,
64+ .bit_depth = 16 ,
65+ .frame_duration_us = 10000 ,
66+ .frame_duration_ms = 10 ,
67+ .octets_per_codec_frame = 130 ,
68+ .bitrate_kbps = 208 ,
69+ .frame_samples = 441 ,
70+ .frame_bytes = 1764 ,
71+ },
72+ [BT_AUDIO_FMT_48K_LL ] = {
73+ .format = BT_AUDIO_FMT_48K_LL ,
74+ .name = "48k_ll" ,
75+ .codec_name = "LC3" ,
76+ .sample_rate = 48000 ,
77+ .bit_depth = 16 ,
78+ .frame_duration_us = 7500 ,
79+ .frame_duration_ms = 8 ,
80+ .octets_per_codec_frame = 75 ,
81+ .bitrate_kbps = 160 ,
82+ .frame_samples = 360 ,
83+ .frame_bytes = 1440 ,
84+ },
85+ [BT_AUDIO_FMT_96K_HR ] = {
86+ .format = BT_AUDIO_FMT_96K_HR ,
87+ .name = "96k_hr" ,
88+ .codec_name = "LC3plus-HR" ,
89+ .sample_rate = 96000 ,
90+ .bit_depth = 24 ,
91+ .frame_duration_us = 5000 ,
92+ .frame_duration_ms = 5 ,
93+ .octets_per_codec_frame = 160 ,
94+ .bitrate_kbps = 512 ,
95+ .frame_samples = 480 ,
96+ .frame_bytes = 1920 ,
97+ },
98+ [BT_AUDIO_FMT_LPCM ] = {
99+ .format = BT_AUDIO_FMT_LPCM ,
100+ .name = "lpcm" ,
101+ .codec_name = "LPCM (Raw)" ,
102+ .sample_rate = 32000 ,
103+ .bit_depth = 16 ,
104+ .frame_duration_us = 10000 ,
105+ .frame_duration_ms = 10 ,
106+ .octets_per_codec_frame = 640 ,
107+ .bitrate_kbps = 1024 ,
108+ .frame_samples = 320 ,
109+ .frame_bytes = 1280 ,
110+ },
111+ };
21112
22113static struct bt_service_status s_status = {
23114 .c6_powered = false,
24115 .state = BT_STATE_DISABLED ,
25116 .route = SOF_AUDIO_ROUTE_USB_DAI ,
117+ .format = BT_AUDIO_FMT_48K_STD ,
26118 .sample_rate = 48000 ,
119+ .bitrate_kbps = 160 ,
120+ .frame_bytes = 1920 ,
121+ .codec_name = "LC3" ,
27122 .tx_packets = 0 ,
28123 .rx_packets = 0 ,
29124 .tx_bytes = 0 ,
@@ -61,8 +156,10 @@ int bt_service_start_broadcast(void)
61156 k_msleep (150 );
62157 }
63158
159+ const struct bt_audio_format_desc * desc = & s_formats [s_status .format ];
64160 s_status .state = BT_STATE_BROADCASTING ;
65- LOG_INF ("Bluetooth LE Audio Broadcast started at %u Hz stereo (10ms ISO SDU)" , s_status .sample_rate );
161+ LOG_INF ("Bluetooth LE Audio Broadcast started: '%s' (%s @ %u Hz, %u kbps, %u ms SDU)" ,
162+ desc -> name , desc -> codec_name , desc -> sample_rate , desc -> bitrate_kbps , desc -> frame_duration_ms );
66163 return 0 ;
67164}
68165
@@ -102,6 +199,62 @@ enum sof_audio_route bt_service_get_route(void)
102199 return s_status .route ;
103200}
104201
202+ int bt_service_set_format (enum bt_audio_format fmt )
203+ {
204+ if (fmt >= BT_AUDIO_FMT_COUNT ) {
205+ LOG_ERR ("Invalid Bluetooth audio format: %d" , fmt );
206+ return - EINVAL ;
207+ }
208+
209+ const struct bt_audio_format_desc * desc = & s_formats [fmt ];
210+ s_status .format = fmt ;
211+ s_status .sample_rate = desc -> sample_rate ;
212+ s_status .bitrate_kbps = desc -> bitrate_kbps ;
213+ s_status .frame_bytes = desc -> frame_bytes ;
214+ s_status .codec_name = desc -> codec_name ;
215+
216+ bt_audio_set_playback_rate (desc -> sample_rate );
217+ bt_audio_set_capture_rate (desc -> sample_rate );
218+
219+ LOG_INF ("Bluetooth audio format set to '%s' (%s @ %u Hz %u-bit, %u kbps, %u ms SDU, %u B PCM)" ,
220+ desc -> name , desc -> codec_name , desc -> sample_rate , desc -> bit_depth ,
221+ desc -> bitrate_kbps , desc -> frame_duration_ms , desc -> frame_bytes );
222+ return 0 ;
223+ }
224+
225+ enum bt_audio_format bt_service_get_format (void )
226+ {
227+ return s_status .format ;
228+ }
229+
230+ const struct bt_audio_format_desc * bt_service_get_format_desc (enum bt_audio_format fmt )
231+ {
232+ if (fmt >= BT_AUDIO_FMT_COUNT ) {
233+ return NULL ;
234+ }
235+ return & s_formats [fmt ];
236+ }
237+
238+ const struct bt_audio_format_desc * bt_service_get_current_format_desc (void )
239+ {
240+ return & s_formats [s_status .format ];
241+ }
242+
243+ int bt_service_format_from_name (const char * name , enum bt_audio_format * fmt )
244+ {
245+ if (!name || !fmt ) {
246+ return - EINVAL ;
247+ }
248+
249+ for (int i = 0 ; i < BT_AUDIO_FMT_COUNT ; i ++ ) {
250+ if (strcmp (name , s_formats [i ].name ) == 0 ) {
251+ * fmt = (enum bt_audio_format )i ;
252+ return 0 ;
253+ }
254+ }
255+ return - ENOENT ;
256+ }
257+
105258void bt_service_get_status (struct bt_service_status * status )
106259{
107260 if (status ) {
@@ -116,12 +269,16 @@ static void bt_audio_stream_task(void *p1, void *p2, void *p3)
116269 ARG_UNUSED (p2 );
117270 ARG_UNUSED (p3 );
118271
119- static uint8_t s_audio_buf [BT_AUDIO_FRAME_BYTES ] __aligned (4 );
272+ static uint8_t s_audio_buf [1920 ] __aligned (4 );
120273
121274 while (s_thread_running ) {
275+ const struct bt_audio_format_desc * desc = & s_formats [s_status .format ];
276+ uint32_t frame_bytes = desc -> frame_bytes ;
277+ uint32_t sleep_ms = desc -> frame_duration_ms ? desc -> frame_duration_ms : 10 ;
278+
122279 if (s_status .state == BT_STATE_BROADCASTING ) {
123280 /* Fetch audio from pipeline/bt_audio component */
124- size_t fetched = bt_audio_fetch_capture_data (s_audio_buf , BT_AUDIO_FRAME_BYTES );
281+ size_t fetched = bt_audio_fetch_capture_data (s_audio_buf , frame_bytes );
125282 if (fetched > 0 ) {
126283 s_status .tx_packets ++ ;
127284 s_status .tx_bytes += fetched ;
@@ -135,10 +292,10 @@ static void bt_audio_stream_task(void *p1, void *p2, void *p3)
135292 }
136293 } else if (s_status .state == BT_STATE_RECEIVING ) {
137294 s_status .rx_packets ++ ;
138- s_status .rx_bytes += BT_AUDIO_FRAME_BYTES ;
295+ s_status .rx_bytes += frame_bytes ;
139296 }
140297
141- k_msleep (BT_AUDIO_FRAME_MS );
298+ k_msleep (sleep_ms );
142299 }
143300}
144301
0 commit comments