Working sound effect for clicking, bug when using audio volume changer (changes some sounds to be wrong)

This commit is contained in:
lieght
2025-10-03 17:12:50 +02:00
parent 5a200a8a70
commit dd192692bd
7 changed files with 83 additions and 16 deletions

View File

@@ -1,5 +1,7 @@
package org.toop.framework.asset;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.asset.resources.*;
import java.util.*;
@@ -46,6 +48,7 @@ import java.util.concurrent.ConcurrentHashMap;
* </ul>
*/
public class ResourceManager {
private static final Logger logger = LogManager.getLogger(ResourceManager.class);
private static final ResourceManager INSTANCE = new ResourceManager();
private static final Map<String, ResourceMeta<? extends BaseResource>> assets = new ConcurrentHashMap<>();

View File

@@ -23,7 +23,10 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource {
Clip clip = AudioSystem.getClip();
// Insert a new audio stream into the clip
clip.open(this.getAudioStream());
AudioInputStream inputStream = this.getAudioStream();
AudioFormat baseFormat = inputStream.getFormat();
if (baseFormat.getSampleSizeInBits() > 16) inputStream = downSampleAudio(inputStream, baseFormat);
clip.open(inputStream); // ^ Clip can only run 16 bit and lower, thus downsampling necessary.
return clip;
}
@@ -32,6 +35,20 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource {
return AudioSystem.getAudioInputStream(this.file);
}
private AudioInputStream downSampleAudio(AudioInputStream audioInputStream, AudioFormat baseFormat) {
AudioFormat decodedFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16, // force 16-bit
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false // little-endian
);
return AudioSystem.getAudioInputStream(decodedFormat, audioInputStream);
}
@Override
public void load() {
try {

View File

@@ -1,5 +1,7 @@
package org.toop.framework.audio;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.SnowflakeGenerator;
import org.toop.framework.asset.ResourceManager;
import org.toop.framework.asset.ResourceMeta;
@@ -15,6 +17,7 @@ import java.util.*;
import javax.sound.sampled.*;
public class SoundManager {
private static final Logger logger = LogManager.getLogger(SoundManager.class);
private final List<MediaPlayer> activeMusic = new ArrayList<>();
private final Queue<MusicAsset> backgroundMusicQueue = new LinkedList<>();
private final Map<Long, Clip> activeSoundEffects = new HashMap<>();
@@ -38,16 +41,16 @@ public class SoundManager {
.listen(this::handleMusicStart)
.listen(this::handleVolumeChange)
.listen(this::handleGetCurrentVolume)
.listen(AudioEvents.playOnClickButton.class, _ -> {
.listen(AudioEvents.clickButton.class, _ -> {
try {
playSound("hitsound0.wav", false);
playSound("medium-button-click.wav", false);
} catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) {
throw new RuntimeException(e);
logger.error(e);
}
});
}
private void handlePlaySound(AudioEvents.PlayAudio event) {
private void handlePlaySound(AudioEvents.PlayEffect event) {
try {
this.playSound(event.fileName(), event.loop());
} catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) {
@@ -55,7 +58,7 @@ public class SoundManager {
}
}
private void handleStopSound(AudioEvents.StopAudio event) {
private void handleStopSound(AudioEvents.StopEffect event) {
this.stopSound(event.clipId());
}
@@ -71,7 +74,6 @@ public class SoundManager {
for (MediaPlayer mediaPlayer : this.activeMusic) {
mediaPlayer.setVolume(this.volume);
}
IO.println("Volume: " + this.volume);
}
private void handleGetCurrentVolume(AudioEvents.GetCurrentVolume event) {
@@ -125,13 +127,15 @@ public class SoundManager {
mediaPlayer.setVolume(this.volume);
mediaPlayer.play();
activeMusic.add(mediaPlayer);
logger.info("Playing background music: {}", ma.getFile().getName());
}
private long playSound(String audioFileName, boolean loop) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
SoundEffectAsset asset = audioResources.get(audioFileName);
// Return -1 which indicates resource wasn't available
if (asset == null){
if (asset == null) {
logger.warn("Unable to load audio asset: {}", audioFileName);
return -1;
}
@@ -146,6 +150,8 @@ public class SoundManager {
clip.start();
}
logger.info("Playing sound: {}", asset.getFile().getName());
// Generate id for clip
long clipId = idGenerator.nextId();

View File

@@ -1,6 +1,5 @@
package org.toop.framework.audio.events;
import org.toop.framework.asset.resources.MusicAsset;
import org.toop.framework.eventbus.events.EventWithSnowflake;
import org.toop.framework.eventbus.events.EventWithoutSnowflake;
import org.toop.framework.eventbus.events.EventsBase;
@@ -9,10 +8,10 @@ import java.util.Map;
public class AudioEvents extends EventsBase {
/** Starts playing a sound. */
public record PlayAudio(String fileName, boolean loop)
public record PlayEffect(String fileName, boolean loop)
implements EventWithoutSnowflake {}
public record StopAudio(long clipId) implements EventWithoutSnowflake {}
public record StopEffect(long clipId) implements EventWithoutSnowflake {}
public record StartBackgroundMusic() implements EventWithoutSnowflake {}
public record ChangeVolume(double newVolume) implements EventWithoutSnowflake {}
@@ -38,5 +37,5 @@ public class AudioEvents extends EventsBase {
return snowflakeId;
}
}
public record playOnClickButton() implements EventWithoutSnowflake {}
public record clickButton() implements EventWithoutSnowflake {}
}