LC3 encoding compression issue of stereo mode

Hi NRF team,

I am working on one project. I have used 2 PDM Microphones (MMICT5838-00-012). And I have used Zephyr RTOS for development.

I have used the LC3 encoding and decoding method in my application. Encoding and decoding both are working as expected in Mono mode.

But it is not working in stereo mode.

Stereo mode Mic configuration:  Sample rate: 16000Hz, Bit depth of 1 sample: 16bits, audio frame duration: 10000us, bitrate: 32000bps, total number of  channels: 2 channel(s)

I am getting an error from the LC3EncodeSessionOpen API. I am getting an LC3_RESULT_INSUFFICIENT_RESOURCES error code.

My observation is that once firmware calls LC3EncodeSessionOpen the second time for the second channel, it will trigger the LC3_RESULT_INSUFFICIENT_RESOURCES error code.

My project configurations:

CONFIG_MAIN_STACK_SIZE=32768
CONFIG_HEAP_MEM_POOL_SIZE=32768
CONFIG_MICROPHONE=y
CONFIG_AUDIO=y
CONFIG_AUDIO_DMIC=y
CONFIG_AUDIO_DMIC_LOG_LEVEL_DBG=n
CONFIG_NRFX_PDM_LOG=n
CONFIG_DMA=y
CONFIG_MAX_PCM_SAMPLE_RATE=16000
CONFIG_SAMPLE_BIT_WIDTH=16
CONFIG_CHANNEL_COUNT=2
CONFIG_PRIMARY_CHANNEL=1
CONFIG_SH_LC3_CODEC=y
CONFIG_FPU=y
CONFIG_LIBLC3=y
CONFIG_PSCM=y
CONFIG_SW_CODEC_LC3_T2_SOFTWARE=y
CONFIG_CMSIS_DSP=n
# CONFIG_CMSIS_DSP_FASTMATH=n
# CONFIG_CMSIS_DSP_TABLES=n
CONFIG_LC3_ENC_CHAN_MAX=2
CONFIG_LC3_DEC_CHAN_MAX=2

What could be the probable reason for this error? I have allocated a huge stack and heap in the memory and also tweaked some parameters like sampling rate and bit depth. But still, I am facing the same issue.

  • Hi, 

    Are you using nRF5340DK or nRF53 Audio DK?
    Are you using NCS or vanilla Zephyr? What is the version number?

    Regards,
    Amanda H.

  • Hi Amanda H,

    I have a custom PCBA, and I have used nrf5340 MCU. I am using NCS in Zephyr. NCS version is 2.6.1

  • Hi Amanda H,

    I read the documentation and looks like if LC3EncodeSessionOpen API is not able to allocate required memory then it will trigger LC3_RESULT_INSUFFICIENT_RESOURCES issue.

    As of now in SDK we are calling LC3EncodeSessionOpen API based on channel number and in my case number of channels are 2.

    So I have modified the logic of sw_codec_lc3_enc_init API to temporary allocate the static memory for second channel in this manner.

    uint8_t data[2][4096];
    int sw_codec_lc3_enc_init(uint16_t pcm_sample_rate, uint8_t pcm_bit_depth, uint16_t framesize_us,
    uint32_t enc_bitrate, uint8_t num_channels, uint16_t *const pcm_bytes_req)
    {
    int ret;
    uint16_t data_size = 4096;
    LC3FrameSize_t framesize;
    uint16_t size = 0;

    switch (framesize_us) {
    case 7500:
    framesize = LC3FrameSize7_5Ms;
    break;
    case 10000:
    framesize = LC3FrameSize10Ms;
    break;
    default:
    LOG_ERR("Unsupported framesize: %d", framesize_us);
    return -EINVAL;
    }

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

    enc_pcm_bytes_req = LC3PCMBuffersize(pcm_sample_rate, pcm_bit_depth, framesize, &ret);
    *pcm_bytes_req = enc_pcm_bytes_req;

    LOG_ERR("**lC3 buffer size error: %d and size: %d***", ret, *pcm_bytes_req);

    if (enc_pcm_bytes_req == 0) {
    LOG_ERR("Required PCM bytes to encode LC3 is zero.");
    return -EPERM;
    }

    for (uint8_t i = 0; i < num_channels; i++) {
    if (enc_handle_ch[i]) {
    LOG_ERR("LC3 enc ch: %d already initialized", i);
    return -EALREADY;
    }
    LOG_ERR("****Channel count: %d***", i);
    if(i == 0)
    {
    enc_handle_ch[i] = LC3EncodeSessionOpen(pcm_sample_rate, pcm_bit_depth, framesize,
    data[i], &data_size, &ret);
    if (ret) {
    LOG_ERR("**lC3 open session API error: %d***", ret);
    return ret;
    }
    }
    else if(i == 1)
    {
    enc_handle_ch[i] = LC3EncodeSessionOpen(pcm_sample_rate, pcm_bit_depth, framesize,
    data[i], &data_size, &ret);
    if (ret) {
    LOG_ERR("**lC3 open session API error: %d***", ret);
    LOG_ERR("***Buffer size is : %d*****", size);
    return ret;
    }
    }
    }

    m_enc_bitrate = enc_bitrate;

    enc_num_instances = num_channels;

    return ret;
    }

    And after this change I am able to encode the stereo channel data. Now I will validate the data. I am getting proper length of stereo data.

    Can you please check the changes which I have made. Because I don't know how it impact the overall library.

Related