Go Down

Topic: Audio Codec Shield output as dB (Read 2943 times) previous topic - next topic

fabiensen

Hi,

we are waiting for Audio Codec Shield to be shipped to our lab. The product webpage is at http://www.openmusiclabs.com/projects/audio-codec-shield/arduino-audio-codec-shield/index.html

What we will be trying to do is to have a microphone giving input to this board and have the output measured in dB.

Before to buy this shield, we had only the microphone MAX4466 giving output directly in the sketch, but this way was judged not trustable as the Arduino YUN can't elaborate sound up to 44 kHz (it is up to 10 kHz).

We could not find any document on their website nor anywhere in forums.

Does anyone have an idea how to proceed or some documents addressing us to the solution?

Regards
Fabio


Grumpy_Mike

Quote
Before to buy this shield, we had only the microphone MAX4466 giving output directly in the sketch, but this way was judged not trustable as the Arduino YUN can't elaborate sound up to 44 kHz (it is up to 10 kHz).
That is a very odd statement. Why can you not trust the amplitude of the sound samples at a sample rate of 10KHz. This will allow any sample frequency up to 5KHz.

The YUN is a hybrid board consisting of a traditional Arduino and a Linux box.

Quote
What we will be trying to do is to have a microphone giving input to this board and have the output measured in dB.
dBs in relationship to what? A decibel is a ratio so you will get the output of the microphone as a ratio to what?

DVDdoug

#2
Nov 02, 2016, 03:34 pm Last Edit: Nov 02, 2016, 03:41 pm by DVDdoug
Quote
What we will be trying to do is to have a microphone giving input to this board and have the output measured in dB.
You'll need to calibrate it* using a known-good SPL meter and a test-tone or pink or white noise.

For example, if the SPL meter reads 92dB SPL and the Arduino's ADC reads 500,** that becomes your reference.*** 

Now that you have a reference, you can calculate dB relative  to that reference: dB = 20log(ADCx/ADCRef).

If 92dB was 500 and the new reading is 250, we would calculate -6dB.   So, we have 92 - 6 = 89dB SPL.

Note that SPL measurements are normally averaged and weighted.   That's difficult to do with a homemade SPL meter so your readings may differ from a real SLP meter, even after calibration.




* If you have the sensitivity specs for the microphone you can calculate the voltage (including the gain from the preamp) and make the dB SPL calculation from that, but you may not find the specs, and there is a tolerance and your device should be calibrated.

** Since you're reading a sound wave,   you'll have to decide if you want to read the peak, average, or RMS.


*** Of course, once you have a corresponding SPL and ADC reading, you can calculate  a new reference level to use in your software.   For example, you might want to use a reference of 0dB, or 100dB, or whatever is convenient.    Or, you might want to use an ADC reading of 1000 as your reference, etc.

fabiensen

Hi,

thanks for your replies. Maybe I explained the whole thing in the wrong way.

We had a working Arduino Yun with Microphone MAX4466, and we got the dB SPL through several lines of code of sketch.

As DVDdoug pointed out we went through voltage to dB calculation (taking sensitivity, RMS, etc, into account) and this part was written by a sound engineer so, I would say we are ok with that.

However, a real SPL meter showed us that the values were ok with stable and not changing sound levels but, when in real situations, with continuously changing sound levels, values coming from Arduino were totally different and no more trustable.

The sound engineer told us it was Arduino's fault as it just throws away too many measurements being not able to go over 10 kHz. This made sense to us (even if we are not expert at all of this stuff).
He suggested to buy the Arduino Codec Shield, which can read the audio at a better frequency.   

The problem is that this shield comes with no how-to or starting guides at all. What we guess, is that the MAX4466 can be the input of this shield. Supposing this, we can't figure how to take the dB back from the audio shield output with Arduino.

Anyone has an idea or some document/tutorial to start with?

Thanks
Fabio

DVDdoug

Quote
However, a real SPL meter showed us that the values were ok with stable and not changing sound levels but, when in real situations, with continuously changing sound levels, values coming from Arduino were totally different and no more trustable.
I'm guess your weighting & averaging doesn't match the SPL meter.  

Quote
The sound engineer told us it was Arduino's fault as it just throws away too many measurements being not able to go over 10 kHz.
Not Likely...   With normal sound there's not much energy above 10kHz.

Try this experiment -

1.
Play some regular music on a stereo system with an equalizer or use computer audio player with an equalizer, such as Windows media player.  

