lib_mic_array @ 192kHz on XCORE AI Explorer Topic is solved

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

lib_mic_array @ 192kHz on XCORE AI Explorer

Post by alex4d1 »

Hi all,

I connected a PDM mic to the MIC ARRAY port of the XCORE AI Explorer board.
Then I compiled/ran the "USB Audio MUX" sample and the microphone showed up on my Win11 system.
I was able to record audio - so far so good.

Then I tried to increase the sampling rate from 16000 to 96000.
I generated a new TwoStageDecimator filter using the provided python script with the following parameter:
  • PDM frequency of 3072000
  • first stage decimation is 32
  • second stage decimation is 1
  • stage #1: number of moving average stages is 5
  • stage #2: cutoff = 45000
  • stage #2: transition bandwidth = 2000
  • taps_2 = 64
  • fir_window = ("kaiser", 8)
I simply overwrote the default settings used by mic_array_vanilla, for fast trial and error.
Unfortunately any configuration where I set the decimation to have 96kHz sampling output the program crashes.

Any filter configuration for 32khz or 48kHz does run and the Explorer board shows up as a microphone in Windows but when I attempt to make a recording a device error pops up.
Did I miss some USB setting that need to be made in order for this to work?.

Only filter configurations for 16kHz work as expected.

After some reading I noticed the following in the feature list of the mic array library:
48kHz, 24kHz, 16kHz, 12kHz and 8kHz output sample rate by default (3.072MHz PDM clock)

But also this statement in the Decimator Stages documentation:
The first stage filter is a decimating FIR filter with a fixed tap count (S1_TAP_COUNT) of 256 and a fixed decimation factor (S1_DEC_FACTOR) of 32.
The second stage decimator is a fully configurable FIR filter with tap count S2_TAP_COUNT and a decimation factor of S2_DEC_FACTOR (this can be 1).


So if stage 1 decimator is fixed to 32 and we are allowed to set stage 2 decimator to 1 then we should be able to get 96khz output, right?

Any help with this is much appreciated.

Thanks
Alex
View Solution
User avatar
xhuw
Verified
New User
Posts: 3
Joined: Wed May 22, 2024 2:36 pm

Post by xhuw »

Hi Alex,

Unfortunately, the mic_array_vanilla API uses mic_array::prefab::BasicMicArray which hard codes the decimation factors to the values in the default filter bank.

Vanilla mic array class: https://github.com/xmos/lib_mic_array/b ... la.cpp#L97
prefab decimator config: https://github.com/xmos/lib_mic_array/b ... b.hpp#L338
default filter values: https://github.com/xmos/lib_mic_array/b ... ault.h#L74

