Frequency range and other recording issues with Matrix Voice

#1

I just got my Matrix Voice and soon after the initial setup ran into issues with frequency range and sampling rate. Please excuse my ignorance if I missed something obvious since I am new to this.

1) Audio recorded with arecord at 48kHz sampling rate:

Recording command:
arecord -c 8 -f S16_LE -r 48000 -d 5 fs48000.wav

Observations:

Questions:

  • Why are no frequencies above 15kHz present in the recording? The MP34DB02 mems microphones used by Matrix Voice have the frequency range of 20Hz-20kHz according to this datasheet (see 2.3 Frequency response paragraph).

2) Audio recorded with arecord at 96kHz sampling rate:

Recording command:
arecord -c 8 -f S16_LE -r 96000 -d 5 fs96000.wav

Observations:

  • The “overrun” warnings are often reported during recording:

    Recording WAVE ‘fs96000.wav’ : Signed 16 bit Little Endian, Rate 96000 Hz, Channels 8
    overrun!!! (at least 0.939 ms long)
    overrun!!! (at least 0.960 ms long)

  • Similarly as when using the 48kHz sample rate, frequencies above 15kHz are not present in the recording.
  • The recorded audio contains crackling noises not present in the original audio.

Questions:

3) Audio recorded with mic_record_file (from matrix-hal-examples) at 48kHz sampling rate:

Recording command:
matrix-hal-examples/build/microphone_array/mic_record_file --duration 5 --sampling_frequency 48000

Observations:

  • Audible crackling noise can be heard every second.
  • Frequencies above 1700Hz are mostly not present in the recording, except of a spike at 15kHz. This is clearly visible in the attached spectrogram:
  • After I finished recording with mic_record_file, it was not possible to use arecord any more, because the latter reported the following error: arecord: main:788: audio open error: Device or resource busy

Questions:

  • Why are only frequencies up to 1700Hz present in the recording?
  • What causes the crackling noises every second? In mic_record_file.cpp I see a loop running a new iteration each time the sampling rate number of samples is recorded (i.e. every second), but I still don’t understand how this causes the crackling noises.
  • Would it be possible to update the mic_record_file.cpp to properly close the grabbed resources to get rid of the Device or resource busy error when subsequently attempting to use arecord?

4) Audio recorded with mic_record_file (from matrix-hal-examples) at 96kHz sampling rate:

Recording command:
matrix-hal-examples/build/microphone_array/mic_record_file --duration 5 --sampling_frequency 96000

Observations:

  • The recorded audio was not 5s long at 96kHz, but for 10s long at 48kHz with halved pitch.
  • The recorded audio has lots of crackling noise.

Questions:

  • How to update mic_record_file.cpp to fix the issue with duration and pitch?

Note:

Recording with sox has exactly the same issues as recording with arecord.

That’s all for now. Apart from the problems mentioned here, I was very pleased with how smooth the setup of the device was and the quality of the online help and documentation. Thank you for your awesome work!

0 Likes

#2

Hi @minkowski, welcome to MATRIX Community!

Thanks for taking the time and provide good details in the post. I will try to respond to all of your questions one by one :).

  1. You are right about this. These microphones have 20-20K freq range. There is a low-pass filter at 15Khz ( for 48KHz sample rate ) being applied by default. You should be able to change the FIR filter parameters from the HAL library using documentation here. Another resource is in this HAL example using the SelectFIRCoeff() function.

One question for you: I didn’t any reference in the post but I assume you are using the kernel module package right?

Please, give me some more time to respond to the other questions.

-Yoel

0 Likes

#3

If you installed the kernel modules package the highest frequencies that implementation is currently supporting is 48KHz. We are working on adding support for 96KHz in the future. Not sure if that is the reason behind the overrun, I’ll reproduce this and look into it more.

Do you specifically need 96 KHz?

-Yoel

0 Likes

#6

Thanks for quick reply!

1) I’ve installed the following packages. Does this mean that I am using the kernel modules package?

sudo apt-get install matrixio-creator-init libmatrixio-creator-hal libmatrixio-creator-hal-dev
sudo apt install matrixio-kernel-modules
sudo apt-get install matrixio-malos

What was the reasoning behind low-pass filter at 15kHz (for 48kHz sample rate)? Was the audio recorded between 15kHz and 20kHz too distorted?

From your reply I understand that I could change the FIR filter parameters by using your HAL library and record audio programatically. Can I also somehow change the FIR filter parameters that affect the audio received by arecord?

Update from 3/23:

I tried to record audio with the github version of mic_demo_fir_direct.cpp. First I commented out the following line from the /boot/config.txt to disable the kernel modules package (was this the right way to disable it?):

#dtoverlay=matrixio

Btw, If I don’t do this, I get the “Kernel Modules has been loaded. Use ALSA examples” error when I try to run mic_demo_fir_direct.cpp. Where are these ALSA examples?

After reboot I recorded a few seconds of me singing with mic_demo_fir_direct.cpp using the following command:

./mic_demo_fir_direct --duration 5 --sampling_frequency 48000

The spectrum analysis performed with Audacity showed that there were no frequencies above 5000Hz present in the recording (except of a big spike close to the Nyquist frequency, which should be probably ignored, since it is outside of the declared microphone frequency range):


I don’t know exactly how Audacity computed the spectral envelope - it seems that it cuts off energies below certain threshold. Therefore I computed the spectral envelope for the same audio clip “manually” in Python, and got this result:
spectral_envelope_python
Ignoring the part below the Audacity’s threshold, the envelopes seem consistent between Audacity and Python.

