2013-09-07 3 views
0

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

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

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

E.g. При размере буфера 16, startFrame коррелирует с 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; 
     } 

Я полагаю, что я не понял, как поток аудио вход и аудио в общих работах.

ответ

2

Ваш внешний 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].

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

+1

Возможно, вы захотите посмотреть на этот ответ http://stackoverflow.com/questions/5800649/detect-silence-when-recording, который посвящен размерам выборки, количеству каналов и т. Д. –