class AutocorrellatedVoiceActivityDetector {

    public double[] removeSilence(double[] voiceSample, float sampleRate) {
        int oneMilliInSamples = (int)sampleRate / 1000;

        int length = voiceSample.length;
        int minSilenceLength = MIN_SILENCE_MILLIS * oneMilliInSamples;
        int minActivityLength = getMinimumVoiceActivityLength(sampleRate);
        boolean[] result = new boolean[length];
        
        if(length < minActivityLength) {
            return voiceSample;
        }

        int windowSize = WINDOW_MILLIS * oneMilliInSamples;
        double[] correllation = new double[windowSize];
        double[] window = new double[windowSize];
        
        
        for(int position = 0; position + windowSize < length; position += windowSize) {
            System.arraycopy(voiceSample, position, window, 0, windowSize);
            double mean = bruteForceAutocorrelation(window, correllation);
            Arrays.fill(result, position, position + windowSize, mean > threshold);
        }
        

        mergeSmallSilentAreas(result, minSilenceLength);
        
        int silenceCounter = mergeSmallActiveAreas(result, minActivityLength);

//        System.out.println((int)((double)silenceCounter / result.length * 100.0d) + "% removed");
   
        if (silenceCounter > 0) {
            
            int fadeLength = FADE_MILLIS * oneMilliInSamples;
            initFadeFactors(fadeLength);
            double[] shortenedVoiceSample = new double[voiceSample.length - silenceCounter];
            int copyCounter = 0;
            for (int i = 0; i < result.length; i++) {
                if (result[i]) {
                    // detect lenght of active frame
                    int startIndex = i;
                    int counter = 0;
                    while (i < result.length && result[i++]) {
                        counter++;
                    }
                    int endIndex = startIndex + counter;

                    applyFadeInFadeOut(voiceSample, fadeLength, startIndex, endIndex);
                    System.arraycopy(voiceSample, startIndex, shortenedVoiceSample, copyCounter, counter);
                    copyCounter += counter;
                }
            }
            return shortenedVoiceSample;
            
        } else {
            return voiceSample;
        }
    }

}