Skip to content

Commit 654f26b

Browse files
authored
jme3-examples: TestWav - test code optimization
1 parent 2fa2101 commit 654f26b

File tree

1 file changed

+95
-20
lines changed

1 file changed

+95
-20
lines changed

jme3-examples/src/main/java/jme3test/audio/TestWav.java

Lines changed: 95 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2012 jMonkeyEngine
2+
* Copyright (c) 2009-2025 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -33,32 +33,107 @@
3333

3434
import com.jme3.app.SimpleApplication;
3535
import com.jme3.audio.AudioData;
36+
import com.jme3.audio.AudioKey;
3637
import com.jme3.audio.AudioNode;
3738

39+
/**
40+
* @author capdevon
41+
*/
3842
public class TestWav extends SimpleApplication {
3943

40-
private float time = 0;
41-
private AudioNode audioSource;
44+
private float time = 0;
45+
private AudioNode audioSource;
46+
47+
public static void main(String[] args) {
48+
TestWav test = new TestWav();
49+
test.start();
50+
}
4251

43-
public static void main(String[] args) {
44-
TestWav test = new TestWav();
45-
test.start();
46-
}
52+
@Override
53+
public void simpleInitApp() {
54+
testMaxNumChannels();
55+
testFakeAudio();
56+
testPlaySourceInstance();
4757

48-
@Override
49-
public void simpleUpdate(float tpf) {
50-
time += tpf;
51-
if (time > 1f) {
52-
audioSource.playInstance();
53-
time = 0;
58+
audioSource = createAudioNode("Sound/Effects/Gun.wav", AudioData.DataType.Buffer);
59+
audioSource.setName("Gun");
60+
audioSource.setPositional(true);
5461
}
5562

56-
}
63+
@Override
64+
public void simpleUpdate(float tpf) {
65+
time += tpf;
66+
if (time > 1f) {
67+
audioSource.playInstance();
68+
time = 0;
69+
}
70+
}
71+
72+
/**
73+
* Creates an {@link AudioNode} for the specified audio file.
74+
* This method demonstrates an alternative way to defer the creation
75+
* of an AudioNode by explicitly creating and potentially pre-loading
76+
* the {@link AudioData} and {@link AudioKey} before instantiating
77+
* the AudioNode. This can be useful in scenarios where you want more
78+
* control over the asset loading process or when the AudioData and
79+
* AudioKey are already available.
80+
*
81+
* @param filepath The path to the audio file.
82+
* @param type The desired {@link AudioData.DataType} for the audio.
83+
* @return A new {@code AudioNode} configured with the loaded audio data.
84+
*/
85+
private AudioNode createAudioNode(String filepath, AudioData.DataType type) {
86+
boolean stream = (type == AudioData.DataType.Stream);
87+
boolean streamCache = true;
88+
AudioKey audioKey = new AudioKey(filepath, stream, streamCache);
89+
AudioData data = assetManager.loadAsset(audioKey);
90+
91+
AudioNode audio = new AudioNode();
92+
audio.setAudioData(data, audioKey);
93+
return audio;
94+
}
95+
96+
/**
97+
* WARNING: No channel available to play instance of AudioNode[status=Stopped, vol=0.1]
98+
*/
99+
private void testMaxNumChannels() {
100+
final int MAX_NUM_CHANNELS = 64;
101+
for (int i = 0; i < MAX_NUM_CHANNELS + 1; i++) {
102+
AudioNode audio = createAudioNode("Sound/Effects/Gun.wav", AudioData.DataType.Buffer);
103+
audio.setVolume(0.1f);
104+
audio.playInstance();
105+
}
106+
}
107+
108+
/**
109+
* java.lang.UnsupportedOperationException: Cannot play instances of audio streams. Use play() instead.
110+
* at com.jme3.audio.openal.ALAudioRenderer.playSourceInstance()
111+
*/
112+
private void testPlaySourceInstance() {
113+
try {
114+
AudioNode nature = new AudioNode(assetManager,
115+
"Sound/Environment/Nature.ogg", AudioData.DataType.Stream);
116+
audioRenderer.playSourceInstance(nature);
117+
} catch (Exception e) {
118+
e.printStackTrace();
119+
}
120+
}
121+
122+
private void testFakeAudio() {
123+
/**
124+
* Tests AudioRenderer.playSource() with an
125+
* AudioNode lacking AudioData to observe its handling (typically discard).
126+
*/
127+
AudioNode fakeAudio = new AudioNode() {
128+
@Override
129+
public String toString() {
130+
// includes node name for easier identification in log messages.
131+
return getName() + " (" + AudioNode.class.getSimpleName() + ")";
132+
}
133+
};
134+
fakeAudio.setName("FakeAudio");
135+
audioRenderer.playSource(fakeAudio);
136+
audioRenderer.playSourceInstance(fakeAudio);
137+
}
57138

58-
@Override
59-
public void simpleInitApp() {
60-
audioSource = new AudioNode(assetManager, "Sound/Effects/Gun.wav",
61-
AudioData.DataType.Buffer);
62-
audioSource.setLooping(false);
63-
}
64139
}

0 commit comments

Comments
 (0)