Basic Knowledge
Measure the sound intensity, the most familiar unit is the decibel (decibel, abbreviated to DB). This is a non-dimensional relative unit , the calculation formula is as follows:
The numerator is the sound pressure of the measured value, and the denominator is the sound pressure of the reference value (20 kpa, the minimum sound pressure the human can hear). So the daily sound intensity is the number of decibels, the default is a very small reference value.
While the physical amount that the Android device sensor can provide is the amplitude of the field (amplitude), the following formula is used to calculate the decibel value:
After reading the amplitude of an audio data from the SDK, take the maximum amplitude or average amplitude (can be squared and average, or the absolute value of the peace), substituting the A1 of the above formula.
Now the question is, how much is the amplitude A0 as the reference value ?
Bloggers check a lot of posts, blog posts, here is the most group of paste. Some posts take 600, is based on its view of the noise amplitude of 600 hypothesis, at this time calculated is the relative background noise decibel value, if the user does not sound the microphone, calculated the basic is 0 decibels. And the user actually use the scene background noise size varies widely, if we also divert is not right, especially for those who make absolute decibel demand, should find 20 micro-pa sound pressure value corresponding amplitude (or can also take a standard decibel meter for calibration reference).
Bo Master is lazy, the A0 is set to 1, that is, the Android device microphone can "listen" to the minimum sound amplitude. The decibel value can be calculated by taking the amplitude of the measured value directly into the A1 of the second formula.
Android API
Use the microphone to apply the appropriate permissions in Androidmanifest.xml:
<uses-permission android:name= "Android.permission.RECORD_AUDIO"/>
There are two classes of data that can be obtained from audio sources: Android.media.
Mediarecorderand Android.media.
Audiorecord.
Mediarecorder:
The object initialization of this class is cumbersome because it is designed to record a complete piece of audio and write it to the file system. But it is convenient to obtain the amplitude after initialization, and we can obtain the maximum amplitude of the source data in a short period of time by using the getmaxamplitude method without parameter. However, the possible disadvantage of the maximum value is that the extreme data will be affected, so that the subsequent calculation of the decibel value fluctuation is relatively large. However, this method is used by many recording applications to calculate the volume level.
The method returns a 16-bit integer in the range of 0 to 32767, which may be based on the value of the absolute maximum of the source data for a period of 32768 to 32767 and returned. This value is linearly related to the value of the sound pressure in the unit of Pascal. It is also important to note that the first call to the method obtained by the value is 0, in the formula to calculate the decibel value is negative infinity, it is necessary in the code to judge this situation. It can be calculated that, since the maximum value returned by Getmaxamplitude is 32767, the maximum decibel value calculated is 90.3. In other words, the blogger's reference amplitude is 1, and the calculated decibel value is 0 db to 90.3 DBin the normal field.
Code slices:
Package Com.example.atest;import Java.io.file;import Java.io.ioexception;import android.media.mediarecorder;import Android.os.handler;import android.util.log;/** * AMR audio Processing */public class Mediarecorderdemo {private final String TAG = "Mediarecord"; Private Mediarecorder Mmediarecorder; public static final int max_length = 1000 * 60 * 10;//maximum recording duration 1000*60*10; Private String FilePath; Public Mediarecorderdemo () {This.filepath = "/dev/null"; Public Mediarecorderdemo (file file) {This.filepath = File.getabsolutepath (); } private long StartTime; Private long endTime; /** * Start recording using AMR format * * Recording file * @return */public void Startrecord () {//Start recording/*①i Nitial: Instantiate Mediarecorder Object */if (Mmediarecorder = = null) Mmediarecorder = new Mediarecorder (); try {/*②setaudiosource/setvediosource */Mmediarecorder.setaudiosource (MediaRecorder.AudioSource.MIC);//Set microphone /*② to set the encoding of the audio file: aac/aSampling of Mr_nb/amr_mb/default Sound (waveform) */Mmediarecorder.setoutputformat (MediaRecorder.OutputFormat.DEFAULT); /* *② format output file: Three_gpp/mpeg-4/raw_amr/default three_gpp (3gp format *, H263 video/arm audio encoding), MPEG-4, RAW_AMR (audio only and audio encoding required AMR _NB) */Mmediarecorder.setaudioencoder (MediaRecorder.AudioEncoder.AMR_NB);/*③ Preparation */MMEDIARECORDER.S Etoutputfile (FilePath); Mmediarecorder.setmaxduration (max_length); Mmediarecorder.prepare ();/*④ start */Mmediarecorder.start (); Audiorecord audiorecord./* Get start time * */startTime = System.currenttimemillis (); Updatemicstatus (); LOG.I ("Action_start", "startTime" + startTime); } catch (IllegalStateException e) {log.i (TAG, "Call Startamr (File mrecaudiofile) failed!" + e.getmessage ()); } catch (IOException e) {log.i (TAG, "Call Startamr (File mrecaudiofile) failed! " + e.getmessage ()); }}/** * Stop recording * */Public long Stoprecord () {if (Mmediarecorder = = null) return 0 L EndTime = System.currenttimemillis (); LOG.I ("Action_end", "endTime" + endTime); Mmediarecorder.stop (); Mmediarecorder.reset (); Mmediarecorder.release (); Mmediarecorder = null; LOG.I ("Action_length", "Time" + (endtime-starttime)); return endtime-starttime; } private Final Handler Mhandler = new Handler (); Private Runnable Mupdatemicstatustimer = new Runnable () {public void run () {updatemicstatus (); } }; /** * Update Microphone status * */private int BASE = 1; private int SPACE = 100;//interval sampling time private void Updatemicstatus () {if (Mmediarecorder! = null) {Doub Le ratio = (double) mmediarecorder.getmaxamplitude ()/base; Double db = 0;//db if (ratio > 1) db = * MATH.LOG10 (ratio); LOG.D (TAG, "decibel value:" +db); Mhandler.postdelayed (Mupdatemicstatustimer, SPACE); } }}
Audiorecord:
This class can obtain a specific source data value. After reading a piece of audio source data from a buffer into our incoming byte array audiodata using the Read (byte[] audiodata, int offsetinbytes, int sizeinbytes) method, we can manipulate it. such as the mean of squared sum or absolute value. This avoids the effects of individual extremes, making the results of the calculations more stable. After averaging, if the sum of squares is the formula of the constant coefficient of ten , and if it is the absolute value of the formula in the constant coefficient , calculate the decibel value.
Code slices
Package Com.example.atest;import Android.media.audioformat;import Android.media.audiorecord;import Android.media.mediarecorder;import Android.util.log;public class Audiorecorddemo {private static final String TAG = "A Udiorecord "; static final int sample_rate_in_hz = 8000; static final int buffer_size = Audiorecord.getminbuffersize (Sample_rate_in_hz, Audioformat.channel_in_d Efault, Audioformat.encoding_pcm_16bit); Audiorecord Maudiorecord; Boolean isgetvoicerun; Object MLock; Public Audiorecorddemo () {mLock = new Object (); public void Getnoiselevel () {if (Isgetvoicerun) {LOG.E (TAG, "Still on record"); Return } Maudiorecord = new Audiorecord (MediaRecorder.AudioSource.MIC, Sample_rate_in_hz, Audioformat.chann El_in_default, Audioformat.encoding_pcm_16bit, buffer_size); if (Maudiorecord = = null) {LOG.E ("sound", "Maudiorecord initialization failed"); } isGetvoicerun = true; New Thread (New Runnable () {@Override public void run () {maudiorecord.startrecording (); short[] buffer = new Short[buffer_size]; while (Isgetvoicerun) {//r is the actual length of data read, generally r is less than buffersize int r = Maudiorecord.read (b Uffer, 0, buffer_size); Long v = 0; Takes the buffer contents out, squares and operations for (int i = 0; i < buffer.length; i++) {v + = Buffe R[i] * Buffer[i]; }//squared and divided by the total length of the data to get the volume size. Double mean = v/(double) r; Double volume = ten * MATH.LOG10 (mean); LOG.D (TAG, "decibel Value:" + volume); About 10 times a second. Synchronized (MLock) {try {mlock.wait (100 ); } catch (Interruptedexception e) { E.printstacktrace (); }}} maudiorecord.stop (); Maudiorecord.release (); Maudiorecord = null; }}). Start (); }}
code calls to activity
Package Com.example.atest;import Android.app.activity;import Android.os.bundle;public class MainActivity extends Activity {@Overrideprotected void onCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); new Audiorecorddemo (). Getnoiselevel ();}}
Test Results
Source:http://download.csdn.net/detail/pcaxb/9028495
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android Get microphone Volume (decibels)