奇怪的数组索引超出范围异常

时间:2014-07-07 11:45:10

标签: java android audio-recording indexoutofboundsexception

我的应用程序上有一些奇怪的东西让我无法理解。

我正在实施一种算法,可以检测何时产生脉冲响应(当强度值高于0.2时),并且当检测到脉冲响应时,它会在脉冲刺激之前存储0.5秒的样本,冲动后的1.5秒。 在我检测到脉冲之前,所有样本都存储在0.5秒长的环形缓冲区中,当我产生脉冲时,下一个样本存储在2秒长的正常数组中,让一些空间稍后复制0 ,5秒环形缓冲液样本。

问题是代码有时候工作得很好,有时它会给我数组索引超出范围的异常,如下所示:

07-07 13:31:47.312: E/AndroidRuntime(28823): java.lang.ArrayIndexOutOfBoundsException: length=16384; index=16384
07-07 13:31:47.312: E/AndroidRuntime(28823):    at com.example.acoustics.GrabaAudio.calculateImpulseLevel(GrabaAudio.java:174)

我真的没有看到我的代码在哪里可以产生这个数组边界异常,所以我不理解。 Buffersize是8192。

 private byte[] calculateImpulseLevel(byte[] array){
            byte[] circBuffer=new byte[bufferSize*2];
            for (int i=0; i<=array.length-3 ;i+=2){
            double sampleAmpl=(double)Math.abs((array[i+1] << 8 | array[i] & 0xff)/32767.0);
            if (sampleAmpl<0.2 && !triggered){
                int s=circ.size();
                if (s<circCapacity){
                    circ.add(array[i]);
                    circ.add(array[i+1]);
                } else {
                    circ.remove(0);
                    circ.add(array[i]);
                    circ.remove(0);
                    circ.add(array[i+1]);
                } 
            } else{
                    if(!triggered){
                        triggered=true;
                    }
                    indice = indice2+(bufferSize/2);//Empieza a poner en el array a partir de 0,5 seg de muestras
                    circBuffer[indice]=array[i];
                    circBuffer[indice+1]=array[i+1];
                    indice2+=2;
                    //if (indice >=((2*bufferSize)-3)){
                    if (indice2 >=((3*bufferSize)/2)-3){
                        i=array.length-2;
                    }

            }
            }

        System.arraycopy(toByteArray(circ),0,circBuffer,
              0,circ.size());
        //circ.removeAll(circ);
        return circBuffer;
    }

因为这个错误发生了一段时间,通常,当我第一次编译我的应用程序设备时它工作得很好而且越来越糟糕我运行我的应用程序越多,我认为这可能是由于存储在使用后未正确擦除的变量。

你们有什么想法?


好的,我在代码中做了一些更改,我已经解决了索引数组超出范围异常的问题。

这是我改变的代码段:

if(!triggered){
                        triggered=true;
                    }
                    indice=indice2+(bufferSize/2);
                    if (indice>2*bufferSize-2){
                        i=array.length;
                    }else{
                    circBuffer[indice]=array[i];
                    circBuffer[indice+1]=array[i+1];
                    indice2+=2;
                    }
                    /*if (indice >=2*bufferSize-3){
                        i=array.length;
                    }*/

            }}

现在我遇到了一个新问题,当我在调试器模式下运行我的应用程序时,一切都很顺利但是,当我只是尝试在我的设备上正常运行它时,获得的音频阵列看起来是重复的,并且它始终检测到脉冲响应0,20 aprox及其重复版本在1,20 aprox,如下图所示:

image http://www.subirimagenes.com/imagedata.php?url=http://s2.subirimagenes.com/imagen/8987227screenshot2014070915.png

这是我在调试器模式下得到的,实际上我期望获得的是:

image2 http://www.subirimagenes.com/imagedata.php?url=http://s2.subirimagenes.com/imagen/8987236screenshot2014070915.png

为什么会这样?为什么只是在正常模式而不是调试器?

1 个答案:

答案 0 :(得分:0)

for (int i=0; i<=array.length-3 ;i+=2)

假设array.lenght为100,则最后一个索引为99.条件为i<=97

最后一次迭代将有i = 96。并且将使用的最高数组索引是:97,它位于边界内。

根据您提供的数据,变量的Indice最大使用索引为:

((3*bufferSize)/2)-3+(bufferSize/2)这等于2*bufferSize - 3

这比它的界限低2(bufferSize * 2)。

一切似乎都井然有序。 Indice2可能不是你让我们认为的那样。您可能想尝试将bufferSize设置为1个字节,即byte[] circBuffer=new byte[bufferSize*2+1];

由于16384是8192 * 2.