diff --git a/src/com/limelight/binding/audio/JavaxAudioRenderer.java b/src/com/limelight/binding/audio/JavaxAudioRenderer.java index 134b390..7e0ca5e 100644 --- a/src/com/limelight/binding/audio/JavaxAudioRenderer.java +++ b/src/com/limelight/binding/audio/JavaxAudioRenderer.java @@ -14,7 +14,10 @@ public class JavaxAudioRenderer implements AudioRenderer { private SourceDataLine soundLine; private SoundBuffer soundBuffer; private byte[] lineBuffer; + private int channelCount; + private int sampleRate; + public static final int DEFAULT_BUFFER_SIZE = 4096; public static final int STAGING_BUFFERS = 3; // 3 complete frames of audio @Override @@ -26,6 +29,18 @@ public class JavaxAudioRenderer implements AudioRenderer { // If there's space available in the sound line, pull some data out // of the staging buffer and write it to the sound line int available = soundLine.available(); + + // Kinda jank. If the queued is larger than available, we are going to have a delay + // so we increase the buffer size + if (available < soundBuffer.size()) { + System.out.println("buffer too full, buffer size: " + soundLine.getBufferSize()); + int currentBuffer = soundLine.getBufferSize(); + soundLine.close(); + createSoundLine(currentBuffer*2); + available = soundLine.available(); + System.out.println("creating new line with buffer size: " + soundLine.getBufferSize()); + } + if (available > 0) { int written = soundBuffer.fill(lineBuffer, 0, available); if (written > 0) { @@ -41,16 +56,14 @@ public class JavaxAudioRenderer implements AudioRenderer { soundLine.close(); } } - - @Override - public void streamInitialized(int channelCount, int sampleRate) { + + private void createSoundLine(int bufferSize) { AudioFormat audioFormat = new AudioFormat(sampleRate, 16, channelCount, true, true); DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); try { soundLine = (SourceDataLine) AudioSystem.getLine(info); - soundLine.open(audioFormat); + soundLine.open(audioFormat, bufferSize); soundLine.start(); - lineBuffer = new byte[soundLine.getBufferSize()]; soundBuffer = new SoundBuffer(STAGING_BUFFERS); } catch (LineUnavailableException e) { @@ -58,4 +71,11 @@ public class JavaxAudioRenderer implements AudioRenderer { } } + @Override + public void streamInitialized(int channelCount, int sampleRate) { + this.channelCount = channelCount; + this.sampleRate = sampleRate; + createSoundLine(DEFAULT_BUFFER_SIZE); + } + } diff --git a/src/com/limelight/binding/audio/SoundBuffer.java b/src/com/limelight/binding/audio/SoundBuffer.java index 9197ebb..8859bad 100644 --- a/src/com/limelight/binding/audio/SoundBuffer.java +++ b/src/com/limelight/binding/audio/SoundBuffer.java @@ -24,6 +24,14 @@ public class SoundBuffer { bufferList.addLast(buff); } + public int size() { + int size = 0; + for (ShortBufferDescriptor desc : bufferList) { + size += desc.length; + } + return size; + } + public int fill(byte[] data, int offset, int length) { int filled = 0;