Почему размер буфера влияет на аудиоданные?

Я использую javax.sound.sampled и JLayer для воспроизведения MP3 файла. Я пытаюсь проанализировать входной аудиопоток, чтобы определить, когда песня начинается и когда заканчивается (на основе уровней звука в начале и конце MP3). В 4-х минутной песне может быть только 3 минуты и 55 секунд реальной музыки, в то время как остальное - тишина, поэтому я определяю это.

Я думал, что смогу определить эту информацию, найдя первый и последний ненулевые байты в потоке.

Проблема: Проблема в том, что когда я регулирую размер буфера, позиция первого ненулевого байта изменяется. Почему это так и не должно ли оставаться постоянным независимо от размера буфера?

Например. При размере буфера 16 начальный кадр соответствует 17-му байту. При размере буфера 64 startFrame соответствует 65-му байту.

Вот код:

        byte[] buffer;
        int pos = 0;
        short silenceThreshold = 1;

        startFrame = 0;
        endFrame = -1;

        boolean startFrameSet = false;

        buffer = new byte[16];
        byte prevVal = 0;
        for (int n = 0; n != -1; n = audioInputStream.read(buffer, 0,
                buffer.length)) {

            for (int i = 0; i < buffer.length; i++) {
                if (buffer[i] >= silenceThreshold || buffer[i] <= -silenceThreshold) {
                    // Is not silent
                    if (!startFrameSet) {
                        startFrame = (pos * buffer.length) + i;
                        startFrameSet = true;
                    }
                } else {
                    // Silence
                    // If the previous value is > 0 or < 0, set endFrame
                    if (prevVal >= silenceThreshold || prevVal <= silenceThreshold) {
                        endFrame = (pos * buffer.length) + i;
                    }
                }
                prevVal = buffer[i];
            }

            pos++;
        }

        //If last byte is not within silence threshold (song doesn't end in silence).
        if (prevVal >= silenceThreshold || prevVal <= silenceThreshold) {
            // last frame is not silent
            endFrame = -1;
        }

Я полагаю, я неправильно понял, как работает поток аудиовхода и звук в целом.


person noahnu    schedule 07.09.2013    source источник


Ответы (1)


Ваш внешний цикл for не читает из входного аудиопотока при первом проходе цикла

 for (int n = 0; n != -1; n = audioInputStream.read(buffer, 0,
            buffer.length)) {

эквивалентно:

int n = 0;
while (n != -1) {
    // Inner loop

    n = audioInputStream.read(buffer, 0, buffer.length);
}

поэтому в первом цикле буфер представляет собой просто инициализированный нулевой массив из new byte[16].

Вы не должны предполагать, что чтение заполняет весь буфер, используйте значение, возвращаемое чтением.

person greg-449    schedule 07.09.2013
comment
Возможно, вы захотите взглянуть на этот ответ stackoverflow.com/questions/5800649/, который касается размеров выборки, количества каналов и т. д. - person greg-449; 08.09.2013