Java 获取wav文件的声压级

Java 获取wav文件的声压级,java,android,audio,wav,androidplot,Java,Android,Audio,Wav,Androidplot,我正在尝试获取并表示先前使用设备内部麦克风录制的wav文件的SPL。 问题是,我得到的值似乎根本不符合逻辑,因为我得到的值超过100 db,你可以在这里看到,我只是拍手: (来源:) 这就是我正在做的: 首先,由于wav文件保存在16位PCM中,我使用它的字节操作,以使唯一的双精度值在[-1,1]之间标准化(我不使用前44个字节,因为它是wav头) 然后,根据这个方程SPL=10*log(audioSample/Iref),我获得每个期望的声级(Iref=10^-12) 最后,我计算最大值和

我正在尝试获取并表示先前使用设备内部麦克风录制的wav文件的SPL。 问题是,我得到的值似乎根本不符合逻辑,因为我得到的值超过100 db,你可以在这里看到,我只是拍手:


(来源:)

这就是我正在做的:

  • 首先,由于wav文件保存在16位PCM中,我使用它的字节操作,以使唯一的双精度值在[-1,1]之间标准化(我不使用前44个字节,因为它是wav头)
  • 然后,根据这个方程SPL=10*log(audioSample/Iref),我获得每个期望的声级(Iref=10^-12)
  • 最后,我计算最大值和最小值以设置绘图的边距
你们知道我做错了什么吗?我认为这些值应该是所获得值的一半左右

下面是一段代码:

protected void miThread() {
          Thread t=new Thread()  {
            public void run(){
            //Operaciones ope=new Operaciones();
            double [] st =new double [arr.length];
             int j=0;
                try{
                  for (int i = 44; i < s; i+=2) {
                    // convert byte pair to int
                    double audioSample = (double) (array[i+1] << 8 | array[i] & 0xff)/ 32767.0;

                    arr[j]=audioSample;  //double
                    n[j] = (Number)arr[j];  //Number

                    st[j]=10*Math.log10(Math.abs((audioSample/Math.pow(10, -12)))); //double
                    l[j]=(Number)(10*Math.log10(Math.abs((audioSample/Math.pow(10, -12)))));  //Number

                    if(audioSample == 0.0 ){
                        if(j!=0){
                        l[j]=l[j-1];
                        st[j]=st[j-1];
                        }else{
                            l[j]=0.0;
                            st[j]=0.0;
                        }
                      }

                    j=j+1;}
                    min=Operaciones.minimum(arr);
                    max=Operaciones.maximum(arr);
                    min2=Operaciones.minimum(st);
                    max2=Operaciones.maximum(st);
                    }
                    catch (NullPointerException e){
                        e.printStackTrace();
                        } 
                handle.post(proceso);
               } }; t.start();                  
                }

        final Runnable proceso=new Runnable(){
            public void run(){
                //plot.redraw();
                //plot2.redraw();
                Toast.makeText(Grafica.this, 
                "Ya se ha cargado todo el array", Toast.LENGTH_LONG).show();
            }
        };  
protectedvoid-miThread(){
线程t=新线程(){
公开募捐{
//Operaciones ope=新Operaciones();
double[]st=新的double[arr.length];
int j=0;
试一试{
对于(int i=44;idouble audioSample=(double)(数组[i+1]是否表示声压级与绝对参考?相比。因此,麦克风插入了一个16位精度的端口,我认为它可以。信噪比应该在60分贝左右,因此语音间隔大约为44分贝。因此,当麦克风接收到任何声音时,信号应该上升(如果我记得是16位的话,大约104dB)


SPL=20log(Pascal/2e-5)

要转换为dBSPL-我想您首先要通过乘法转换为Pascal-可能是通过lref。接下来您需要从Pascal转换为dBSPL,其中
dBSPL=20*log10(Pa/2e-5)
。以任何分贝为单位绘制时域波形是非常不寻常的,也不是很有用。你最好用帕斯卡为单位绘制时域波形。另外,我对你的10e-12 lref数字有点怀疑。这是你的麦克风的灵敏度吗?嗨,杰克,谢谢你的回答,正如我在互联网上读到的几个来源一样,声音压力确定声级Lp=20log(Pa/2e-5)等于声强级Li=10log(I/10e-12),在这种情况下,我使用第二个公式(因此,其Iref).我真的不知道音频样本给了我什么,压力还是强度?我怎么能把它转换成帕斯卡?我有点搞不懂这个音频样本是代表满刻度分数(FFS)的瞬时值转换为帕斯卡所需知道的是话筒的灵敏度。换句话说,产生满标度音频样本需要多少帕斯卡。表征这一点的方法是在话筒校准器连接到话筒时测量FFS输入的RMS电平。校准器将产生a音t 94dBSPL,因此您可以反向计算,以确定每帕斯卡的FFS为单位的比例因子。也有可能mic的数据表中有它的规范。