Исправление - указать размер буфера в методе open(AudioFormat,int)
.Задержка 10 мс-100 мс будет приемлемой для звука в реальном времени.Очень низкие задержки, например, не будут работать на всех компьютерных системах, и 100 мс или более, вероятно, будут раздражать ваших пользователей.Хороший компромисс, например, 50 мс.Для вашего аудиоформата, 8-битного, моно при 44100 Гц, хороший размер буфера составляет 2200 байт, что составляет почти 50 мс.
Также обратите внимание, что разные ОС имеют разные аудио возможности в Java.В Windows и Linux вы можете работать с довольно маленькими размерами буфера, но OS X использует старую реализацию со значительно большей задержкой.
Кроме того, запись байтов данных в SourceDataLine очень неэффективна (размер буфера установленв методе open()
, а не в write()
), как правило, я всегда записываю один полный размер буфера в SourceDataLine.
После настройки SourceDataLine используйте этот код:
final int bufferSize = 2200; // in Bytes
soundLine.open(audioFormat, bufferSize);
soundLine.start();
byte counter = 0;
final byte[] buffer = new byte[bufferSize];
byte sign = 1;
while (frame.isVisible()) {
int threshold = audioFormat.getFrameRate() / sliderValue;
for (int i = 0; i < bufferSize; i++) {
if (counter > threshold) {
sign = (byte) -sign;
counter = 0;
}
buffer[i] = (byte) (sign * 30);
counter++;
}
// the next call is blocking until the entire buffer is
// sent to the SourceDataLine
soundLine.write(buffer, 0, bufferSize);
}