feat: music & sound!!!
This commit is contained in:
108
src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java
Normal file
108
src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package eu.midnightdust.yaytris.util;
|
||||
|
||||
import eu.midnightdust.yaytris.Settings;
|
||||
|
||||
import javax.sound.sampled.*;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SoundUtil {
|
||||
private static final Map<String, MusicThread> musicThreads = new HashMap<>();
|
||||
|
||||
public static void playMusic(String fileLocation, boolean looped) {
|
||||
if (musicThreads.containsKey(fileLocation)) stopMusic(fileLocation);
|
||||
MusicThread musicThread = new MusicThread(fileLocation, looped);
|
||||
musicThread.start();
|
||||
musicThreads.put(fileLocation, musicThread);
|
||||
}
|
||||
|
||||
public static void stopMusic(String fileLocation) {
|
||||
if (musicThreads.containsKey(fileLocation)) musicThreads.get(fileLocation).stopMusic();
|
||||
}
|
||||
|
||||
// Adapted from: https://www.baeldung.com/java-play-sound
|
||||
public static void playSoundClip(String fileLocation) {
|
||||
try (AudioInputStream stream = AudioSystem.getAudioInputStream(SoundUtil.class.getResource(fileLocation))) { // FIXME: Support audio files from JAR. File streams won't work here for some reason.
|
||||
AudioFormat format = stream.getFormat();
|
||||
DataLine.Info info = new DataLine.Info(Clip.class, format);
|
||||
|
||||
Clip audioClip = (Clip) AudioSystem.getLine(info);
|
||||
audioClip.addLineListener(new LineUpdateListener());
|
||||
audioClip.open(stream);
|
||||
audioClip.start();
|
||||
setVolume(audioClip, Settings.soundVolume);
|
||||
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from: https://stackoverflow.com/a/40698149
|
||||
private static void setVolume(Line line, int volume) {
|
||||
if (volume < 0 || volume > 100)
|
||||
throw new IllegalArgumentException("Volume not valid: " + volume);
|
||||
FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
|
||||
gainControl.setValue(20f * (float) Math.log10(volume/100f));
|
||||
}
|
||||
|
||||
public static class MusicThread extends Thread {
|
||||
private static final int BUFFER_SIZE = 8192;
|
||||
private final boolean looped;
|
||||
private final String fileLocation;
|
||||
private boolean playing;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Adapted from: https://www.baeldung.com/java-play-sound
|
||||
private void playMusic(String fileLocation) {
|
||||
try (AudioInputStream stream = AudioSystem.getAudioInputStream(SoundUtil.class.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();
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LineUpdateListener implements LineListener {
|
||||
@Override
|
||||
public void update(LineEvent event) {
|
||||
if (LineEvent.Type.STOP == event.getType()) {
|
||||
event.getLine().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user