Making a decibel meter (first android app), problems converting Amplitude to Decibels - android

As a part of a larger aplication I am currently working on a decibel meters that takes the average sound level of a 10 second timespan.
To achieve this I made a CountDownTimer of 10 000 miliseconds that ticks every 100 miliseconds.
In each onTick event I update the textfield that shows the time left, and I also update the realtime decibel value.
My issue however is converting the maximum amplitude to decibels. I found the "power_db = 20 * log10(amp / amp_ref);" formula here on StackOverflow and I understand how it works, but I seem to always end up with a negative decibel value.
I understand that this is because of a wrong amp_ref value, but I am absolutely stumped on which one I should use. I found alot of different values on the web and none seem to do the trick.
Does anyone have any idea which reference amplitude I should use to get the correct decibel reading on my meter? The phone I am testing this on is a Google Nexus 5. For now it would be good enough if it only was a really accurate value on this phone if thats of any help.
The code I have in my onTick event is the following (I removed the formula for now since it seemed to be wrong anyways):
public void onTick(long ms) {
meetBtn.setText(String.valueOf((ms/1000)+1));
amplitude = mRecorder.getMaxAmplitude();
decibelView.setText(String.valueOf(amplitude));
}
If anyone has any tips or needs more information, please let me know!
Thanks in advance! :)

Negative decibels are fine, because it's a relative measure anyway. In fact it's a common practice to take the maximum possible amplitude as a reference point and as a result have decibels go from 0 down to negative space. Pro systems usually indicate positive decibels as an overload when clipping and distortions of sound may occur.
So for example if your amplitude range is 0 to 1 (an accepted float-PCM standard), then your amp_ref would be 1 and your decibel values will go from some negative value that depends on the bitness resolution of your source (e.g. -186dB for 32 bit, or -90dB for 16-bit source), up to 0dB. This is normal!
Edit: actually, your float-PCM amplitude range is -1 to 1, but decibel calculation "drops" the minus sign and gives the same result for both negative and positive amplitudes.

Related

