Fixed AL close action

Added a test for the Audio Engine
Refactored Audio Engine
This commit is contained in:
Евгений Смирнов 2020-11-22 14:44:19 +03:00
parent 104d64ff9a
commit 2fbb274c31
12 changed files with 116 additions and 118 deletions

View File

@ -18,7 +18,7 @@
package ru.windcorp.progressia.client; package ru.windcorp.progressia.client;
import ru.windcorp.progressia.ProgressiaLauncher; import ru.windcorp.progressia.ProgressiaLauncher;
import ru.windcorp.progressia.client.audio.ALTest; import ru.windcorp.progressia.test.ALTest;
public class ProgressiaClientMain { public class ProgressiaClientMain {

View File

@ -1,24 +0,0 @@
package ru.windcorp.progressia.client.audio;
public class ALTest {
static private void initializeAL() {
AudioManager.initAL();
}
static void loadALData() {
AudioManager.loadSound("assets/sounds/sample_stereo.ogg",
"Progressia", "SampleStereo",
AudioFormat.STEREO);
Music music = new Music("Progressia", "SampleStereo");
music.play(false);
}
static void killALData() {
//TODO implement the method or its analogue
}
public static void execute() {
initializeAL();
loadALData();
}
}

View File

@ -26,7 +26,7 @@ public class AudioManager {
private static List<Speaker> soundSpeakers = new ArrayList<>(SOUNDS_NUM); private static List<Speaker> soundSpeakers = new ArrayList<>(SOUNDS_NUM);
private static Speaker musicSpeaker; private static Speaker musicSpeaker;
private static ArrayList<SoundType> soundsBuffer = new ArrayList<>(); private static ArrayList<SoundType> soundsBuffer = new ArrayList<>();
public static void initAL() { public static void initAL() {
String defaultDeviceName = alcGetString( String defaultDeviceName = alcGetString(
0, 0,
@ -45,13 +45,13 @@ public class AudioManager {
checkALError(); checkALError();
createBuffers(); createBuffers();
} }
public static void update() { public static void update() {
// Position of the listener // Position of the listener
Listener.getInstance().update(); Listener.getInstance().update();
} }
private static Speaker getLastSpeaker() { private static Speaker getLastSpeaker() {
Speaker speaker; Speaker speaker;
do { do {
@ -72,9 +72,9 @@ public class AudioManager {
} }
} }
throw new Exception("ERROR: The selected sound is not loaded or" + throw new Exception("ERROR: The selected sound is not loaded or" +
" not exists"); " not exists");
} }
public static Speaker initSpeaker(String soundID) { public static Speaker initSpeaker(String soundID) {
Speaker speaker = getLastSpeaker(); Speaker speaker = getLastSpeaker();
try { try {
@ -103,29 +103,30 @@ public class AudioManager {
} }
} }
public static void loadSound(String path, String namespace, String name, public static void loadSound(String path, String id, AudioFormat format) {
AudioFormat format) {
if (format == AudioFormat.MONO) { if (format == AudioFormat.MONO) {
soundsBuffer.add(AudioReader.readAsMono(path, namespace, name)); soundsBuffer.add(AudioReader.readAsMono(path, id));
} else } else
{ {
soundsBuffer.add(AudioReader.readAsStereo(path, namespace, name)); soundsBuffer.add(AudioReader.readAsStereo(path, id));
} }
} }
public static void closeAL() { public static void closeAL() {
//clearSounds();
//TODO replace alDeleteSources(SOURCES);
for (Speaker s : soundSpeakers) { for (Speaker s : soundSpeakers) {
alDeleteBuffers(s.getAudioData()); alDeleteBuffers(s.getAudioData());
alDeleteBuffers(s.getSourceData());
} }
alDeleteBuffers(musicSpeaker.getAudioData());
alDeleteBuffers(musicSpeaker.getSourceData());
alcCloseDevice(device); alcCloseDevice(device);
} }
public static ALCapabilities getALCapabilities() { public static ALCapabilities getALCapabilities() {
return alCapabilities; return alCapabilities;
} }
public static ALCCapabilities getDeviceCapabilities() { public static ALCCapabilities getDeviceCapabilities() {
return deviceCapabilities; return deviceCapabilities;
} }
@ -138,5 +139,5 @@ public class AudioManager {
musicSpeaker = new Speaker(); musicSpeaker = new Speaker();
} }
} }

View File

@ -2,30 +2,27 @@ package ru.windcorp.progressia.client.audio;
import glm.vec._3.Vec3; import glm.vec._3.Vec3;
import ru.windcorp.progressia.client.audio.backend.Speaker; import ru.windcorp.progressia.client.audio.backend.Speaker;
import ru.windcorp.progressia.common.util.Namespaced; import ru.windcorp.progressia.common.util.namespaces.Namespaced;
public class Music public class Music extends Namespaced {
extends Namespaced {
private Vec3 position = new Vec3(); private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3(); private Vec3 velocity = new Vec3();
private float pitch = 1.0f; private float pitch = 1.0f;
private float gain = 1.0f; private float gain = 1.0f;
public Music(String namespace, public Music(String id)
String name)
{ {
super(namespace, name); super(id);
} }
public Music(String namespace, public Music(String id,
String name, Vec3 position,
Vec3 position, Vec3 velocity,
Vec3 velocity, float pitch,
float pitch, float gain)
float gain)
{ {
this(namespace, name); this(id);
this.position = position; this.position = position;
this.velocity = velocity; this.velocity = velocity;
this.pitch = pitch; this.pitch = pitch;
@ -47,9 +44,6 @@ public class Music
} }
} }
//TODO implement
public void stop() {}
public void setGain(float gain) { public void setGain(float gain) {
this.gain = gain; this.gain = gain;
} }

View File

@ -2,7 +2,7 @@ package ru.windcorp.progressia.client.audio;
import glm.vec._3.Vec3; import glm.vec._3.Vec3;
import ru.windcorp.progressia.client.audio.backend.Speaker; import ru.windcorp.progressia.client.audio.backend.Speaker;
import ru.windcorp.progressia.common.util.Namespaced; import ru.windcorp.progressia.common.util.namespaces.Namespaced;
public class SoundEffect public class SoundEffect
extends Namespaced { extends Namespaced {
@ -13,20 +13,18 @@ public class SoundEffect
private float gain = 1.0f; private float gain = 1.0f;
public SoundEffect(String namespace, public SoundEffect(String id)
String name)
{ {
super(namespace, name); super(id);
} }
public SoundEffect(String namespace, public SoundEffect(String id,
String name,
Vec3 position, Vec3 position,
Vec3 velocity, Vec3 velocity,
float pitch, float pitch,
float gain) float gain)
{ {
this(namespace, name); this(id);
this.position = position; this.position = position;
this.velocity = velocity; this.velocity = velocity;
this.pitch = pitch; this.pitch = pitch;
@ -48,9 +46,6 @@ public class SoundEffect
} }
} }
//TODO implement
public void stop() {}
public void setGain(float gain) { public void setGain(float gain) {
this.gain = gain; this.gain = gain;
} }

View File

@ -11,44 +11,39 @@ import static org.lwjgl.stb.STBVorbis.*;
import static org.lwjgl.openal.AL10.*; import static org.lwjgl.openal.AL10.*;
public class AudioReader { public class AudioReader {
private AudioReader() {} private AudioReader() {}
// TODO fix converting from mono-stereo // TODO fix converting from mono-stereo
// TODO change audio naming from full path to just name private static SoundType readAsSpecified(String path, String id, int format) {
private static SoundType readAsSpecified(String path, String audioNamespace,
String audioName, int format) {
IntBuffer channelBuffer = BufferUtils.createIntBuffer(1); IntBuffer channelBuffer = BufferUtils.createIntBuffer(1);
IntBuffer rateBuffer = BufferUtils.createIntBuffer(1); IntBuffer rateBuffer = BufferUtils.createIntBuffer(1);
Resource res = ResourceManager.getResource(path); Resource res = ResourceManager.getResource(path);
ShortBuffer rawAudio = decodeVorbis(res, channelBuffer, rateBuffer); ShortBuffer rawAudio = decodeVorbis(res, channelBuffer, rateBuffer);
return new SoundType(audioNamespace ,audioName, rawAudio, format, return new SoundType(id, rawAudio, format,
rateBuffer.get(0)); rateBuffer.get(0));
} }
public static SoundType readAsMono(String path, String audioNamespace, public static SoundType readAsMono(String path, String id) {
String audioName) { return readAsSpecified(path, id, AL_FORMAT_MONO16);
return readAsSpecified(path, audioNamespace,
audioName, AL_FORMAT_MONO16);
} }
public static SoundType readAsStereo(String path,String audioNamespace, public static SoundType readAsStereo(String path,String id) {
String audioName) { return readAsSpecified(path, id, AL_FORMAT_STEREO16);
return readAsSpecified(path, audioNamespace, audioName, AL_FORMAT_STEREO16);
} }
private static ShortBuffer decodeVorbis( private static ShortBuffer decodeVorbis(
Resource dataToDecode, Resource dataToDecode,
IntBuffer channelsBuffer, IntBuffer channelsBuffer,
IntBuffer rateBuffer IntBuffer rateBuffer
) { ) {
return stb_vorbis_decode_memory( return stb_vorbis_decode_memory(
dataToDecode.readAsBytes(), dataToDecode.readAsBytes(),
channelsBuffer, channelsBuffer,
rateBuffer rateBuffer
); );
} }
} }

View File

@ -8,52 +8,50 @@ import ru.windcorp.progressia.client.graphics.world.Camera;
import static org.lwjgl.openal.AL10.*; import static org.lwjgl.openal.AL10.*;
//TODO add getters and setters
public class Listener { public class Listener {
private static final Listener INSTANCE = new Listener(); private static final Listener INSTANCE = new Listener();
private Listener() {} private Listener() {}
public static Listener getInstance() { public static Listener getInstance() {
return INSTANCE; return INSTANCE;
} }
// Params // Params
private final Vec3 position = new Vec3(); private final Vec3 position = new Vec3();
private final Vec3 velocity = new Vec3(); private final Vec3 velocity = new Vec3();
private final Vec3 oriAt = new Vec3(); private final Vec3 oriAt = new Vec3();
private final Vec3 oriUp = new Vec3(); private final Vec3 oriUp = new Vec3();
private boolean isInWorld = false; private boolean isInWorld = false;
public void update() { public void update() {
Client client = ClientState.getInstance(); Client client = ClientState.getInstance();
Camera camera = client == null ? null : client.getCamera(); Camera camera = client == null ? null : client.getCamera();
boolean wasInWorld = isInWorld; boolean wasInWorld = isInWorld;
isInWorld = client != null && camera.getAnchor() != null; isInWorld = client != null && camera.getAnchor() != null;
if (isInWorld) { if (isInWorld) {
if (wasInWorld) { if (wasInWorld) {
velocity.set(camera.getLastAnchorPosition()).sub(position).div( velocity.set(camera.getLastAnchorPosition()).sub(position).div(
(float) GraphicsInterface.getFrameLength() (float) GraphicsInterface.getFrameLength()
); );
} else { } else {
// If !wasInWorld, previous position is nonsence. Assume 0. // If !wasInWorld, previous position is nonsence. Assume 0.
velocity.set(0); velocity.set(0);
} }
position.set(camera.getLastAnchorPosition()); position.set(camera.getLastAnchorPosition());
oriAt.set(camera.getLastAnchorLookingAt()); oriAt.set(camera.getLastAnchorLookingAt());
oriUp.set(camera.getLastAnchorUp()); oriUp.set(camera.getLastAnchorUp());
} else if (wasInWorld) { // Do not reset if we weren't in world } else if (wasInWorld) { // Do not reset if we weren't in world
resetParams(); resetParams();
} }
/* /*
* Only apply if there is a chance that params changed. * Only apply if there is a chance that params changed.
* This can only happen if we are in world now (isInWorld) or we just * This can only happen if we are in world now (isInWorld) or we just
@ -63,20 +61,20 @@ public class Listener {
applyParams(); applyParams();
} }
} }
private void resetParams() { private void resetParams() {
position.set(0); position.set(0);
velocity.set(0); velocity.set(0);
oriAt.set(0); oriAt.set(0);
oriUp.set(0); oriUp.set(0);
} }
private void applyParams() { private void applyParams() {
alListener3f(AL_POSITION, position.x, position.y, position.z); alListener3f(AL_POSITION, position.x, position.y, position.z);
alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
alListenerfv(AL_ORIENTATION, new float[] { alListenerfv(AL_ORIENTATION, new float[] {
oriAt.x, oriAt.y, oriAt.z, oriUp.x, oriUp.y, oriUp.z oriAt.x, oriAt.y, oriAt.z, oriUp.x, oriUp.y, oriUp.z
}); });
} }
} }

View File

@ -1,26 +1,26 @@
package ru.windcorp.progressia.client.audio.backend; package ru.windcorp.progressia.client.audio.backend;
import ru.windcorp.progressia.common.util.Namespaced; import ru.windcorp.progressia.common.util.namespaces.Namespaced;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import static org.lwjgl.openal.AL11.*; import static org.lwjgl.openal.AL11.*;
public class SoundType extends Namespaced { public class SoundType extends Namespaced {
private ShortBuffer rawAudio; private ShortBuffer rawAudio;
private int sampleRate; private int sampleRate;
private int format; private int format;
private int audioBuffer; private int audioBuffer;
public SoundType(String namespace, String name, ShortBuffer rawAudio, public SoundType(String id, ShortBuffer rawAudio,
int format, int sampleRate) { int format, int sampleRate) {
super(namespace, name); super(id);
this.rawAudio = rawAudio; this.rawAudio = rawAudio;
this.sampleRate = sampleRate; this.sampleRate = sampleRate;
this.format = format; this.format = format;
createAudioBuffer(); createAudioBuffer();
} }
private void createAudioBuffer() { private void createAudioBuffer() {
this.audioBuffer = alGenBuffers(); this.audioBuffer = alGenBuffers();
alBufferData(audioBuffer, format, rawAudio, sampleRate); alBufferData(audioBuffer, format, rawAudio, sampleRate);
@ -30,7 +30,7 @@ public class SoundType extends Namespaced {
private Speaker createSound(int source, int audio) { private Speaker createSound(int source, int audio) {
if (!alIsBuffer(audio) || !alIsSource(source)) if (!alIsBuffer(audio) || !alIsSource(source))
throw new RuntimeException(); throw new RuntimeException();
alBufferData(audio, format, rawAudio, sampleRate); alBufferData(audio, format, rawAudio, sampleRate);
return new Speaker(audio); return new Speaker(audio);
} }

View File

@ -98,6 +98,10 @@ public class Speaker {
return audioData; return audioData;
} }
public int getSourceData() {
return sourceData;
}
public void setAudioData(int audioData) { public void setAudioData(int audioData) {
this.audioData = audioData; this.audioData = audioData;
alSourcei(this.sourceData, AL_BUFFER, audioData); alSourcei(this.sourceData, AL_BUFFER, audioData);

View File

@ -0,0 +1,30 @@
package ru.windcorp.progressia.test;
import ru.windcorp.progressia.client.audio.AudioFormat;
import ru.windcorp.progressia.client.audio.AudioManager;
import ru.windcorp.progressia.client.audio.Music;
public class ALTest {
static private void initializeAL() {
AudioManager.initAL();
}
static void loadALData() {
AudioManager.loadSound("assets/sounds/sample_stereo.ogg",
"Progressia:SampleStereo",
AudioFormat.STEREO);
AudioManager.loadSound("assets/sounds/block_destroy_clap.ogg",
"Progressia:BlockDestroy",
AudioFormat.MONO);
Music music = new Music("Progressia:SampleStereo");
music.setGain(0.5f);
//music.play(false);
}
public static void execute() {
initializeAL();
Thread shutdownHook = new Thread(AudioManager::closeAL, "AL Shutdown Hook");
Runtime.getRuntime().addShutdownHook(shutdownHook);
loadALData();
}
}

View File

@ -9,6 +9,7 @@ import org.lwjgl.glfw.GLFW;
import glm.vec._3.i.Vec3i; import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.ClientState;
import ru.windcorp.progressia.client.audio.SoundEffect;
import ru.windcorp.progressia.client.comms.controls.*; import ru.windcorp.progressia.client.comms.controls.*;
import ru.windcorp.progressia.client.graphics.input.KeyEvent; import ru.windcorp.progressia.client.graphics.input.KeyEvent;
import ru.windcorp.progressia.client.graphics.input.KeyMatcher; import ru.windcorp.progressia.client.graphics.input.KeyMatcher;
@ -213,6 +214,10 @@ public class TestContent {
private static void onBlockBreakTrigger(ControlData control) { private static void onBlockBreakTrigger(ControlData control) {
((ControlBreakBlockData) control).setBlockInWorld(getSelection().getBlock()); ((ControlBreakBlockData) control).setBlockInWorld(getSelection().getBlock());
SoundEffect sfx = new SoundEffect("Progressia:BlockDestroy");
sfx.setPosition(getSelection().getPoint());
sfx.setPitch((float) (Math.random() + 1 * 0.5));
sfx.play(false);
} }
private static void onBlockBreakReceived(Server server, PacketControl packet, ru.windcorp.progressia.server.comms.Client client) { private static void onBlockBreakReceived(Server server, PacketControl packet, ru.windcorp.progressia.server.comms.Client client) {