Then I turned the FIR filter specified in mic_demo_fir_direct.cpp off by following the advice from this post, which said that this can be done by setting the FIR coeffs to [1 0 0 0 … ] via the SetCustomFIRCoeff function.

Here is my code snippet:

// mic_core.SelectFIRCoeff(&FIR_bandpass[0]);
std::valarray<int16_t> filter_taps(matrix_hal::kNumberFIRTaps);
filter_taps[0] = 1;
mic_core.SetCustomFIRCoeff(filter_taps);

But the audio recorded with this setup was completely quiet. Did I do anything obviously wrong?

To summarize, I still don’t know how to record audio at 48kHz to use the full 20Hz-20kHz microphone bandwidth, not to mention that 96kHz sampling rate just doesn’t work, although it is advertised here and was one of my reasons for buying this particular microphone array board (I’ve realized that 96kHz sampling rate in fact doesn’t work only after starting to dig into support forums). For example, is it possible to use ALSA without any FIR filter, which I could apply explicitly as a post-processing step?

I would appreciate a lot if you would help me with figuring out how to record the full 20Hz-20kHz microphone bandwidth.

0 Likes

#7

2) I would like to have 96kHz sampling rate because I believe it would enable more accurate beamforming than 48khz.

You said that if I installed the kernel modules package, then the highest frequencies that implementation is currently supporting is 48KHz. Does this imply that I could use 96kHz sample rate if I would not install the kernel modules package?

Could in this case I still use arecord to record audio from Matrix Voice? My understanding it that I couldn’t, but I am not sure.

0 Likes

#8

Hi Yoel, are you still looking into this? I would really appreciate if you could help me with the following questions:

  1. Is it possible to capture Matrix Voice microphones with ALSA without using any FIR filter preprocessing to avoid eliminating frequencies in 15kHz-20kHz range?

  2. How to avoid periodic crackling noise that appears every second when recording without ALSA?

  3. Is 96kHz sampling rate supported or not? As noted above, different docs and forum posts from your site provide conflicting answers to this. You have already clarified that if I installed the kernel modules package, then the highest frequencies that implementation is currently supporting is 48KHz. What about if I had not installed then kernel modules package? Would I be able to record at 96kHz in this case?

0 Likes

#9

Hi @minkowski,

Sorry for the late reply on this issue. Find bellow some answers:

  1. The easiest way right now would be modifying the FIR filter parameter, similar to what you did above, but I would recommend to do it in the kernel modules code so in that way you avoid the cracking you mentioned. The steps for this are:
...
{ 48000, { 
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0, 32767,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0}},
....

you can also use these values for other frecuencies if you like.

  • Follow instructions of Option 2: for compiling from sources and installing
  • Don’t forget the final step of adding dtoverlay=matrixio to /boot/config.txt.
  • Finally reboot.

I recognize that there should be a better way of doing this and that many user will like better to have audio as raw as possible. We would include this recommendation in next releases. Thank for sharing all the details and taking time to play and test this in depth.

Also there is a matlab/octave script for generating the FIR filter parameters here. Let me know if you try this and need any help using it.

Please let me know if this method worked.

  1. Regarding the question about the cracking. I was able to reproduce that at 48kHz using the C++ example in HAL. That’s new for us and something that will be improved. This very simple examples on how to get data from the MATRIX Voice/Creator and it seems that for 48kHz some data from the mics gets lost. A better way of getting audio from C++ would be have the kernel modules running and use ALSA C++ library, take a look here https://www.alsa-project.org/alsa-doc/alsa-lib/examples.html

  2. Regarding the 96kHz support. Both HAL and the kernel modules currently have issues with this sampling rate as you have noticed. The issue is related to bandwidth limitation on the SPI bus that we are working on. Thanks for the heads up here, we will update the documentation.

Thank you,

-Yoel

0 Likes

#10

Hi Yoel, thanks a lot for your help!

Here are my findings:

  1. I was able to turn off the FIR filter preprocessing for ALSA following your recipe (yay! :slightly_smiling_face:). Here is the resulting spectral density chart for all microphones, it worked as expected:
    fir_nop
    Then I’ve tried to experiment with your FIR_coeff_generation.m script for generating the FIR filter parameters (using octave), however, this didn’t work as expected. Even when using the version of this script at github head, which specifies a 200Hz-19kHz bandpass filter for 48kHz sampling rate, I got neither recordings matching the 200Hz-19kHz band, nor result exactly matching the values in the fir_coeff.h file submitted at github head. Here is the spectral density chart for all microphones using the FIR filter generated by the FIR_coeff_generation.m at the current github head:
    fir_generated
    Obviously, but strangely, the upper cutoff frequency is at 15kHz and not at 19kHz as specified by the script.

  2. Thank you for the pointer to the ALSA C++ library examples.

  3. Regarding the issues with 96kHz support, I’ve noticed that even when capturing from all eight microphones at 48kHz, sometimes the following error occurs (though very rarely):

    pi@raspberrypi:~/tmp $ arecord -D sysdefault:CARD=2 -c 8 -f S16_LE -r 48000 -d 5 test.wav
    Recording WAVE ‘test.wav’ : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 8
    overrun!!! (at least 67.645 ms long)

    I don’t know much about this, but is it possible that audio buffer in FPGA is too small (as discussed here)?

0 Likes