From f3ec709997d966834cd7392b74260af7c7da8ddd Mon Sep 17 00:00:00 2001 From: RaphiMC <50594595+RaphiMC@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:09:49 +0200 Subject: [PATCH] Replace AL_SOFT_events with polling again AL_SOFT_events is currently not well suited for use in NoteBlockTool. See https://github.com/kcat/openal-soft/issues/1003 --- .../export/impl/OpenALAudioExporter.java | 1 + .../audio/soundsystem/SoundSystem.java | 2 +- .../soundsystem/impl/JavaxSoundSystem.java | 2 +- .../impl/MultithreadedJavaxSoundSystem.java | 2 +- .../soundsystem/impl/OpenALSoundSystem.java | 33 ++++++++----------- .../noteblocktool/frames/SongPlayerFrame.java | 2 +- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/raphimc/noteblocktool/audio/export/impl/OpenALAudioExporter.java b/src/main/java/net/raphimc/noteblocktool/audio/export/impl/OpenALAudioExporter.java index cfda9a7..4714d34 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/export/impl/OpenALAudioExporter.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/export/impl/OpenALAudioExporter.java @@ -41,6 +41,7 @@ protected void processSound(final String sound, final float pitch, final float v @Override protected void writeSamples() { this.soundSystem.renderSamples(this.sampleOutputStream, this.samplesPerTick); + this.soundSystem.tick(); } @Override diff --git a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/SoundSystem.java b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/SoundSystem.java index 417f493..1f10578 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/SoundSystem.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/SoundSystem.java @@ -27,7 +27,7 @@ public SoundSystem(final int maxSounds) { public abstract void playSound(final String sound, final float pitch, final float volume, final float panning); - public void writeSamples() { + public void tick() { } public abstract void stopSounds(); diff --git a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/JavaxSoundSystem.java b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/JavaxSoundSystem.java index 5d8ede9..49c1d6f 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/JavaxSoundSystem.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/JavaxSoundSystem.java @@ -69,7 +69,7 @@ public synchronized void playSound(final String sound, final float pitch, final } @Override - public synchronized void writeSamples() { + public synchronized void tick() { final long[] samples = new long[this.samplesPerTick]; final int[] outputBuffer = new int[this.samplesPerTick]; final int[] mutationBuffer = new int[this.samplesPerTick * 2]; diff --git a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/MultithreadedJavaxSoundSystem.java b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/MultithreadedJavaxSoundSystem.java index 62dd8ba..0441c0c 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/MultithreadedJavaxSoundSystem.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/MultithreadedJavaxSoundSystem.java @@ -89,7 +89,7 @@ public MultithreadedJavaxSoundSystem(final int maxSounds, final float playbackSp } @Override - public synchronized void writeSamples() { + public synchronized void tick() { this.soundsToRender.addAll(this.playingSounds); this.syncLock.set(this.playingSounds.size()); while (this.syncLock.get() != 0 && !Thread.currentThread().isInterrupted()) { diff --git a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java index 91d55da..2c0a345 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java @@ -64,17 +64,6 @@ public static OpenALSoundSystem createCapture(final int maxSounds, final AudioFo private Thread shutdownHook; private ByteBuffer captureBuffer; - @SuppressWarnings("FieldCanBeLocal") - private final SOFTEventProcI eventCallback = (eventType, object, param, length, message, userParam) -> { - if (eventType == SOFTEvents.AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT && param == AL10.AL_STOPPED) { - synchronized (this) { - this.playingSources.remove((Integer) object); - AL10.alDeleteSources(object); - this.checkALError("Could not delete audio source", AL10.AL_INVALID_NAME); - } - } - }; - private OpenALSoundSystem(final int maxSounds) { this(maxSounds, null); } @@ -130,9 +119,6 @@ private OpenALSoundSystem(final int maxSounds, final AudioFormat captureAudioFor if (!alCapabilities.OpenAL11) { throw new RuntimeException("OpenAL 1.1 is not supported"); } - if (!alCapabilities.AL_SOFT_events) { - throw new RuntimeException("AL_SOFT_events is not supported"); - } AL10.alDistanceModel(AL10.AL_NONE); this.checkALError("Could not set distance model"); @@ -149,11 +135,6 @@ private OpenALSoundSystem(final int maxSounds, final AudioFormat captureAudioFor throw new RuntimeException("Could not load sound samples", e); } - SOFTEvents.alEventCallbackSOFT(this.eventCallback, null); - this.checkALError("Could not set event callback"); - SOFTEvents.alEventControlSOFT(new int[]{SOFTEvents.AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT}, true); - this.checkALError("Could not configure event control"); - Runtime.getRuntime().addShutdownHook(this.shutdownHook = new Thread(() -> { this.shutdownHook = null; this.close(); @@ -190,6 +171,20 @@ public synchronized void playSound(final String sound, final float pitch, final this.playingSources.add(source); } + @Override + public synchronized void tick() { + this.playingSources.removeIf(source -> { + final int state = AL10.alGetSourcei(source, AL10.AL_SOURCE_STATE); + this.checkALError("Could not get audio source state"); + if (state == AL10.AL_STOPPED) { + AL10.alDeleteSources(source); + this.checkALError("Could not delete audio source"); + return true; + } + return false; + }); + } + public synchronized void renderSamples(final SampleOutputStream outputStream, final int sampleCount) { final int samplesLength = sampleCount * this.captureAudioFormat.getChannels(); if (samplesLength * this.captureAudioFormat.getSampleSizeInBits() / 8 > this.captureBuffer.capacity()) { diff --git a/src/main/java/net/raphimc/noteblocktool/frames/SongPlayerFrame.java b/src/main/java/net/raphimc/noteblocktool/frames/SongPlayerFrame.java index 74f2ae8..33876fb 100644 --- a/src/main/java/net/raphimc/noteblocktool/frames/SongPlayerFrame.java +++ b/src/main/java/net/raphimc/noteblocktool/frames/SongPlayerFrame.java @@ -348,7 +348,7 @@ public void playCustomNote(NbsCustomInstrument customInstrument, float pitch, fl public void playNotes(java.util.List notes) { for (Note note : notes) this.playNote(note); - this.soundSystem.writeSamples(); + this.soundSystem.tick(); } }