Skip to content

change audio system for one-shot samples to improve performance #109

Merged
merged 1 commit into from
May 14, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Audio/Audio.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,28 @@
public enum Audio {

// Sound effects
OPEN_APP("/Audio/open_app.mp3"),
CLOSE_APP("/Audio/close_app.mp3"),
WARNING("/Audio/warning.mp3"),
CLOCK("/Audio/clock.mp3"),
OPEN_APP("/Audio/open_app.wav", true),
CLOSE_APP("/Audio/close_app.wav", true),
WARNING("/Audio/warning.wav", true),
CLOCK("/Audio/clock.wav", true),

// Background music
WEEKEND_THEME("/Audio/weekend_theme.mp3"),
GAME_OVER_THEME("/Audio/game_over_theme.mp3");
WEEKEND_THEME("/Audio/weekend_theme.mp3", false),
GAME_OVER_THEME("/Audio/game_over_theme.mp3", false);

private String path;
private boolean isSFX;

Audio(String path) {
Audio(String path, boolean isSFX) {
this.path = path;
this.isSFX = isSFX;
}

public String getPath() {
return path;
}

public boolean isSFX() {
return isSFX;
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,58 @@
package edu.ntnu.idi.idatt2003.gruppe42.Audio;

import javax.sound.sampled.*;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;

import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;

public class AudioManager {

private static final AudioManager instance = new AudioManager();
private final Map<Audio, String> urlCache = new EnumMap<>(Audio.class);
private final Map<Audio, byte[]> sfxCache = new EnumMap<>(Audio.class);
private MediaPlayer bgPlayer;

private AudioManager() {
for (Audio audio : Audio.values()) {
var url = getClass().getResource(audio.getPath());
urlCache.put(audio, url.toExternalForm());
if (audio.isSFX()) {
try (var stream = getClass().getResourceAsStream(audio.getPath())) {
sfxCache.put(audio, stream.readAllBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

public static AudioManager getInstance() { return instance; }

public void playSFX(Audio audio) {
String url = urlCache.get(audio);

if (url == null) {
return;
}

MediaPlayer sfxPlayer = new MediaPlayer(new Media(url));
sfxPlayer.setOnEndOfMedia(() -> {
sfxPlayer.stop();
sfxPlayer.dispose();
});
byte[] data = sfxCache.get(audio);
if (data == null) return;

sfxPlayer.play();
new Thread(() -> {
try {
var stream = AudioSystem.getAudioInputStream(
new java.io.ByteArrayInputStream(data));
Clip clip = AudioSystem.getClip();
clip.open(stream);
clip.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) clip.close();
});
clip.start();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}

public void playBgMusic(Audio audio) {
stopBgMusic();

String url = urlCache.get(audio);
if (url == null) {
return;
}

var url = getClass().getResource(audio.getPath()).toExternalForm();
bgPlayer = new MediaPlayer(new Media(url));
bgPlayer.setVolume(1);
bgPlayer.setCycleCount(MediaPlayer.INDEFINITE);
bgPlayer.setVolume(0.5);
bgPlayer.play();
}

Expand Down
Binary file removed src/main/resources/Audio/clock.mp3
Binary file not shown.
Binary file added src/main/resources/Audio/clock.wav
Binary file not shown.
Binary file removed src/main/resources/Audio/close_app.mp3
Binary file not shown.
Binary file added src/main/resources/Audio/close_app.wav
Binary file not shown.
Binary file removed src/main/resources/Audio/open_app.mp3
Binary file not shown.
Binary file added src/main/resources/Audio/open_app.wav
Binary file not shown.
Binary file removed src/main/resources/Audio/warning.mp3
Binary file not shown.
Binary file added src/main/resources/Audio/warning.wav
Binary file not shown.