Search code examples
javaaudiowavrecording

Recognize wav files with silence in Java


I need a function in JAVA, something like this:

Input: .wav file (or byte[] fileBytes) Output: true/false (the file consists of silence only)

What is the best way to do it?

Thank you.

UPDATE:

  1. The command that I use for recording:

    arecord --format=S16_LE --max-file-time=60 --rate=16000 --file-type=wav randomvalue_i.wav

  2. Silent = no audio at all


Solution

  • Well, the short answer is you'll want to scan the .WAV data and do a min/max value on it. A "silent" file the values should essentially all be 0.

    The longer answer is that you'll want to understand the .WAV format, which you can find described here (http://soundfile.sapp.org/doc/WaveFormat/). You can probably skip over the first 44 bytes (RIFF, 'fmt') to get down to the data, then start looking at the bytes. The 'bits-per-sample' value from the header might be important, as 16-bit samples would mean you'd need to consolidate 2 'bytes' together to get a single sample. But, even so, both bytes would be 0 for a silent, 16-bit sample file. Ditto for NumChannels - in theory you should understand it, but again, both should be 0 for true 'silent'. If all the data is '0', it's silent.

    "Silent" is a bit ambiguous. Above, I was strict and assumed it meant true '0' only. However, in a silent room, there would still be very low levels of background ambient noise. In that case, you'd need to be a bit more forgiving about the comparison. e.g. calculate a min/max for each sample, and insure that the range is within some tolerance. It can still be determined, but it just adds code.

    For completeness:

    public boolean isSilent(byte[] info) {
        for (int idx = 44; idx < info.length; ++idx) {
            if (info[idx] != 0)
                return false;
        }
        return true;
    }