|
|
|
@ -5,15 +5,15 @@ |
|
|
|
|
*/ |
|
|
|
|
package moe.nekojimi.chords; |
|
|
|
|
|
|
|
|
|
import java.io.Closeable; |
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.io.*; |
|
|
|
|
import moe.nekojimi.chords.Util; |
|
|
|
|
import java.nio.ByteBuffer; |
|
|
|
|
import java.util.LinkedList; |
|
|
|
|
import java.util.Queue; |
|
|
|
|
import java.util.function.Consumer; |
|
|
|
|
import java.util.logging.Level; |
|
|
|
|
import java.util.logging.Logger; |
|
|
|
|
import javax.sound.sampled.UnsupportedAudioFileException; |
|
|
|
|
import javax.sound.sampled.*; |
|
|
|
|
import net.dv8tion.jda.api.audio.AudioSendHandler; |
|
|
|
|
import org.apache.commons.io.input.buffer.CircularByteBuffer; |
|
|
|
|
|
|
|
|
@ -27,7 +27,7 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer<Song> |
|
|
|
|
private final LinkedList<Song> songQueue = new LinkedList<>(); |
|
|
|
|
// private final Queue<byte[]> queue = new ConcurrentLinkedQueue<>();
|
|
|
|
|
private final CircularByteBuffer audioBuffer = new CircularByteBuffer(3840 * 1024); |
|
|
|
|
private boolean playing = true; |
|
|
|
|
private boolean playing = true; |
|
|
|
|
private int byteCount; |
|
|
|
|
|
|
|
|
|
private boolean arrayErr = false; |
|
|
|
@ -35,8 +35,22 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer<Song> |
|
|
|
|
private Song currentSong; |
|
|
|
|
private TrackPlayer player; |
|
|
|
|
|
|
|
|
|
private File debugOutFile; |
|
|
|
|
private BufferedOutputStream debugOut; |
|
|
|
|
|
|
|
|
|
public MusicHandler() |
|
|
|
|
{ |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
debugOutFile = new File("debug.wav"); |
|
|
|
|
if (debugOutFile.exists()) |
|
|
|
|
debugOutFile.delete(); |
|
|
|
|
debugOutFile.createNewFile(); |
|
|
|
|
debugOut = new BufferedOutputStream(new FileOutputStream(debugOutFile)); |
|
|
|
|
} catch (IOException ex) |
|
|
|
|
{ |
|
|
|
|
Logger.getLogger(MusicHandler.class.getName()).log(Level.SEVERE, null, ex); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void addSong(Song song) |
|
|
|
@ -94,7 +108,11 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer<Song> |
|
|
|
|
} |
|
|
|
|
currentSong = songQueue.poll(); |
|
|
|
|
if (currentSong == null) |
|
|
|
|
{ |
|
|
|
|
System.out.println("End of queue."); |
|
|
|
|
debugOut.flush(); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
System.out.println("Playing song " + currentSong.getLocation().getAbsolutePath()); |
|
|
|
|
arrayErr = false; |
|
|
|
|
byteCount = 3840; |
|
|
|
@ -125,7 +143,7 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer<Song> |
|
|
|
|
@Override |
|
|
|
|
public boolean canProvide() |
|
|
|
|
{ |
|
|
|
|
return player != null && player.has(byteCount); |
|
|
|
|
return player != null && player.has(1); |
|
|
|
|
// If we have something in our buffer we can provide it to the send system
|
|
|
|
|
// return audioBuffer.getCurrentNumberOfBytes() > byteCount && playing;
|
|
|
|
|
} |
|
|
|
@ -136,25 +154,32 @@ public class MusicHandler implements AudioSendHandler, Closeable, Consumer<Song> |
|
|
|
|
ByteBuffer ret = ByteBuffer.allocate(byteCount); |
|
|
|
|
while (ret.position() < byteCount && player != null) |
|
|
|
|
{ |
|
|
|
|
System.out.println("Position: " + ret.position() + " Remaining: " + ret.remaining()); |
|
|
|
|
ByteBuffer read = player.read(ret.remaining()); |
|
|
|
|
|
|
|
|
|
if (read != null) |
|
|
|
|
// System.out.println("Position: " + ret.position() + " Remaining: " + ret.remaining());
|
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
ByteBuffer read = player.read(ret.remaining()); |
|
|
|
|
// System.out.println("SAMPLES from player: " + Util.printSamples(read));
|
|
|
|
|
|
|
|
|
|
System.out.println("Read: " + read.remaining()); |
|
|
|
|
ret.put(read); |
|
|
|
|
} else if (!nextSong()) |
|
|
|
|
} catch (TrackPlayer.OutOfInputException | IOException ex) |
|
|
|
|
{ |
|
|
|
|
System.out.println("Out of songs!"); |
|
|
|
|
break; |
|
|
|
|
System.out.println("Track ended, starting next."); |
|
|
|
|
boolean foundNext = nextSong(); |
|
|
|
|
|
|
|
|
|
if (!foundNext) |
|
|
|
|
{ |
|
|
|
|
System.out.println("Out of tracks!"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
System.out.println("Buffer filled, submitting."); |
|
|
|
|
ret.rewind(); // required apparently, if returned buf has pos > 0 you get silence
|
|
|
|
|
assert ret.hasArray(); // output MUST be array backed
|
|
|
|
|
return ret; |
|
|
|
|
// 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)
|
|
|
|
|