4

I'm trying to get the Sound Level Pressure expressed in decibel but I always get 0. (The output of the TextView is -Infinity but because log(0) = -infinity.

public class SLP extends Activity{

TextView sound;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sound_activity);

    MediaRecorder recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new RecorderTask(recorder), 0, 500);


}

private class RecorderTask extends TimerTask {
    TextView sound = (TextView) findViewById(R.id.decibel);
    private MediaRecorder recorder;

    public RecorderTask(MediaRecorder recorder) {
        this.recorder = recorder;
    }

    public void run() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int amplitude = recorder.getMaxAmplitude();
                double amplitudeDb = 20 * Math.log10((double)Math.abs(amplitude) / 32768);
                sound.setText("" + amplitudeDb);
            }
        });
    }
}

The permission in the Manifest.xml:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

Could you help me please?

Update

I tried with this too:

MediaRecorder recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    recorder.setOutputFile("/dev/null");
    try {
        recorder.prepare();
    } catch (IOException e) {
        e.printStackTrace();
    }
    recorder.start();
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new RecorderTask(recorder), 0, 500);
    recorder.reset();
}
private class RecorderTask extends TimerTask {
    TextView risultato = (TextView) findViewById(R.id.decibel);
    private MediaRecorder recorder;

    public RecorderTask(MediaRecorder recorder) {
        this.recorder = recorder;
    }

    public double getAmplitude() {
        if (recorder != null)
            return  (recorder.getMaxAmplitude());
        else
            return 0;

    }

    public void run() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int amplitude = recorder.getMaxAmplitude();
                double amplitudeDb = 20 * Math.log10(getAmplitude() / 32768);
                //double db = 20 * Math.log(recorder.getMaxAmplitude() / 2700.0);
                risultato.setText("" + amplitudeDb);
            }
        });
    }
}

but nothing, still getting -Infinite

            

Pier
  • 794
  • 1
  • 12
  • 27

3 Answers3

5

Try with this:

MediaRecorder recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new RecorderTask(recorder), 0, 500);
    recorder.setOutputFile("/dev/null");

    try {
        recorder.prepare();
        recorder.start();
    } catch(IllegalStateException e)
    {
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

private class RecorderTask extends TimerTask {
    TextView sound = (TextView) findViewById(R.id.decibel);
    private MediaRecorder recorder;

    public RecorderTask(MediaRecorder recorder) {
        this.recorder = recorder;
    }

    public void run() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int amplitude = recorder.getMaxAmplitude();
                double amplitudeDb = 20 * Math.log10((double)Math.abs(amplitude)); 
                sound.setText("" + amplitudeDb);
            }
        });
    }
}

Without / 32768 I get values between 30 db (my room with silence) and 88 db (when I put loud music).

enter image description here

I think they're OK

Rick
  • 3,943
  • 6
  • 33
  • 45
  • Yes actually it works, I'm getting values in that range too. But I'm not very sure about the operation, I mean, many SO question I've seen said that to get the value in db i have to do this: _ powerDb = 20 * log10(getAmplitude() / referenceAmp);_ – Pier Jul 09 '15 at 17:23
  • There are 4 questions on SO that will make you understand: 1) http://stackoverflow.com/questions/16072185/decibels-in-android?rq=1 2) http://stackoverflow.com/questions/13627284/android-record-decibel-from-microphone?rq=1 3) http://stackoverflow.com/questions/9597767/decibel-sound-meter-for-android?rq=1 4) http://stackoverflow.com/questions/14453674/audio-output-level-in-a-form-that-can-be-converted-to-decibel/14455170#14455170 – Rick Jul 09 '15 at 17:38
  • Oh I see, it is ok for me just to have _int amplitude = recorder.getMaxAmplitude(); double amplitudeDb = 20 * Math.log10((double)Math.abs(amplitude));_ to get the _SOUND LEVEL PRESSURE_. Thanks a lot man :D – Pier Jul 09 '15 at 17:43
1

I think you need to call recorder.prepare() and recorder.start() as per the developer notes

UPDATE you also must setOutputFile(file_path);

MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(PATH_NAME);
recorder.prepare();
recorder.start();   // Recording is now started
 ...
recorder.stop();
recorder.reset();   // You can reuse the object by going 
Mark Gilchrist
  • 1,972
  • 3
  • 24
  • 44
  • I added _recorder.prepare(); recorder.start();_ but I only get an error in the LogCat – Pier Jul 08 '15 at 23:08
  • _Unable to start activity ComponentInfo{beta_toolbox.pier.beta_toolbox/beta_toolbox.pier.beta_toolbox.SLP}: java.lang.IllegalStateException_ _java.lang.IllegalStateException_ on line _recorder.start();_ – Pier Jul 08 '15 at 23:13
  • If you cut an paste the stacktrace into your question I may be able to help more – Mark Gilchrist Jul 08 '15 at 23:15
  • does it say something like .....caused by ...., the whole stacktrace would be more help, you can add it to your question by editing it – Mark Gilchrist Jul 08 '15 at 23:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/82758/discussion-between-mark-gilchrist-and-pier). – Mark Gilchrist Jul 08 '15 at 23:21
0

Below code worked for me, need to set "setAudioSamplingRate" and "setAudioEncodingBitRate"

 MediaRecorder recorder = new MediaRecorder();
 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 if (Build.VERSION.SDK_INT >= 10) {
  recorder.setAudioSamplingRate(44100);
  recorder.setAudioEncodingBitRate(96000);
  recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
  recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
} else {
  // older version of Android, use crappy sounding voice codec
   recorder.setAudioSamplingRate(8000);
   recorder.setAudioEncodingBitRate(12200);
   recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
   recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
}
recorder.setOutputFile(file.getAbsolutePath());
try {
 recorder.prepare();
 } catch (IOException e) {
throw new RuntimeException(e);
}
Sandeep
  • 11
  • 2