test/le_audio_unicast_sink: start audio playback with 30ms of data

This commit is contained in:
Matthias Ringwald 2022-10-27 15:28:04 +02:00
parent 87806d86dd
commit 5b24213372

View File

@ -88,9 +88,10 @@
#define MAX_SAMPLES_PER_FRAME 480 #define MAX_SAMPLES_PER_FRAME 480
// playback // playback
#define MAX_NUM_LC3_FRAMES 5 #define MAX_NUM_LC3_FRAMES 3
#define MAX_BYTES_PER_SAMPLE 4 #define MAX_BYTES_PER_SAMPLE 4
#define PLAYBACK_BUFFER_SIZE (MAX_NUM_LC3_FRAMES * MAX_SAMPLES_PER_FRAME * MAX_BYTES_PER_SAMPLE) #define PLAYBACK_BUFFER_SIZE (MAX_NUM_LC3_FRAMES * MAX_SAMPLES_PER_FRAME * MAX_BYTES_PER_SAMPLE)
#define PLAYBACK_START_MS 30
// analysis // analysis
#define PACKET_PREFIX_LEN 10 #define PACKET_PREFIX_LEN 10
@ -113,7 +114,8 @@ static enum {
APP_W4_CIG_COMPLETE, APP_W4_CIG_COMPLETE,
APP_W4_CIS_CREATED, APP_W4_CIS_CREATED,
APP_STREAMING, APP_STREAMING,
APP_IDLE APP_IDLE,
APP_SHUTDOWN
} app_state = APP_W4_WORKING; } app_state = APP_W4_WORKING;
// //
@ -174,6 +176,8 @@ static btstack_lc3plus_fraunhofer_decoder_t fraunhofer_decoder_contexts[MAX_CHAN
static void * decoder_contexts[MAX_NR_BIS]; static void * decoder_contexts[MAX_NR_BIS];
// playback // playback
static uint16_t playback_start_threshold_bytes;
static bool playback_active;
static uint8_t playback_buffer_storage[PLAYBACK_BUFFER_SIZE]; static uint8_t playback_buffer_storage[PLAYBACK_BUFFER_SIZE];
static btstack_ring_buffer_t playback_buffer; static btstack_ring_buffer_t playback_buffer;
@ -185,28 +189,31 @@ static uint16_t cached_iso_sdu_len;
static void le_audio_connection_sink_playback(int16_t * buffer, uint16_t num_samples){ static void le_audio_connection_sink_playback(int16_t * buffer, uint16_t num_samples){
// called from lower-layer but guaranteed to be on main thread // called from lower-layer but guaranteed to be on main thread
uint32_t bytes_needed = num_samples * num_channels * 2;
static bool underrun = true;
log_info("Playback: need %u, have %u", num_samples, btstack_ring_buffer_bytes_available(&playback_buffer) / (num_channels * 2)); log_info("Playback: need %u, have %u", num_samples, btstack_ring_buffer_bytes_available(&playback_buffer) / (num_channels * 2));
if (bytes_needed > btstack_ring_buffer_bytes_available(&playback_buffer)){ uint32_t bytes_needed = num_samples * num_channels * 2;
memset(buffer, 0, bytes_needed); if (playback_active == false){
if (underrun == false){ if (btstack_ring_buffer_bytes_available(&playback_buffer) >= playback_start_threshold_bytes) {
log_info("Playback underrun"); log_info("Playback started");
underrun = true; playback_active = true;
}
} else {
if (bytes_needed > btstack_ring_buffer_bytes_available(&playback_buffer)) {
log_info("Playback underrun");
// empty buffer
uint32_t bytes_read;
btstack_ring_buffer_read(&playback_buffer, (uint8_t *) buffer, bytes_needed, &bytes_read);
playback_active = false;
} }
return;
} }
if (underrun){ if (playback_active){
underrun = false; uint32_t bytes_read;
log_info("Playback started"); btstack_ring_buffer_read(&playback_buffer, (uint8_t *) buffer, bytes_needed, &bytes_read);
btstack_assert(bytes_read == bytes_needed);
} else {
memset(buffer, 0, bytes_needed);
} }
uint32_t bytes_read;
btstack_ring_buffer_read(&playback_buffer, (uint8_t *) buffer, bytes_needed, &bytes_read);
btstack_assert(bytes_read == bytes_needed);
} }
static void setup_lc3_decoder(void){ static void setup_lc3_decoder(void){
@ -259,12 +266,16 @@ static void enter_streaming(void){
// init playback buffer // init playback buffer
btstack_ring_buffer_init(&playback_buffer, playback_buffer_storage, PLAYBACK_BUFFER_SIZE); btstack_ring_buffer_init(&playback_buffer, playback_buffer_storage, PLAYBACK_BUFFER_SIZE);
// calc start threshold in bytes for PLAYBACK_START_MS
playback_start_threshold_bytes = (sampling_frequency_hz / 1000 * PLAYBACK_START_MS) * num_channels * 2;
// start playback // start playback
const btstack_audio_sink_t * sink = btstack_audio_sink_get_instance(); const btstack_audio_sink_t * sink = btstack_audio_sink_get_instance();
if (sink != NULL){ if (sink != NULL){
sink->init(num_channels, sampling_frequency_hz, le_audio_connection_sink_playback); sink->init(num_channels, sampling_frequency_hz, le_audio_connection_sink_playback);
sink->start_stream(); sink->start_stream();
} }
} }
static void start_scanning() { static void start_scanning() {
@ -681,6 +692,7 @@ static void stdin_process(char c){
break; break;
#endif #endif
case 'x': case 'x':
app_state = APP_SHUTDOWN;
close_files(); close_files();
printf("Shutdown...\n"); printf("Shutdown...\n");
hci_power_control(HCI_POWER_OFF); hci_power_control(HCI_POWER_OFF);