lawless-legends/Platform/Apple/tools/jace/src/main/java/jace/lawless/MediaPlayer.java
2024-02-25 21:10:39 -06:00

133 lines
4.0 KiB
Java

package jace.lawless;
import java.time.Duration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import jace.core.SoundMixer;
import jace.core.SoundMixer.SoundBuffer;
import jace.core.SoundMixer.SoundError;
public class MediaPlayer {
double vol = 1.0;
int repeats = 0;
int maxRepetitions = 1;
Status status = Status.NOT_STARTED;
Media soundData;
SoundBuffer playbackBuffer;
Duration lastKnownDuration = Duration.ZERO;
Executor executor = Executors.newSingleThreadExecutor();
public static enum Status {
NOT_STARTED, PLAYING, PAUSED, STOPPED
}
public static final int INDEFINITE = -1;
public MediaPlayer(Media song) {
this.soundData = song;
}
public Status getStatus() {
return status;
}
public Duration getCurrentTime() {
if (soundData == null) {
return lastKnownDuration;
} else {
return soundData.getCurrentTime();
}
}
public double getVolume() {
return vol;
}
// NOTE: Once a song is stopped, it cannot be restarted.
public void stop() {
status = Status.STOPPED;
try {
if (playbackBuffer != null) {
playbackBuffer.flush();
playbackBuffer.shutdown();
playbackBuffer = null;
}
} catch (InterruptedException | ExecutionException | SoundError e) {
// Ignore exception on shutdown
} finally {
if (soundData != null) {
lastKnownDuration = soundData.getCurrentTime();
soundData.close();
}
soundData = null;
}
}
public void setCycleCount(int i) {
maxRepetitions = i;
}
public void setVolume(double d) {
vol = Math.max(0.0, Math.min(1.0, d));
}
public void setStartTime(javafx.util.Duration millis) {
soundData.seekToTime(millis);
}
public void pause() {
status = Status.PAUSED;
}
public void play() {
if (status == Status.STOPPED) {
return;
} else if (status == Status.NOT_STARTED) {
repeats = 0;
if (playbackBuffer == null || !playbackBuffer.isAlive()) {
try {
playbackBuffer = SoundMixer.createBuffer(true);
} catch (InterruptedException | ExecutionException | SoundError e) {
stop();
return;
}
if (playbackBuffer == null) {
stop();
return;
}
}
}
executor.execute(() -> {
status = Status.PLAYING;
// System.out.println("Song playback thread started");
Media theSoundData = soundData;
while (status == Status.PLAYING && (maxRepetitions == INDEFINITE || repeats < maxRepetitions) && theSoundData != null) {
if (theSoundData.isEnded()) {
if (maxRepetitions == INDEFINITE) {
theSoundData.restart();
} else {
repeats++;
if (repeats < maxRepetitions) {
theSoundData.restart();
} else {
System.out.println("Song ended");
this.stop();
break;
}
}
}
try {
playbackBuffer.playSample((short) (theSoundData.getNextLeftSample() * vol));
playbackBuffer.playSample((short) (theSoundData.getNextRightSample() * vol));
} catch (InterruptedException | ExecutionException | SoundError e) {
e.printStackTrace();
this.stop();
}
theSoundData = soundData;
}
});
}
}