Math.sin() does not give accurate results [I'm using Math.toRadians to pass the right values]

I'm actually using Math.sin() in my android app to calculate a sinus of a given angle (using Math.toRadians(angle_in_degrees)). For exemple when I want to get the Math.cos(90) which is 0, the result is 6.123233... E-17. Thanks you.
For floating point numbers, the system can often only approximate their values. For instance, the system would return something like 0.333333 for the expression (1.0 / 3). The number of 3s after the decimal point will be different depending on whether you're a floats or doubles, but it will still be limited to some finite length.
If you're just displaying the value, then you can limit the number of digits using something like String.format("%0.2f", value) or by rounding it using one of the rounding functions such as Math.round().
The tricky part comes when you need to compare the value to something. You can't just use if (value == some_constant) or even if (value == some_variable). At minimum, you usually have to use something like if (Math.abs(value - some_constant) < 0.001). The actual value of the '0.001' depends on the needs of your particular application and is customarily defined as a named constant.
For more complicated needs, you can implement the algorithm in the Floating-Point Guide.
You're getting back an approximation from Math.cos(Math.toRadians(90)) which is
6.123233... E-17 == 0.00000000000000006123233... which is basically 0
The following link should help clear things up as far as the precision of doubles/floats in programming.
http://www.java67.com/2015/09/float-and-double-value-comparison-in-java-use-relational.html

Hi I want to know what is the appropriate process of converting Amplitude to dB . Through Android device

I want to know what is the appropriate process of converting Amplitude to dB. I am using double as below
db = (20 * Math.log10(mediaRecorder.getMaximimAmplitude));
But there are suggestions to use double as below
db = (20 * Math.log10(x2 / REFERENCE));
I dont know what reference is to use in which scenerio
The decibel is a much misused unit. It is defined as the 10 log (P1/P2) where P1 is the measured power, and P2 is the reference power. That is, it is always relative to some reference power. A common reference power is one milliwatt, and this is the definition of dBm. 0dBm is one milliwatt; +30dbm is one watt. Don't be misled by the oft-quoted "0dBm = one milliwatt in 600 ohms". This is an artifact of when voltage measuring devices were used to display dBm. Because they were voltage measuring rather than power measuring, an impedance at which they read correctly needed to be specified, and it was nearly always 600 ohms.
Over the years dB usage has been stretched to cover situations where having a logarithmic unit is really useful. For instance the voltage gain of an amplifier may be quoted in dB, using the formula 20log(Vout/Vin). In this situation, the input and output impedances (and hence powers) are often vastly different, so the usage is technically wrong. In practice it is a convenient unit to work with, and has been given some legitimacy by labeling it dBv.
The first formula you are using will return dB referenced to 1 volt in whatever impedance your circuit exhibits. This is fine, but it won't be dBm. Often this does not matter, as you just need to graph gain in dB against an arbitrary reference.If you need it to be dBm just find the circuit impedance and use Ohms law to work out what voltage represents one milliwatt in that impedance.
The second formula is a bit strange. What is x2? I would expect the formula to be 20log(Vmeasured/Vreference).

Frame-independent animation in game developement on android

Ok so delta-time is 1/fps right? Say the fps was 50, then delta time would equal 1/50= 0.02. My question is that frame rate varies(one second it might be 50, another it might be 52). So say for one second the fps is 50, that means that delta time will be equal to 0.02, but the NEXT second the fps will be 52, but we don't know that yet. So our animations are being done with delta time of 1/50 but the fps is actually 52. Until the next second is finished we won't know that the fps has changed. This may not seem like a big deal if the changes are small, but if they become very big then we have a problem. So the thing is we are always doing calculations based on the previous second's fps. I want to know how to solve this. Thanks!
You're right that 1/fps = delta-time. However, fps isn't known at the present, and as you pointed out going about it this way would cause a problem! In practice, the formula is re-arranged such that 1/dt = fps.
So, we determine delta-time by determining how much time has passed since the last update( deltaTime = (CurrentTime - LastTime) ). If we were to have a variable that we add delta time to every every update (say, deltaCounter += deltaTime), and another variable which is a counter we add one to each update (Counter++), we would see that when deltaCounter is becomes equal to 1, the Counter variable is our fps for that second.
Further Reading on Delta Time and its Implementation

How to display mathematical power values in xml

I have a xml which I am parsing and displaying the values.
<question>
The frequency of tuning fork is 1000 Hz and velocity of sound in air 300 ms-1.The distance travelled by sound while the fork executes 500 oscillations is
</question>
In this as you can see 300 ms to the power -1 is the exact value. But while parsing it is not displayed.
Also I need to display 10^8 as (10 to the power 8 )
How to display these values. Itried including ASCII code but it does not work.
Please help and Thanks in advance.

Android PCM Bytes

I am using the AudioRecord class to analize raw pcm bytes as it comes in the mic.
So thats working nicely. Now i need convert the pcm bytes into decibel.
I have a formula that takes sound presure in Pa into db.
db = 20 * log10(Pa/ref Pa)
So the question is the bytes i am getting from audiorecorder from the buffer what is it is it amplitude pascal sound pressure or what.
I tried to putting the value into te formula but it comes back with very hight db so i do not think its right
thanks
Disclaimer: I know little about Android.
Your device is probably recording in mono at 44,100 samples per second (maybe less) using two bytes per sample. So your first step is to combine pairs of bytes in your original data into two-byte integers (I don't know how this is done in Android).
You can then compute the decibel value (relative to the peak) of each sample by first taking the normalized absolute value of the sample and passing it to your Db function:
float Db = 20 * log10(ABS(sampleVal) / 32768)
A value near the peak (e.g. +32767 or -32768) will have a Db value near 0. A value of 3277 (0.1) will have a Db value of -20; a value of 327 (.01) will have a Db value of -40 etc.
The problem is likely the definition of the "reference" sound pressure at the mic. I have no idea what it would be or if it's available.
The only audio application I've ever used, defined 0db as "full volume", when the samples were at + or - max value (in unsigned 16 bits, that'd be 0 and 65535). To get this into db I'd probably do something like this:
// assume input_sample is in the range 0 to 65535
sample = (input_sample * 10.0) - 327675.0
db = log10(sample / 327675.0)
I don't know if that's right, but it feels right to the mathematically challenged me. As the input_sample approaches the "middle", it'll look more and more like negative infinity.
Now that I think about it, though, if you want a SPL or something that might require different trickery like doing RMS evaluation between the zero crossings, again something that I could only guess at because I have no idea how it really works.
The reference pressure in Leq (sound pressure level) calculations is 20 micro-Pascal (rms).
To measure absolute Leq levels, you need to calibrate your microphone using a calibrator. Most calibrators fit 1/2" or 1/4" microphone capsules, so I have my doubts about calibrating the microphone on an Android phone. Alternatively you may be able to use the microphone sensitivity (Pa/mV) and then calibrate the voltage level going into the ADC. Even less reliable results could be had from comparing the Android values with the measured sound level of a diffuse stationary sound field using a sound level meter.
Note that in Leq calculations you normally use the RMS values. A single sample's value doesn't mean much.
I held my sound level meter right next to the mic on my google ion and went 'Woooooo!' and noted that clipping occurred about 105 db spl. Hope this helps.
The units are whatever units are used for the reference reading. In the formula, the reading is divided by the reference reading, so the units cancel out and no longer matter.
In other words, decibels is a way of comparing two things, it is not an absolute measurement. When you see it used as if it is absolute, then the comparison is with the quietest sound the average human can hear.
In our case, it is a comparison to the highest reading the device handles (thus, every other reading is negative, or less than the maximum).

Categories

Resources