3

My app. is calculating noise level and peak of frequency of input sound. I used FFT to get array of shorts[] buffer , and this is the code : bufferSize = 1024, sampleRate = 44100

 int bufferSize = AudioRecord.getMinBufferSize(sapleRate,
                channelConfiguration, audioEncoding);
        AudioRecord audioRecord = new AudioRecord(
                MediaRecorder.AudioSource.DEFAULT, sapleRate,
                channelConfiguration, audioEncoding, bufferSize);

and this is converting code :

short[] buffer = new short[blockSize];
        try {
            audioRecord.startRecording();
        } catch (IllegalStateException e) {
            Log.e("Recording failed", e.toString());
        }
        while (started) {
            int bufferReadResult = audioRecord.read(buffer, 0, blockSize);

            /*
             * Noise level meter begins here
             */
            // Compute the RMS value. (Note that this does not remove DC).
            double rms = 0;
            for (int i = 0; i < buffer.length; i++) {
                rms += buffer[i] * buffer[i];
            }
            rms = Math.sqrt(rms / buffer.length);
            mAlpha = 0.9;   mGain = 0.0044;
            /*Compute a smoothed version for less flickering of the
            // display.*/
            mRmsSmoothed = mRmsSmoothed * mAlpha + (1 - mAlpha) * rms;
            double rmsdB = 20.0 * Math.log10(mGain * mRmsSmoothed);

Now I want to know if this algorithm works correctly or i'm missing something ? And I want to know if it was correct and i have sound in dB displayed on mobile , how to test it ? I need any help please , Thanks in advance :)

Fareed
  • 560
  • 2
  • 7
  • 23
  • I think it'll be difficult to produce a reliable absolute dB value, because of hardware differences in D/A converters and microphones. You'd have to calibrate it to an audio source of known loudness. Also why are you multiplying the `log10` by a factor of `20.0`? Shouldn't that be `10` (because it's _deci_bel)? Also also, maybe you need to apply the gain before calculating the RMS, not after, depending on what exactly 'gain' means here. – Thomas Apr 21 '13 at 09:04
  • 2
    @Thomas: `20*log10` is correct in this case, as we're dealing with a *voltage*. `10*log10` is used for *power*. (Note that you can also achieve the same result more efficiently by not taking the `sqrt` of the magnitude and then use `10*log10`.) – Paul R Apr 21 '13 at 09:34

1 Answers1

1

The code looks correct but you should probably handle the case where the buffer initially contains zeroes, which could cause Math.log10 to fail, e.g. change:

        double rmsdB = 20.0 * Math.log10(mGain * mRmsSmoothed);

to:

        double rmsdB = mGain * mRmsSmoothed >.0 0 ?
                           20.0 * Math.log10(mGain * mRmsSmoothed) :
                           -999.99;  // choose some appropriate large negative value here for case where you have no input signal
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Great Thanks for your reply, i have a question .. how can i test the result ? ,or how can i calibrate the device ? – Fareed Apr 21 '13 at 17:29
  • You need a reference sound source - they are quite expensive but you can hire them from electronic equipment rental companies by the week or month. – Paul R Apr 21 '13 at 17:57
  • Note that the above comment assumes that you're talking about measuring dB SPL via a microphone input. If you just want dBV or dBm from a line level input say, the it's a lot easier. – Paul R Apr 21 '13 at 18:05
  • I want to take input from mic of android phone and display sound level in dB at peak frequency. Is it easy to test result and how ? If you want any code, i can get. – Fareed Apr 21 '13 at 18:13
  • Do you want [dB SPL](https://en.wikipedia.org/wiki/Sound_pressure) ? Are you going to apply any weighting, e.g. [A Weighting](https://en.wikipedia.org/wiki/A_weighting) ? – Paul R Apr 21 '13 at 18:14
  • No i wont do this, just dBV .. what is the best way to test this ? – Fareed Apr 21 '13 at 18:23
  • For dBV you would just input a reference signal at e.g. -6 dBV @ 1 kHz and then determine a calibration constant based on your measured value. However this only works for an analogue input - if it's a mike input then you are back to needing a reference sound source. – Paul R Apr 21 '13 at 20:16
  • What is the difference between measuring sound level, and measuring it at peak frequency ? – Fareed Apr 21 '13 at 21:23
  • Read the links I gave above on dB SPL and A Weighting. Normally sound levels are measured across a wide range of frequencies and a weighting curve is applied (most commonly A Weighting). – Paul R Apr 21 '13 at 22:07