Invalid pcm_bytes_req returned from API for LC3 encoder 8ksps configuration.

Hi,

I am in progress of making own audio application. I wanted to try 8_2 configuration. I see however, that despite that, 10ms window worth of data at that sample rate should be 160 i get 320 as a requirement from sw_codec_lc3_enc_init API call. Also i see, that 24000 kbps, while should be a valid value produces log warning.

I am using NRF SDK ver 2.9.2

Why is it like that?

  • Hi,

    Could you show me how you are using the 8_2 configuration? Are you using SDC? Could you show me this log with the warnings?

    Regards,

    Elfving

  • I have made a code to quickly evaluate operation of various configurations.

    #include "sw_codec_lc3.h"
    
    #define FRAME_SIZE (10000U)
    #define STNDRD_SDU (30U)
    #define BITRATE    (24000U)
    #define BITE_SIZE  (160U)
    #define SAMPLERATE (8000U)
    
    void codec_test()
    {
    	int ret = 0;
    	int sample_rate = SAMPLERATE;
    
    	ret = sw_codec_lc3_init(NULL, NULL, FRAME_SIZE);
    
    	if (ret != 0) {
    		LOG_ERR("Failed to initialize LC3 codec %i", ret);
    		return;
    	}
    	
    	uint16_t req_bytes = 0;
    	ret = sw_codec_lc3_enc_init(sample_rate, 16, FRAME_SIZE, BITRATE, CONFIG_PEER_LIMIT + 1, &req_bytes);
    
    	if (ret != 0) {
    		LOG_ERR("Failed to initialize LC3 encoder %i", ret);
    		return;
    	}
    
    	LOG_INF("LC3 encoder initialized successfully, %i bytes required", req_bytes);
    
    	req_bytes = 0;
    	ret = sw_codec_lc3_dec_init(sample_rate, 16, FRAME_SIZE, CONFIG_PEER_LIMIT + 1);
    
    	if (ret != 0) {
    		LOG_ERR("Failed to initialize LC3 decoder %i", ret);
    		return;
    	}
    
    	LOG_INF("LC3 decoder initialized successfully", req_bytes);
    
    	// Initialize the test tone buffer
    	ret = tone_gen(test_tone_buf, &test_tone_size, 200, sample_rate, 0.05f);
    	if (ret != 0) {
    		LOG_ERR("Failed to generate test tone %i", ret);
    		return;
    	}
    
    	
    	// Calculate how many fill-ins are required
    	int fill_ins = ((2 * 48000 / 100) / test_tone_size);
    	LOG_INF("Fill ins %i", fill_ins);
    	// Duplicate the test tone buffer
    	for (int fill_in = 1; fill_in < fill_ins; fill_in++) {
    		memcpy(((uint8_t*)test_tone_buf )+ fill_in * test_tone_size, test_tone_buf, test_tone_size);
    	}
    
    	int64_t tmp, tick_counter;
    	uint8_t out_dat[BITE_SIZE];
    	uint8_t* ptr;
    	
    	tmp = k_uptime_ticks();
    	tick_counter = 0;
    	ptr = test_lc3_buf;
    	for(int i = 0; i < 100; i++){
    		tmp = k_uptime_ticks();
    		sw_codec_lc3_enc_run(test_tone_buf, BITE_SIZE, BITRATE, CONFIG_PEER_LIMIT, STNDRD_SDU, ptr, &test_lc3_siz);
    		tick_counter += (k_uptime_ticks() - tmp);
    
    		ptr += STNDRD_SDU;
    		k_msleep(10);
    	}
    
    	LOG_INF("Encode took %lli ticks per 100 calls. Average time: %8.3f us", tick_counter, ((float)tick_counter * 10000.0f / (float)CONFIG_SYS_CLOCK_TICKS_PER_SEC));
    
    
    	int dec_size;
    
    	tmp = k_uptime_ticks();
    	tick_counter = 0;
    	ptr = test_lc3_buf;
    	for(int i = 0; i < 100; i++) {
    		tmp = k_uptime_ticks();
    		sw_codec_lc3_dec_run(ptr, STNDRD_SDU, BITE_SIZE, CONFIG_PEER_LIMIT, out_dat, &dec_size, false);
    		tick_counter += (k_uptime_ticks() - tmp);
    
    		ptr += STNDRD_SDU;
    		k_msleep(10);
    	}
    
    	LOG_INF("Decode took %lli ticks per 100 calls. Average time: %8.3f us", tick_counter, ((float)tick_counter * 10000.0f / (float)CONFIG_SYS_CLOCK_TICKS_PER_SEC));
    
    	k_msleep(10);
    	k_msleep(10);
    
    	while (1)
    	{
    		k_sleep(K_SECONDS(1));
    	}
    }


    Values for configuration are taken from "Introducing Bluetooth® LE Audio" by Nick Hunn.

    I am very confused now - I double checked everything and it now seems to work, but it still produces warning.

    [00:00:00.425,598] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x20fd
    [00:00:00.425,628] <inf> cap_initiator: Bluetooth initialized
    [00:00:00.434,722] <wrn> sw_codec_lc3: LC3 enc_bitrate: 24000 : likely too low
    [00:00:00.436,401] <inf> cap_initiator_tx: LC3 encoder initialized successfully, 160 bytes required
    [00:00:00.437,896] <inf> cap_initiator_tx: LC3 decoder initialized successfully.

  • And this is with the nordic softdevice (SDC) enabled? And I assume its not based on any audio application in particular?

    Regards,

    Elfving

  • It couldn't be - as any of your audio applications are not meant to work with 8 khz sample rate.

    Softdevice is enabled, but i don't see why would it be relevant to this case.

  • Ah that is true, thought it was releated to the controller for a second. There is often confusion regarding what the Zephyr controller and SDC supports. Sorry about that. 

    I see however, that despite that, 10ms window worth of data at that sample rate should be 160 i get 320 as a requirement from sw_codec_lc3_enc_init API call.

    I believe this is because it uses 2bytes per sample.

    Also i see, that 24000 kbps, while should be a valid value produces log warning.

    #define ENC_BITRATE_WRN_LVL_LOW 24000
    ..
    	if (enc_bitrate == 0) {
    		LOG_ERR("LC3 enc_bitrate is 0");
    		return -EINVAL;
    	} else if (enc_bitrate <= ENC_BITRATE_WRN_LVL_LOW) {
    		LOG_WRN("LC3 enc_bitrate: %d : likely too low", enc_bitrate);
    	} else if (enc_bitrate >= ENC_BITRATE_WRN_LVL_HIGH) {
    		LOG_WRN("LC3 enc_bitrate: %d : likely too high", enc_bitrate);
    	}

    I see here that 24000 kbps should be on the verge of "too low", though it is good that it works. Are you wondering why we are considering it as such?

    Regards,

    Elfving

Related