2.  Set the equalizer to flat (or "off"' or "bypass") and watch the SPL meter.

3.  Turn down the frequencies above 10kHz as much as possible and notice how the SPL readings don't change.

4.  Return the frequencies above 10kHz to normal and reduce everything below 10kHz as much as possible.  Notice how much quieter the sound is and notice how much the SPL readings drop.

Grumpy_Mike

Quote
Not Likely...   With normal sound there's not much energy above 10kHz.
I quite agree, it looks like your sound engineer knows little about a digitised signal.

If you are only interested in the peak amplitude why not put a peak detector, sometimes called an envelope follower, in front of the A/D?

pjrc

I wouldn't be so quick to call this engineer incompetent.  He might be, and I'll agree the notion that the low sample rate is the blame seems suspicious.  But then again, from only the very limited info in this thread, we know almost nothing about what's really been tried so far.

We haven't even seen those few lines of code that were running on Yun.  There's all sorts of ways this could be done wrong, apart from a low sample rate.

Regarding the original question:

Quote
Does anyone have an idea how to proceed or some documents addressing us to the solution?
There's really 2 ways to understand and answer this question.

#1: Regarding use of the codec shield, you're almost certainly going to have to read the example code Open Music Labs publishes.  It's not terribly complicated.  I know, because I've read it.  You can too.  You're not going to find the detailed answers spelled out in web documentation.  The knowledge you seek, about how to specifically get the data from this shield, is found in the code.

#2: The words "how to proceed" could also be read as inviting a discussion about what is the proper algorithm or even appropriate hardware to accomplish this task.

With that in mind, I'd like to ask you what specific algorithm you're going to use on those samples arriving at 44100 per second rate?  Presumably you're doing something pretty simple right now, if it's just a few lines of code, right?

I'll also point out the very limited speed of 8 bit AVR-based Arduino and the huge overhead the codec shield takes, because those Arduino boards lack a proper I2S communication port.  If you look at the codec shield library code, you'll see there is a very limited amount of time to execute instructions before work must begin again to receive the next incoming sample.

I'm going to refrain from suggesting anything better, at least until I know much more about what you're really doing.

fabiensen

Hi,

sure I am going to paste my code, begging your pardon if my English is not of the best…

So, basically, every 10 seconds I am calculating the dB SPL in this way, commenting the most important lines.

Code: [Select]

const long interval = 10000; // this is the interval where the Microphone MAX4466 is doing a new measurement
const int sampleWindow = 1000 ; // Sample window width in mS (50 mS = 20Hz), this is the window in milliseconds where the measurement is done

uint32_t timer = millis();

void misuraEinvio() {
   
   unsigned long startMillis= millis();  // Start of sample window
   
   unsigned int peakToPeak = 0;   // peak-to-peak level
 
   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;
 
   while (millis() - startMillis < sampleWindow)
   {

      sample = analogRead(0);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
      //SerialUSB.print(sample);
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   double volts = ((peakToPeak * 3.3) / 1024) * 0.707;  // convert to RMS voltage
   // as the mic sensitivity is -44 +-2 dB converted to V RMS / PA is 0.000631
   double first = log10(volts/0.00631)*20;
   // gain is 25, 94 is a PA expressed as dB Spl
   double second = first + 94 - 44 - 25;


Basically the engineer is stating that even if I take those 10 seconds down to 1 second let's say (or even less) there would be no trustable measurement at all due to the 10 kHz sampling rate of Arduino.
Is he right?
Another question: is it really not possible to tweak Arduino Yun to make it able to go at a greater frequency than 10 kHz without burning its processor?
I repeat once more that for stable sounds the sketch works like a charm :)

Any help is greatly appreciated.
Regards

Fabio

Grumpy_Mike

Quote
Is he right?
No.

Quote
Another question: is it really not possible to tweak Arduino Yun to make it able to go at a greater frequency than 10 kHz without burning its processor?
I told you before the Yun is two boards, the input board is just like an Ardunio Uno. It is not a matter of processor speed it is a matter of the A/D settling time.
Yes you can speed things up by altering the prescaler rate in the A/D chain. BUT that is not your problem. Your problem is:-
1) A audio engineer who it seems from your reports not to know much about digitising sound.
2) The limited resolution of your A/D in the Arduino
3) The method you are extracting the peak amplitude from the samples
4) Your lack of filtering on the output producing .....
Quote
I repeat once more that for stable sounds the sketch works like a charm

fabiensen

Hi Grumpy_Mike,

thanks for your kind reply and time you dedicated to me.

Well, about the 4 points:

1) I could agree, but as far as I know, the sampling of 10 kHz is not enough to produce results so precise as with 44.000 kHz sampling. So, how is he wrong about it?

2) Ok, could we tweak the code this to increase the prescaler rate, I suppose?

3) I am quite sure the methods are right. As proof I can mention this forum thread on Adafruit (https://forums.adafruit.com/viewtopic.php?f=8&t=100462) where almost at the end of it, an admin member of Adafruit says the code is ok

4) I am aware of this. What do you suggest in order to solve this? Could you indicate some hardware you are aware of?

