From 654f26badeea5515fa7b2afdbc8ad5d8d3813ab7 Mon Sep 17 00:00:00 2001 From: Wyatt Gillette Date: Thu, 8 May 2025 19:00:09 +0200 Subject: [PATCH 1/2] jme3-examples: TestWav - test code optimization --- .../src/main/java/jme3test/audio/TestWav.java | 115 +++++++++++++++--- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/jme3-examples/src/main/java/jme3test/audio/TestWav.java b/jme3-examples/src/main/java/jme3test/audio/TestWav.java index 70ec211f23..edeb68220f 100644 --- a/jme3-examples/src/main/java/jme3test/audio/TestWav.java +++ b/jme3-examples/src/main/java/jme3test/audio/TestWav.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2025 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,32 +33,107 @@ import com.jme3.app.SimpleApplication; import com.jme3.audio.AudioData; +import com.jme3.audio.AudioKey; import com.jme3.audio.AudioNode; +/** + * @author capdevon + */ public class TestWav extends SimpleApplication { - private float time = 0; - private AudioNode audioSource; + private float time = 0; + private AudioNode audioSource; + + public static void main(String[] args) { + TestWav test = new TestWav(); + test.start(); + } - public static void main(String[] args) { - TestWav test = new TestWav(); - test.start(); - } + @Override + public void simpleInitApp() { + testMaxNumChannels(); + testFakeAudio(); + testPlaySourceInstance(); - @Override - public void simpleUpdate(float tpf) { - time += tpf; - if (time > 1f) { - audioSource.playInstance(); - time = 0; + audioSource = createAudioNode("Sound/Effects/Gun.wav", AudioData.DataType.Buffer); + audioSource.setName("Gun"); + audioSource.setPositional(true); } - } + @Override + public void simpleUpdate(float tpf) { + time += tpf; + if (time > 1f) { + audioSource.playInstance(); + time = 0; + } + } + + /** + * Creates an {@link AudioNode} for the specified audio file. + * This method demonstrates an alternative way to defer the creation + * of an AudioNode by explicitly creating and potentially pre-loading + * the {@link AudioData} and {@link AudioKey} before instantiating + * the AudioNode. This can be useful in scenarios where you want more + * control over the asset loading process or when the AudioData and + * AudioKey are already available. + * + * @param filepath The path to the audio file. + * @param type The desired {@link AudioData.DataType} for the audio. + * @return A new {@code AudioNode} configured with the loaded audio data. + */ + private AudioNode createAudioNode(String filepath, AudioData.DataType type) { + boolean stream = (type == AudioData.DataType.Stream); + boolean streamCache = true; + AudioKey audioKey = new AudioKey(filepath, stream, streamCache); + AudioData data = assetManager.loadAsset(audioKey); + + AudioNode audio = new AudioNode(); + audio.setAudioData(data, audioKey); + return audio; + } + + /** + * WARNING: No channel available to play instance of AudioNode[status=Stopped, vol=0.1] + */ + private void testMaxNumChannels() { + final int MAX_NUM_CHANNELS = 64; + for (int i = 0; i < MAX_NUM_CHANNELS + 1; i++) { + AudioNode audio = createAudioNode("Sound/Effects/Gun.wav", AudioData.DataType.Buffer); + audio.setVolume(0.1f); + audio.playInstance(); + } + } + + /** + * java.lang.UnsupportedOperationException: Cannot play instances of audio streams. Use play() instead. + * at com.jme3.audio.openal.ALAudioRenderer.playSourceInstance() + */ + private void testPlaySourceInstance() { + try { + AudioNode nature = new AudioNode(assetManager, + "Sound/Environment/Nature.ogg", AudioData.DataType.Stream); + audioRenderer.playSourceInstance(nature); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void testFakeAudio() { + /** + * Tests AudioRenderer.playSource() with an + * AudioNode lacking AudioData to observe its handling (typically discard). + */ + AudioNode fakeAudio = new AudioNode() { + @Override + public String toString() { + // includes node name for easier identification in log messages. + return getName() + " (" + AudioNode.class.getSimpleName() + ")"; + } + }; + fakeAudio.setName("FakeAudio"); + audioRenderer.playSource(fakeAudio); + audioRenderer.playSourceInstance(fakeAudio); + } - @Override - public void simpleInitApp() { - audioSource = new AudioNode(assetManager, "Sound/Effects/Gun.wav", - AudioData.DataType.Buffer); - audioSource.setLooping(false); - } } From 0c636aa9bd6526c4d5119cfa1eeb1fc0a45f8f27 Mon Sep 17 00:00:00 2001 From: Wyatt Gillette Date: Thu, 15 May 2025 18:16:41 +0200 Subject: [PATCH 2/2] TestWav: rename test -> app --- jme3-examples/src/main/java/jme3test/audio/TestWav.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jme3-examples/src/main/java/jme3test/audio/TestWav.java b/jme3-examples/src/main/java/jme3test/audio/TestWav.java index edeb68220f..a24b2f24d5 100644 --- a/jme3-examples/src/main/java/jme3test/audio/TestWav.java +++ b/jme3-examples/src/main/java/jme3test/audio/TestWav.java @@ -45,8 +45,8 @@ public class TestWav extends SimpleApplication { private AudioNode audioSource; public static void main(String[] args) { - TestWav test = new TestWav(); - test.start(); + TestWav app = new TestWav(); + app.start(); } @Override