1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-05-15 05:44:11 +00:00

Fix speaker.playAudio not updating volume

Honestly, the whole design around volume and playSound/playAudio is a
little janky — it probably should be a separate setVolume method which
updates directly. But too late to change that now, so let's do what we
can.

See #2108
This commit is contained in:
Jonathan Coates 2025-03-01 20:28:37 +00:00
parent 6660966320
commit 9d2c2db22b
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
2 changed files with 23 additions and 5 deletions

View File

@ -24,7 +24,7 @@ public class SpeakerInstance {
SpeakerInstance() { SpeakerInstance() {
} }
private void pushAudio(EncodedAudio buffer) { private void pushAudio(EncodedAudio buffer, float volume) {
var sound = this.sound; var sound = this.sound;
var stream = currentStream; var stream = currentStream;
@ -32,18 +32,30 @@ public class SpeakerInstance {
var exhausted = stream.isEmpty(); var exhausted = stream.isEmpty();
stream.push(buffer); stream.push(buffer);
// If we've got nothing left in the buffer, enqueue an additional one just in case. if (sound == null) return;
if (exhausted && sound != null && sound.stream == stream && stream.channel != null && stream.executor != null) {
var volumeChanged = sound.setVolume(volume);
if ((exhausted || volumeChanged) && sound.stream == stream && stream.channel != null && stream.executor != null) {
var actualStream = sound.stream; var actualStream = sound.stream;
stream.executor.execute(() -> { stream.executor.execute(() -> {
var channel = Nullability.assertNonNull(actualStream.channel); var channel = Nullability.assertNonNull(actualStream.channel);
if (!channel.stopped()) channel.pumpBuffers(1); if (channel.stopped()) return;
// If we've got nothing left in the buffer, enqueue an additional one just in case.
if (exhausted) channel.pumpBuffers(1);
// Update the attenuation if the volume has changed: SoundEngine.tickNonPaused updates the volume
// itself, but leaves the attenuation unchanged. We mirror the logic of SoundEngine.play here.
if (volumeChanged) {
channel.linearAttenuation(Math.max(volume, 1) * sound.getSound().getAttenuationDistance());
}
}); });
} }
} }
public void playAudio(SpeakerPosition position, float volume, EncodedAudio buffer) { public void playAudio(SpeakerPosition position, float volume, EncodedAudio buffer) {
pushAudio(buffer); pushAudio(buffer, volume);
var soundManager = Minecraft.getInstance().getSoundManager(); var soundManager = Minecraft.getInstance().getSoundManager();

View File

@ -83,4 +83,10 @@ public class SpeakerSound extends AbstractSoundInstance implements TickableSound
public @Nullable AudioStream getStream() { public @Nullable AudioStream getStream() {
return stream; return stream;
} }
boolean setVolume(float volume) {
if (volume == this.volume) return false;
this.volume = volume;
return true;
}
} }