Thanks for your support!
Fabio

DVDdoug

#10
Nov 04, 2016, 05:03 pm Last Edit: Nov 04, 2016, 06:08 pm by DVDdoug
Maybe we should back-up a bit...

You really can't expect the kind of results you'd get with a laboratory-calibrated SPL meter.   And, I wouldn't be surprised if a "cheap" SPL meter is off by 6dB or more, depending on the nature of the sound you're measuring.

You should be able to build something that gives you an idea of relative loudness, but you can't expect something homemade to be "accurate".

What's the nature of the sound you're measuring?   What's the purpose and how much accuracy do you need?


I haven't studied your code in detail but looks like you are taking the peak over a 10 second period.   Is that what you want?  Do you want the peak loudness?   Of course, that's NOT what a normal SPL meter does...

And, you are not measuring/calculating RMS.    The 0.707 factor is only true for a constant sine wave.  You're calculating the approximate RMS value of the cycle with the highest peak.   With normal audio, that could easily be 20dB greater than the true RMS (over a longer period of time).   I assume your readings are generally higher than the SPL meters ?

A true Root Mean Square calculation may not be practical on the Arduino, but you can do averaging or take a moving average.   

Quote
However, a real SPL meter showed us that the values were ok with stable and not changing sound levels but, when in real situations, with continuously changing sound levels, values coming from Arduino were totally different and no more trustable.
What are you using for your "non-changing" signal?    A sine wave?  If so what frequency?   Pink noise or white noise?

Is your real SPL meter A-Weighted?



 

Grumpy_Mike

Quote
4) I am aware of this. What do you suggest in order to solve this? Could you indicate some hardware you are aware of?
You don't need hardware to do this, you just take a running average of the last n results. That is what your "professional" system does and that this why the output indication is "steady" when you have changing noise.

Quote
1) I could agree, but as far as I know, the sampling of 10 kHz is not enough to produce results so precise as with 44.000 kHz sampling. So, how is he wrong about it?
Because the measurement you want to take is not affected by the sample rate. With the right envelope detector on the front end you could get a very accurate result with a sample rate of 10 per second, let alone 10K.

Quote
3) I am quite sure the methods are right.
See what Doug says, he is quite right the 0.707 is just silly. What you want to do if you want to do it properly is to take the square of each sample, add them all up, and take the square root of the result. That gives you the RMS value of the actual waveform you have not a sin wave, which you haven't.

 

fabiensen

Hi and again thank you for your kind replies!

yes, the fact of the interval of 10 seconds could be a problem. I can take it down to 1 second and see what happens.
This interval was chosen as we collect 360 mesurements in an array and then calculate the hourly LAEQ sending it to the server afterwards. We make the array then empty and start again collecting measurements. This is the logic.

Now, the professional tool used by the engineer revealed that with stable sounds (both white and pink noise) this is working.

BTW, with changing sounds we have a higher levels than the SPL meter says, that's true, however, no more than 6-7 dB to speak the truth.

All considered, do you think that by taking the interval to 1 could improve results? About RMS, this goes beyond my knowledge actually and I thought it was a constant at least for that measurement (1 second every 10 seconds).

The peak-to-peak is taken from the Adafruit sample and all the calculation was actually approved by their admins. So, forgive me, but i really thought we were ok like that.

How could I get better results with software only?

Last but not least, our purposes is to collect 24 LAEQs a day, send them to the server and calculate the night, daily and 24h LAEQ and finally compare these values with WHO and European Union recommended limits.

Thanks
Fabio

Grumpy_Mike

Quote
The peak-to-peak is taken from the Adafruit sample and all the calculation was actually approved by their admins
What do you mean by "approved by their admins"? Did these admins know what you were going to use the calculations for? You can have calculations in one context that will be fine, but totally rubbish in another context.

I once did some consultancy for a night club owner who had commissioned a sound system, specified the output power but thought it was not loud enough. His problem was that he did not understand what he was specifying.

There are many ways to express sound level and if you are going to " finally compare these values with WHO and European Union recommended limits", then you better do some research and find out what these values are expressed in, and how they are measured.

DVDdoug

#14
Nov 07, 2016, 11:58 pm Last Edit: Nov 08, 2016, 12:02 am by DVDdoug
Quote
Last but not least, our purposes is to collect 24 LAEQs a day, send them to the server and calculate the night, daily and 24h LAEQ and finally compare these values with WHO and European Union recommended limits.
Anything related to regulatory requirements has to be periodically calibrated/validated by an independent lab.

A calibration lab probably won't calibrate anything "homemade".

And as you've discovered, if you calibrate it for pink noise it won't be properly calibrated for a constant tone, and vice-versa.

Go Up