Skip to content

Commit

Permalink
applications: nrf5340_audio: Rail the presentation delay.
Browse files Browse the repository at this point in the history
	Ensure the preferred presentation delay is within the range of the
	min and max delays, rail if not.
	Search for the presentation delay function updated to search over
	the end points for the direction.

Signed-off-by: Graham Wacey <[email protected]>
  • Loading branch information
gWacey committed May 16, 2024
1 parent 02cd095 commit fb06f73
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 49 deletions.
23 changes: 5 additions & 18 deletions applications/nrf5340_audio/src/audio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ config AUDIO_MIN_PRES_DLY_US
int "The minimum presentation delay"
default 3000
help
The minimum presentation delay in micro seconds determined by
the audio system processing and the minimum buffering.
The minimum allowable presentation delay in microseconds.
This needs to allow time for decoding and internal routing.
For 48kHz sampling rate and 96kbps bitrate this is about 4000 us.

config AUDIO_MAX_PRES_DLY_US
int "The maximum presentation delay"
default 60000
help
The maximum presentation delay in micro seconds.
The maximum allowable presentation delay in microseconds.
Increasing this will also increase the FIFO buffers to allow buffering.

choice AUDIO_SYSTEM_SAMPLE_RATE
prompt "System audio sample rate"
Expand Down Expand Up @@ -108,21 +110,6 @@ config AUDIO_BIT_DEPTH_OCTETS
help
Bit depth of one sample in storage given in octets.

config AUDIO_MIN_PRES_DLY_US
int "The minimum presentation delay"
default 4000
help
The minimum allowable presentation delay in microseconds.
This needs to allow time for decoding and internal routing.
For 48kHz sampling rate and 96kbps bitrate this is about 4000 us.

config AUDIO_MAX_PRES_DLY_US
int "The maximum presentation delay"
default 60000
help
The maximum allowable presentation delay in microseconds.
Increasing this will also increase the FIFO buffers to allow buffering.

choice AUDIO_SOURCE_GATEWAY
prompt "Audio source for gateway"
default AUDIO_SOURCE_I2S if WALKIE_TALKIE_DEMO
Expand Down
27 changes: 27 additions & 0 deletions applications/nrf5340_audio/src/bluetooth/bt_stream/le_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,33 @@ bool le_audio_ep_state_check(struct bt_bap_ep *ep, enum bt_bap_ep_state state)
return false;
}

bool le_audio_ep_qos_configured(struct bt_bap_ep const *const ep)
{
int ret;
struct bt_bap_ep_info ep_info;

if (ep == NULL) {
LOG_DBG("EP is NULL");
/* If an endpoint is NULL it is not in any of the states */
return false;
}

ret = bt_bap_ep_get_info(ep, &ep_info);
if (ret) {
LOG_WRN("Unable to get info for ep");
return false;
}

if (ep_info.state == BT_BAP_EP_STATE_QOS_CONFIGURED ||
ep_info.state == BT_BAP_EP_STATE_ENABLING ||
ep_info.state == BT_BAP_EP_STATE_STREAMING ||
ep_info.state == BT_BAP_EP_STATE_DISABLING) {
return true;
}

return false;
}

