Files
TetrisClone/src/main/java/eu/midnightdust/yaytris/util/sound/MusicThread.java
Martin Prokoph 7cbe2466d8 fix: Windows support
eww...
2025-09-08 18:27:22 +02:00

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
}
}
}