73 lines
2.4 KiB
Java
73 lines
2.4 KiB
Java
package eu.midnightdust.yaytris.util.sound;
|
|
|
|
import eu.midnightdust.yaytris.Settings;
|
|
|
|
import javax.sound.sampled.*;
|
|
import java.io.IOException;
|
|
|
|
/**
|
|
* Handle music in separate threads to not interrupt the main game
|
|
*/
|
|
public class MusicThread extends Thread {
|
|
private static final int BUFFER_SIZE = 8192;
|
|
private final boolean looped;
|
|
private final String fileLocation;
|
|
private boolean playing;
|
|
|
|
public MusicThread(String fileLocation, boolean looped) {
|
|
this.fileLocation = fileLocation;
|
|
this.looped = looped;
|
|
this.playing = true;
|
|
}
|
|
|
|
public void stopMusic() {
|
|
this.playing = false;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
do {
|
|
playMusic(fileLocation);
|
|
} while (looped && playing);
|
|
}
|
|
|
|
/**
|
|
* INTERNAL!
|
|
* Play the long audio file found at the specified location.
|
|
* Fades out after calling {@link #stopMusic()}.
|
|
* Adapted from: <a href="https://www.baeldung.com/java-play-sound">Baeldung</a>
|
|
*
|
|
* @see SoundUtil#playMusic(String, boolean)
|
|
*/
|
|
private void playMusic(String fileLocation) {
|
|
try (AudioInputStream stream = AudioSystem.getAudioInputStream(SoundUtil.getResource(fileLocation))) {
|
|
AudioFormat format = stream.getFormat();
|
|
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
|
|
|
|
SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
|
|
sourceDataLine.open(format);
|
|
sourceDataLine.start();
|
|
SoundUtil.setVolume(sourceDataLine, Settings.musicVolume);
|
|
float fadeOut = 1.0f;
|
|
|
|
byte[] bufferBytes = new byte[BUFFER_SIZE];
|
|
int readBytes;
|
|
while ((readBytes = stream.read(bufferBytes)) != -1) {
|
|
if (!playing) {
|
|
fadeOut = (float) Math.sin(fadeOut - 0.01f); // Sinus fade-out
|
|
SoundUtil.setVolume(sourceDataLine, (int) (fadeOut * Settings.musicVolume));
|
|
if (fadeOut <= 0) break;
|
|
}
|
|
sourceDataLine.write(bufferBytes, 0, readBytes);
|
|
}
|
|
|
|
sourceDataLine.drain();
|
|
sourceDataLine.close();
|
|
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (IllegalArgumentException ignored) {
|
|
// Happens when no audio device is connected
|
|
}
|
|
}
|
|
}
|