Therefore if you want alternate decimation factors then you will need to construct a custom MicArray (https://github.com/xmos/lib_mic_array/b ... ay.hpp#L58).

Your basic plan of changing the decimation factors is a good one. I will look for an example that does what you want.

If you could clarify if you want 192kHz or 96kHz that would also be useful

Thanks

Huw

XMOS Software Engineer
alex4d1
Member++
Posts: 18
Joined: Mon May 13, 2024 11:38 pm

Post by alex4d1 »

Hi Huw,

Thanks for getting back to me on this so quickly.

Yes, this is exactly what I did. I generated the coefficients using the python scripts design_filter.py and stage1.py/stage2.py.
Then I replaced in default_filter.h the following parameters
- changed STAGE2_DEC_FACTOR to 1
- changed STAGE2_TAP_COUNT to 64
according to my custom filter.

I also replaced the coefficients as well as the "stage 2 right shift" in stage1_fir_coef.c/stage2_fir_coef.c with the ones generated with stage1.py/stage2.py.

Generally I'd need it to work with 96kHz. If you could provide me an example for that would much appreciated.

There might be a future application where we want to run it at 192kHz. Is 192kHz even feasible if the stage 1 decimation factor is fixed at 32 and my microphone doesn't allow PDM frequencies higher than 4.8MHz (microphone used: Knowles SPH0641LU4H-1)?

Also, does anything prevent me from using the Audio MUX example with PDM mic (mic array) input and USB output and sampling rates higher than 16kHz? Specifically 96kHz/192kHz?

Thanks
Alex
User avatar
xhuw
Verified
New User
Posts: 3
Joined: Wed May 22, 2024 2:36 pm

Post by xhuw »

Hey Alex,

There aren't any existing demos which run at 96kHz. However, I put together a quick one myself which shows that the mic array will happily output 96kHz (see link).

96kHz example, needs filter design as well as port updates (I made it for the XK-VOICE-SQ66 board which I have with me) https://github.com/xhuw/mic_array_96kHz ... p/main.cpp

It is critical that the rest of your application is also updated to read from the mic_array thread at the correct rate.

> Is 192kHz even feasible if the stage 1 decimation factor is fixed at 32 and my microphone doesn't allow PDM frequencies higher than 4.8MHz (microphone used: Knowles SPH0641LU4H-1)?

I expect it can be done, but it will be more involved as you will have to write your own Decimator stage, as you noted it is hardcoded at the moment to have a decimation factor of 32 in the first stage.

If you provide a link to the mux example I can have a look.

Huw
alex4d1
Member++
Posts: 18
Joined: Mon May 13, 2024 11:38 pm

Post by alex4d1 »

Thanks Huw.

Here is the Audio MUX example I based my experiments on:
https://github.com/xmos/xcore_iot/tree/ ... /audio_mux

Other than the changes to the lib_mic_array to get my custom filter integrated I made the following 2 changes to the Audio MUX project:

xcore_iot\examples\freertos\audio_mux\bsp_config\XCORE-AI-EXPLORER\platform\platform_conf.h
#define appconfPIPELINE_AUDIO_SAMPLE_RATE 96000
xcore_iot\examples\freertos\audio_mux\src\app_conf.h
#define appconfAUDIO_PIPELINE_SAMPLE_RATE 96000
alex4d1
Member++
Posts: 18
Joined: Mon May 13, 2024 11:38 pm

Post by alex4d1 »

Hi Huw,

Quick update: I took your example and adjusted it for the explorer board and added my custom filter. I am able to verify with my oscilloscope that the processing thread toggles the selected port at 96kHz.

Next step would be to get the Audio MUX example working,
but I have little success.
The Audio MUX example is based on FreeRTOS and allows me to enumerate the setup as a USB microphone on my Windows. I start to get a feeling that maybe the RTOS or USB is causing my troubles.

If you could have a look at the Audio MUX example that would be greatly appreciated

Thanks
Alex
User avatar
xhuw
Verified
New User
Posts: 3
Joined: Wed May 22, 2024 2:36 pm

Post by xhuw »

Hi Alex, It seems like you are on the right track.

I am not familiar with this example so I will ask around. One thought I have is that there are issues with changing sample rates of a USB device on Windows as it caches the driver settings. Deleting the driver might trigger it to behave.

1. Open device manager
2. View -> Show hidden devices
3. find the driver and uninstall it.

If that doesn't work then we will be in the weeds of debugging the system to find out.

If the device enumerates then you can can find your device in "Sound Settings" -> "Sounds control panel" and check what sample rate it has enumerated with.

Huw
alex4d1
Member++
Posts: 18
Joined: Mon May 13, 2024 11:38 pm

Post by alex4d1 »

Hi Hew,

I've tried re-enumerating the windows driver but had no success.

As mentioned in my initial post I do see 2 problems:
1) If I set the Audio MUX example to audio rates 32000 or 48000 (and use one of the preconfigured filter examples in design_filter.py: good_32k_filter/good_48k_filter) the application runs and the device shows up in Windows, however applications are not able to access the device and are throwing a device exception.
2) If I set the Audio MUX example to audio rate 96000 (and adjust the filter accordingly) the application crashed immediately after bootup in the pdm_rx_isr()

Uninstalling and re-enumerating the device driver didn't help neither of the two issues observed.

Thanks
Alex
alex4d1
Member++
Posts: 18
Joined: Mon May 13, 2024 11:38 pm

Post by alex4d1 »

Ok a little more progress.

Got the Audio MUX sample now working at 48000.

I changed in tusb_config.h AUDIO_FRAMES_PER_USB_FRAME to (appconfUSB_AUDIO_SAMPLE_RATE / 6000)
and changed line 69 in usb_audio.c to
#define USB_FRAMES_PER_VFE_FRAME (appconfAUDIO_PIPELINE_FRAME_ADVANCE / (appconfAUDIO_PIPELINE_SAMPLE_RATE / 6000))

The problem with 96000 still remains, the applications crashes immediately after start in the pdm_rx_isr(). It seems unrelated to USB or Audio Pipeline, looks like something is not configured correctly on the PDM side.

Thanks
Alex
alex4d1
Member++
Posts: 18
Joined: Mon May 13, 2024 11:38 pm

Post by alex4d1 »

Ok I finally figured it out what caused it to crash.

I had to set the MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME to 40 and then it worked.

I basically divided MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME by 6 and multiplied AUDIO_FRAMES_PER_USB_FRAME and USB_FRAMES_PER_VFE_FRAME by 6, 6 because 16000 * 6 = 96000.

It would be very helpful to have some documentation explaining the interactions of parameters like MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME and the sampling rate, and it would be good to remove magic numbers used to define AUDIO_FRAMES_PER_USB_FRAME and USB_FRAMES_PER_VFE_FRAME.

Only problem now is that the Windows driver doesn't seem to support 96kHz (I think). The device driver shows the following error code:
This device cannot start. (Code 10)

The specified range could not be found in the range list.
Thanks
Alex