Jump to content
  • 0

How to interpret pmod mic3 data?


skandigraun

Question

Hi,

this is my first try to interact with a chip, so please bear with me if my question is dumb. I'm using Basys3 with the pmod MIC3.

The ADC gives back 4 leading zeros and 12 bits of data. I can get this out of pmod. But how to interpret this data? I understand the main principle of the ADC - I get a relative value between 0 and 2^12. The pmod's reference says that this value is representative of the volume and frequency. I assume that this is a kind of composite value, like X high bits are the frequency, and the rest are for volume, or similar - but couldn't find anything about such things. I was looking at all reference documentation and sample codes I could find, but maybe I was looking at wrong places.

How do I get the volume and frequency separately out of the retrieved 12 bit value?

Thanks

Edited by skandigraun
Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 1

@skandigraun,

I'm not a physicist, so others might correct me here, but has I understand things audio waves are compression waves.  To "read" them, you need to create a diaphragm that will move as the compression wave moves, and then you can read the position of this diaphragm over time.  The PMic does this with a MEMS microphone.  Consider this to be the meaning of those twelve bits.

Be careful with that twelfth  bit: it is a sign bit.  You may need to extend it to the left some to understand it properly.  For example, { int v; v = (sample<<20)>>12; }.

It is possible to get volume by simply averaging the absolute values of the various samples.  While crude, the estimate should work.

Getting frequency is harder.  Doing that requires a Fourier transform.  However, sound is very often composed of many frequencies, as the attached picture shows.  In that picture, time goes from left to right, frequency from bottom to top, and energy comes out of the page.  It's taken from the opening of the Cathedral's recording of "Echoes from the Burning Bush."  The clip starts with laughter, but otherwise has speech within it.  I would particularly draw your attention to how speech has a fundamental frequency associated with it, followed by many harmonics of that same frequency--as shown in the picture.  The result is that it can be difficult to say which frequency is in use, as many are present at the same time.

One of the book's I have on my shelf is Cohen's "Time Frequency Analysis."  In it, Leon Cohen goes through and compares many algorithms for frequency evaluation.  At one time I had a paper written that proved that the Short Time Fourier Transform, among his list but widely criticized, was the *only* frequency estimation problem that preserved certain key properties of spectral energy estimation: 1) all energy values should be non-negative, 2) all frequency shifts should produce frequency shifts in the estimation, 3) time shifts should produce time shifts in the estimate, and 4) that the estimate have and achieve the "best" time-frequency resolution as measured by the uncertainty function.  Perhaps I'll find a venue for publishing it in the future.  For now, you might wish to study the discrete time Short Time Fourier Transform, which is appropriate for the data coming out of the PMic.

At one time, I tried to build a digital tuner from sampled data.  Such a tuner requires exactly what you are asking for: knowing the frequency of the incoming data.  Further, it requires the assumption that there is only one incoming frequency, even when multiple are present (as the diagram shows).  To get there, I evaluated the autocorrelation signal that I got by taking the Inverse Fourier Transform of the magnitude squared of the output of a Fourier transform, and looking for the biggest peak.  This operation, taking place in time, usually but not always found the fundamental frequency I was looking for.

One more thought: you can find forward and inverse Fourier transform code, in Verilog, here, just in case you need it.  ;)

Hope that helps,

Dan

burning-bush.png

Link to comment
Share on other sites

  • 0

I wad looking to do something on this also. Just thinking on the best approach. One that I am thinking of its using some sort of machine learning. I am thinking of playing a musical note and getting my basys 3 to figure out what note it is. 

My thinking is to play each note and get say 1000 samples of each note. Check what bits are 1 and 0. So, if my 1000 samples of a C have bit0 switched on 60% Of the time, bit1 is on 90% Of the time, bit2......the 1000 samples are stored in memory. If then a note is played, the board checks the sample of the note being played against the samples in memory. It checks all the 12 bits for this and if bit0 is on 61% and bit1 is on 89%..... there is a strong possibility it's the C. 

Would this sound like a possible way to check for frequency?

As I say, this is just a thought. 

Link to comment
Share on other sites

  • 0

@Davie,

No, I don't think that will work.  You can read many of my thoughts above.  How about this, though: Why not build it, and try it, and then share with us the things you learned in the process?  I'd be willing to look over anything you post, and see if I can offer any insights into things you get confused with along the way.

Dan

Link to comment
Share on other sites

  • 0

For an appropriate processing of a MEMS PDM datastream (not I2S data stream)  a good filter is required. Averaging only will cause a lot of alias frequencies to pass the filter.
The same is with the Hogenauer CIC (often called SINC) which is not a good SINC at all.

A cost effective Filter can be built in any PLD with an IIR like this:

SUM = (65536 * NEW  + 1023 * SUM) / 1024

leading to Value with 16 Bit quality and an edge frequency of ~/512  (for a <5MHz PDM here around  10kHz).

 

 

Link to comment
Share on other sites

  • 0

@D@n

Hi Dan. Thanks for writing the comprehensive code! It was very helpful! I tried using your code for the FFT, but I get this error while generating bitstream on my Vivado. Are we supposed to change the code in butterfly.v in order to resolve this?

Thanks for any input!

 

[DRC LUTLP-1] Combinatorial Loop Alert: 1 LUT cells form a combinatorial loop. This can create a race condition. Timing analysis may not be accurate. The preferred resolution is to modify the design to remove combinatorial logic loops. If the loop is known and understood, this DRC can be bypassed by acknowledging the condition and setting the following XDC constraint on any one of the nets in the loop: 'set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets ]'. One net in the loop is nolabel_line52/stage_16/FWBFLY.bfly/p3/GENSTAGES[5].genmpy/o_r_reg[25]_0. Please evaluate your design. The cells in the loop are: nolabel_line52/stage_16/FWBFLY.bfly/p3/GENSTAGES[5].genmpy/omem_reg_i_1__0.

Link to comment
Share on other sites

  • 0

There should be no combinatorial loops within the design.  (If there were, I'd fix them ...)

Can you post the generated design you are using somewhere?  And (even better) can you list/find all the components of this loop?  One thing that doesn't make sense from your comment above is that the *genmpy_o_r_reg[25]_O bit is an output of a flip-flop.  I wouldn't expect that in a combinatorial loop, but maybe it starts the loop?  Again, that'd be why I'd want to see the logic you've generated if you could post it somewhere for evaluation.

Thanks!

Dan

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...