[XU316] Mic Array Library and >2 mics

Discussions relating to the XK-EVK-XU316
alex4d1
Active Member
Posts: 33
Joined: Mon May 13, 2024 11:38 pm

[XU316] Mic Array Library and >2 mics

Post by alex4d1 »

Hi all,

I have a RTOS application running on XU316 using the mic array library with 2 mics in DDR configuration connected to a 1-bit MIC DATA port.
I modified the decimator stages of the mic array library to sample at 96ksps. This works perfectly.

Now I would like to add more microphones. I switched to a 4-bit port and reconfigured the mic array library to use 8 microphones in DDR configuration, but now rtos_mic_array_rx() call does not return anymore.
If I change the configuration to use a 4-bit port but only use 2 microphones the problem goes away.

This makes me think this is not a problem of the port width but the mic array library itself. The mic array library has only so many parameters, so I am confused on what I am doing wrong.
Does anyone have any suggestions?

Here is snippet of the cmake file of my BSP (4-bit port, only 2 mics):

Code: Select all

    set(MIC_MAPPING "0, 1")

    target_compile_definitions(projects_board_support_config_xcore_ai_explorer_custom
        INTERFACE
            PLATFORM_SUPPORTS_TILE_0=1
            PLATFORM_SUPPORTS_TILE_1=1
            PLATFORM_SUPPORTS_TILE_2=0
            PLATFORM_SUPPORTS_TILE_3=0
            USB_TILE_NO=0
            USB_TILE=tile[USB_TILE_NO]

            MIC_ARRAY_CONFIG_MCLK_FREQ=24576000
            MIC_ARRAY_CONFIG_PDM_FREQ=3072000
            MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME=64
            MIC_ARRAY_CONFIG_USE_DDR=1
            MIC_ARRAY_CONFIG_MIC_COUNT=2
            MIC_ARRAY_CONFIG_MIC_INPUT=8
            MIC_ARRAY_CONFIG_INPUT_MAPPING={${MIC_MAPPING}}
            MIC_ARRAY_CONFIG_USE_DC_ELIMINATION=1
            MIC_ARRAY_CONFIG_CLOCK_BLOCK_A=XS1_CLKBLK_1
            MIC_ARRAY_CONFIG_CLOCK_BLOCK_B=XS1_CLKBLK_2
            MIC_ARRAY_CONFIG_PORT_MCLK=PORT_MCLK_IN
            MIC_ARRAY_CONFIG_PORT_PDM_CLK=PORT_PDM_CLK
            MIC_ARRAY_CONFIG_PORT_PDM_DATA=PORT_PDM_DATA
            # DEBUG_PRINT_ENABLE_RTOS_MIC_ARRAY=1
    )
My custom vanilla implementation:

Code: Select all

using TMicArray = mic_array::prefab::BasicMicArray<
                        MIC_ARRAY_CONFIG_MIC_COUNT,
                        MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME,
                        MIC_ARRAY_CONFIG_USE_DC_ELIMINATION,
                        MIC_ARRAY_CONFIG_MIC_INPUT>;

TMicArray mics;


void ma_vanilla_init()
{
  unsigned input_mic_mapping[] = MIC_ARRAY_CONFIG_INPUT_MAPPING;
  _Static_assert(
        (sizeof(input_mic_mapping) / sizeof(unsigned)) == MIC_ARRAY_CONFIG_MIC_COUNT,
        "The number of elements in MIC_ARRAY_CONFIG_INPUT does not match MIC_ARRAY_CONFIG_MIC_COUNT"
  );
  
  mics.Init();
  mics.SetPort(pdm_res.p_pdm_mics);
  mics.PdmRx.MapChannels(input_mic_mapping);
  mic_array_resources_configure(&pdm_res, MIC_ARRAY_CONFIG_MCLK_DIVIDER);
  mic_array_pdm_clock_start(&pdm_res);
}
My XN file:

Code: Select all

            <!-- Mic related ports -->
            <Port Location="XS1_PORT_1G" Name="PORT_PDM_CLK"/>
            <Port Location="XS1_PORT_4B" Name="PORT_PDM_DATA"/>
And the calls to the mic array library:

Code: Select all

static void mics_init(void)
{
#if ON_TILE(MICARRAY_TILE_NO)
    rtos_mic_array_init(
            mic_array_ctx,
            (1 << appconfPDM_MIC_IO_CORE),
            RTOS_MIC_ARRAY_CHANNEL_SAMPLE);
#endif /* MIC_ARRAY */
}
...
static void mics_start(void)
{
#if ON_TILE(MICARRAY_TILE_NO)
    rtos_mic_array_start(
            mic_array_ctx,
            2 * MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME,
            appconfPDM_MIC_INTERRUPT_CORE);
#endif /* MIC_ARRAY */
}
...
#ifndef appconfAUDIO_FRAME_LENGTH
#define appconfAUDIO_FRAME_LENGTH               (MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME)
#endif /* appconfAUDIO_FRAME_LENGTH */

#ifndef appconfAUDIO_PIPELINE_CHANNELS
#define appconfAUDIO_PIPELINE_CHANNELS          (MIC_ARRAY_CONFIG_MIC_COUNT)
#endif /* appconfAUDIO_PIPELINE_CHANNELS */
...
int32_t input_audio_frames[appconfAUDIO_PIPELINE_CHANNELS][appconfAUDIO_FRAME_LENGTH];
int32_t frame_count = appconfAUDIO_FRAME_LENGTH;
...
frames_received = rtos_mic_array_rx(mic_array_ctx,
                        (int32_t**)input_audio_frames,
                        frame_count,
                        portMAX_DELAY);
Cheers
Alex
User avatar
andrewxcav
Verified
Experienced Member
Posts: 87
Joined: Wed Feb 17, 2016 5:10 pm

Post by andrewxcav »

Hi Alex,

While I don't recommend overclocking long term as you could damage the chip, it might help you to figure out if the mic array task is simply running out of cycles. There should be a .XN file in your board support folder that has a parameter called system frequency. Try bumping this up by 100MHz. and see if that makes everything work.

If it does, then the configuration is all correct, but too slow. You can try reducing the number of concurrent tasks on that tile (which will only help if you have more than 5), or maybe increasing the MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME.

If you are running out of cycles, and it is still a problem with 5 threads running then you can try checking out the maintain/v4 branch of lib_mic_array. This version is less efficient, but incredibly stable and predictable. For every 8 mics you need a task to capture data and for every 4 mics you need a task to decimate, so you would need 3 hardware threads (or logical cores) for your setup, but these will still function with the tile maxed out. This, however, should be a last resort, as the API compatibility will be broken going back a major version.

Cheers,
-Andrew