int le_audio_freq_hz_get(const struct bt_audio_codec_cfg *codec, int *freq_hz)
{
int ret;
Expand Down
11 changes: 11 additions & 0 deletions applications/nrf5340_audio/src/bluetooth/bt_stream/le_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ int le_audio_ep_state_get(struct bt_bap_ep *ep, uint8_t *state);
*/
bool le_audio_ep_state_check(struct bt_bap_ep *ep, enum bt_bap_ep_state state);

/**
* @brief Check if an endpoint has had the QoS configured.
* If the endpoint is NULL, it is not in the state, and this function returns false.
*
* @param[in] ep The endpoint to check.
*
* @retval true The endpoint QoS is configured.
* @retval false Otherwise.
*/
bool le_audio_ep_qos_configured(struct bt_bap_ep const *const ep);

/**
* @brief Decode the audio sampling frequency in the codec configuration.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include "le_audio.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(unicast_client, CONFIG_UNICAST_CLIENT_LOG_LEVEL);
LOG_MODULE_REGISTER(unicast_client, 4); /* CONFIG_UNICAST_CLIENT_LOG_LEVEL); */

ZBUS_CHAN_DEFINE(le_audio_chan, struct le_audio_msg, NULL, NULL, ZBUS_OBSERVERS_EMPTY,
ZBUS_MSG_INIT(0));
Expand Down Expand Up @@ -191,56 +191,82 @@ K_WORK_DEFINE(cap_start_work, cap_start_worker);
*/
static int device_pres_delay_find(uint8_t index, uint32_t *pres_dly_us)
{
uint32_t pres_dly_min = unicast_servers[index].sink_ep->qos_pref.pd_min;
uint32_t pres_dly_max = unicast_servers[index].sink_ep->qos_pref.pd_max;
uint32_t pref_dly_min = unicast_servers[index].sink_ep->qos_pref.pref_pd_min;
uint32_t pref_dly_max = unicast_servers[index].sink_ep->qos_pref.pref_pd_max;
uint32_t pd_min = unicast_servers[index].sink_ep->qos_pref.pd_min;
uint32_t pd_max = unicast_servers[index].sink_ep->qos_pref.pd_max;
uint32_t pref_pd_min = unicast_servers[index].sink_ep->qos_pref.pref_pd_min;
uint32_t pref_pd_max = unicast_servers[index].sink_ep->qos_pref.pref_pd_max;

LOG_DBG("Index: %d, Pref min: %d, pref max: %d, pres_min: %d, pres_max: %d", index,
pref_dly_min, pref_dly_max, pres_dly_min, pres_dly_max);
pref_pd_min, pref_pd_max, pd_min, pd_max);

*pres_dly_us = 0;

for (int i = 0; i < ARRAY_SIZE(unicast_servers); i++) {
if (unicast_servers[i].sink_ep != NULL) {
pres_dly_min =
MAX(pres_dly_min, unicast_servers[i].sink_ep->qos_pref.pd_min);
pres_dly_max =
MIN(pres_dly_max, unicast_servers[i].sink_ep->qos_pref.pd_max);
pref_dly_min =
MAX(pref_dly_min, unicast_servers[i].sink_ep->qos_pref.pref_pd_min);
pref_dly_max =
MIN(pref_dly_max, unicast_servers[i].sink_ep->qos_pref.pref_pd_max);
if (le_audio_ep_qos_configured(unicast_servers[i].sink_ep)) {
LOG_DBG("i: %d, Pref min: %d, pref max: %d, pres_min: %d, pres_max: %d", i,
unicast_servers[i].sink_ep->qos_pref.pref_pd_min,
unicast_servers[i].sink_ep->qos_pref.pref_pd_max,
unicast_servers[i].sink_ep->qos_pref.pd_min,
unicast_servers[i].sink_ep->qos_pref.pd_max);

pd_min = MAX(pd_min, unicast_servers[i].sink_ep->qos_pref.pd_min);
pref_pd_min =
MAX(pref_pd_min, unicast_servers[i].sink_ep->qos_pref.pref_pd_min);

if (unicast_servers[i].sink_ep->qos_pref.pd_max) {
pd_max = MIN(pd_max, unicast_servers[i].sink_ep->qos_pref.pd_max);
}

if (unicast_servers[i].sink_ep->qos_pref.pref_pd_max) {
pref_pd_max = MIN(pref_pd_max,
unicast_servers[i].sink_ep->qos_pref.pref_pd_max);
}
}
}

if (IS_ENABLED(CONFIG_BT_AUDIO_PRES_DELAY_SRCH_MIN)) {
*pres_dly_us = pres_dly_min;
*pres_dly_us = pd_min;

return 0;
}

if (IS_ENABLED(CONFIG_BT_AUDIO_PRES_DELAY_SRCH_MAX)) {
*pres_dly_us = pres_dly_max;
*pres_dly_us = pd_max;

return 0;
}

if (IS_ENABLED(CONFIG_BT_AUDIO_PRES_DELAY_SRCH_PREF_MIN)) {
/* Preferred min is 0, so we set min supported */
if (pref_dly_min == 0) {
*pres_dly_us = pres_dly_min;
if (pref_pd_min == 0) {
*pres_dly_us = pd_min;
} else if (pref_pd_min < pd_min) {
*pres_dly_us = pd_min;
LOG_WRN("pref_pd_min < pd_min (%d < %d), pres delay set to %d", pref_pd_min,
pd_min, *pres_dly_us);
} else if (pref_pd_min <= pd_max) {
*pres_dly_us = pref_pd_min;
} else {
*pres_dly_us = pref_dly_min;
*pres_dly_us = pd_max;
LOG_WRN("pref_pd_min > pd_max (%d > %d), pres delay set to %d", pref_pd_min,
pd_max, *pres_dly_us);
}

return 0;
}

if (IS_ENABLED(CONFIG_BT_AUDIO_PRES_DELAY_SRCH_PREF_MAX)) {
/* Preferred max is 0, so we set max supported */
if (pref_dly_max == 0) {
*pres_dly_us = pres_dly_max;
if (pref_pd_max == 0) {
*pres_dly_us = pd_max;
} else if (pref_pd_max > pd_max) {
*pres_dly_us = pd_max;
LOG_WRN("pref_pd_max > pd_max (%d > %d), pres delay set to %d", pref_pd_max,
pd_max, *pres_dly_us);
} else if (pref_pd_max >= pd_min) {
*pres_dly_us = pref_pd_max;
} else {
*pres_dly_us = pref_dly_max;
*pres_dly_us = pd_min;
LOG_WRN("pref_pd_max < pd_min (%d < %d), pres delay set to %d", pref_pd_max,
pd_min, *pres_dly_us);
}

return 0;
Expand Down Expand Up @@ -644,7 +670,8 @@ static int update_cap_sink_stream_qos(struct le_audio_unicast_server *unicast_se
if (playing_state &&
le_audio_ep_state_check(unicast_server->cap_sink_stream.bap_stream.ep,
BT_BAP_EP_STATE_STREAMING)) {
LOG_DBG("Update streaming %s unicast_server, connection %p, stream %p",
LOG_DBG("Update streaming %s unicast_server, connection %p, stream "
"%p",
unicast_server->ch_name, (void *)&unicast_server->device_conn,
(void *)&unicast_server->cap_sink_stream.bap_stream);

Expand Down Expand Up @@ -918,7 +945,8 @@ static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
}

if (!playing_state) {
/* Since we are not in a playing state we return before starting the new streams */
/* Since we are not in a playing state we return before starting the new
* streams */

Check warning on line 949 in applications/nrf5340_audio/src/bluetooth/bt_stream/unicast/unicast_client.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

BLOCK_COMMENT_STYLE

applications/nrf5340_audio/src/bluetooth/bt_stream/unicast/unicast_client.c:949 Block comments use a trailing */ on a separate line
return;
}

Expand Down Expand Up @@ -1447,7 +1475,8 @@ int unicast_client_start(void)
cap_stream_params[param.count].codec_cfg = &lc3_preset_sink.codec_cfg;
param.count++;
} else {
LOG_WRN("Found unicast_server[%d] with an endpoint not in IDLE state: %d",
LOG_WRN("Found unicast_server[%d] with an endpoint not in IDLE "
"state: %d",
i, state);
}

Expand All @@ -1466,7 +1495,8 @@ int unicast_client_start(void)
cap_stream_params[param.count].codec_cfg = &lc3_preset_source.codec_cfg;
param.count++;
} else {
LOG_WRN("Found unicast_server[%d] with an endpoint not in IDLE state: %d",
LOG_WRN("Found unicast_server[%d] with an endpoint not in IDLE "
"state: %d",
i, state);
}
}
Expand Down Expand Up @@ -1512,7 +1542,8 @@ int unicast_client_stop(void)
streams[param.count] = &unicast_servers[i].cap_sink_stream;
param.count++;
} else {
LOG_WRN("Found unicast_server[%d] with an endpoint not in STREAMING state: "
LOG_WRN("Found unicast_server[%d] with an endpoint not in "
"STREAMING state: "
"%d",
i, state);
}
Expand All @@ -1527,7 +1558,8 @@ int unicast_client_stop(void)
streams[param.count] = &unicast_servers[i].cap_source_stream;
param.count++;
} else {
LOG_WRN("Found unicast_server[%d] with an endpoint not in STREAMING state: "
LOG_WRN("Found unicast_server[%d] with an endpoint not in "
"STREAMING state: "
"%d",
i, state);
}
Expand Down

0 comments on commit fb06f73

Please sign in to comment.