diff --git a/src/main/java/moe/nekojimi/chords/MusicHandler.java b/src/main/java/moe/nekojimi/chords/MusicHandler.java index ad5107d..62bde01 100644 --- a/src/main/java/moe/nekojimi/chords/MusicHandler.java +++ b/src/main/java/moe/nekojimi/chords/MusicHandler.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -19,6 +18,7 @@ import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; import net.dv8tion.jda.api.audio.AudioSendHandler; +import org.apache.commons.io.input.buffer.CircularByteBuffer; /** * @@ -27,10 +27,13 @@ import net.dv8tion.jda.api.audio.AudioSendHandler; public class MusicHandler implements AudioSendHandler, Closeable, Consumer { + private static final int DESIRED_BUFFER_SIZE = 3840 * 500; + private final LinkedList songQueue = new LinkedList<>(); private Song currentSong; private AudioInputStream din = null; - private final Queue queue = new ConcurrentLinkedQueue<>(); +// private final Queue queue = new ConcurrentLinkedQueue<>(); + private final CircularByteBuffer audioBuffer = new CircularByteBuffer(3840 * 1024); private boolean playing = true; private int byteCount; @@ -80,7 +83,7 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer public boolean nextSong(boolean immediate) { if (immediate) - queue.clear(); + audioBuffer.clear(); AudioInputStream in = null; try @@ -104,10 +107,8 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer AudioFormat decodedFormat = AudioSendHandler.INPUT_FORMAT; din = AudioSystem.getAudioInputStream(decodedFormat, in); byteCount = 3840; - while (queue.size() < 500) - if (!readData()) - break; - System.out.println("Queue filled to " + queue.size()); + fillBuffer(false); + System.out.println("Queue filled to " + audioBuffer.getCurrentNumberOfBytes()); return true; } catch (UnsupportedAudioFileException | IOException ex) { @@ -134,19 +135,26 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer public boolean canProvide() { // If we have something in our buffer we can provide it to the send system - return !queue.isEmpty() && playing; + return audioBuffer.getCurrentNumberOfBytes() > byteCount && playing; } @Override public ByteBuffer provide20MsAudio() + { + fillBuffer(true); + byte[] data = new byte[byteCount]; + audioBuffer.read(data, 0, data.length); +// byte[] data = queue.poll(); + return ByteBuffer.wrap(data); // Wrap this in a java.nio.ByteBuffer + } + + private void fillBuffer(boolean canSkip) { // use what we have in our buffer to send audio as PCM - while (queue.size() < 500) + while (audioBuffer.getCurrentNumberOfBytes() < DESIRED_BUFFER_SIZE) if (!readData()) - if (!nextSong()) + if (!canSkip || !nextSong()) break; - byte[] data = queue.poll(); - return data == null ? null : ByteBuffer.wrap(data); // Wrap this in a java.nio.ByteBuffer } private boolean readData() @@ -157,15 +165,23 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer { // if (din.available() == 0) // return false; - int bytesToRead = byteCount; + int bytesToRead = DESIRED_BUFFER_SIZE - audioBuffer.getCurrentNumberOfBytes(); + int space = audioBuffer.getSpace(); if (din.available() > 0 && din.available() < bytesToRead) bytesToRead = din.available(); + if (bytesToRead > space) + bytesToRead = space; + if (bytesToRead == 0) + return false; byte[] bytes = new byte[bytesToRead]; // byte[] bytes = din.readNBytes(bytesToRead); int read = din.read(bytes); + System.out.println("Wanted: " + byteCount + " Space:" + space + " Available: " + din.available() + " To read: " + bytesToRead + " Read: " + read); if (read < 0) return false; - queue.add(bytes); +// queue.add(bytes); + + audioBuffer.add(bytes, 0, read); } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);