diff --git a/assets/Audio/movement/Equip A.wav b/assets/Audio/movement/Equip A.wav new file mode 100644 index 00000000..771db569 Binary files /dev/null and b/assets/Audio/movement/Equip A.wav differ diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 84d8e6ae..1c60fffb 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -180,6 +180,9 @@ "nameThirdPerson" : "Land", "nameFirstPerson" : "Land", "priorityCategory" : "MOVEMENT_MODIFIER" + }, + "audioData" : { + "audioPath" : "Audio/movement/Equip A.wav" } } } diff --git a/src/main/java/electrosphere/audio/AudioBuffer.java b/src/main/java/electrosphere/audio/AudioBuffer.java index 29da3655..b43f13e7 100644 --- a/src/main/java/electrosphere/audio/AudioBuffer.java +++ b/src/main/java/electrosphere/audio/AudioBuffer.java @@ -9,7 +9,16 @@ import java.nio.ShortBuffer; import java.nio.channels.SeekableByteChannel; import java.nio.file.Files; import java.nio.file.Path; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.UnsupportedAudioFileException; + import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL11; + import static org.lwjgl.openal.AL10.*; import org.lwjgl.stb.STBVorbis; @@ -26,9 +35,6 @@ public class AudioBuffer { //the id of the buffer private int bufferId; - //buffer containing vorbis metadata - private ByteBuffer vorbis = null; - //The main audio data private ShortBuffer pcm = null; @@ -43,15 +49,23 @@ public class AudioBuffer { String fileNameSanitized = FileUtils.sanitizeFilePath(fileNameRaw); bufferId = alGenBuffers(); - //create buffer to store vorbis data - try (STBVorbisInfo info = STBVorbisInfo.malloc()) { - //read the vorbis data as well as main audio data - ShortBuffer pcm = readVorbis(fileNameSanitized, 32 * 1024, info); - // Copy to buffer - alBufferData(bufferId, info.channels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, info.sample_rate()); - } catch (Exception e){ - LoggerInterface.loggerAudio.ERROR("Failed to load audio", e); + //read vorbis + if(fileNameSanitized.contains(".ogg")){ + //create buffer to store vorbis data + try(STBVorbisInfo info = STBVorbisInfo.malloc()){ + readVorbis(fileNameSanitized, bufferId, 32 * 1024, info); + } catch (Exception e){ + LoggerInterface.loggerAudio.ERROR("Failed to load audio", e); + } } + + + //read wav + if(fileNameSanitized.contains(".wav")){ + readWav(fileNameSanitized, 32 * 1024, bufferId); + } + + LoggerInterface.loggerAudio.DEBUG("Created audio buffer(" + fileNameRaw + ") with length " + length); } @@ -63,7 +77,9 @@ public class AudioBuffer { * @return The main audio data buffer * @throws Exception Throws an exception if the decoder fails */ - private ShortBuffer readVorbis(String filepath, int bufferSize, STBVorbisInfo info) throws Exception { + private void readVorbis(String filepath, int bufferId, int bufferSize, STBVorbisInfo info) throws Exception { + //buffer containing vorbis metadata + ByteBuffer vorbis = null; try (MemoryStack stack = MemoryStack.stackPush()) { //read the vorbis data from disk @@ -89,7 +105,43 @@ public class AudioBuffer { //close decoder and return STBVorbis.stb_vorbis_close(decoder); - return pcm; + // Copy to buffer + alBufferData(bufferId, info.channels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, info.sample_rate()); + } + } + + /** + * Reads a wav file + * @param filepath The filepath to the wav + * @param bufferSize The buffer size + * @param bufferId The id of the buffer + */ + private void readWav(String filepath, int bufferSize, int bufferId){ + try { + //get raw file objects + AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(FileUtils.getAssetFile(filepath)); + AudioFormat format = fileFormat.getFormat(); + AudioInputStream inputStream = AudioSystem.getAudioInputStream(FileUtils.getAssetFile(filepath)); + + //get data about specific file + int channels = format.getChannels(); + float sampleRate = format.getSampleRate(); + this.length = fileFormat.getFrameLength() * format.getFrameRate(); + + //read data + byte[] dataRaw = inputStream.readAllBytes(); + ByteBuffer buffer = MemoryUtil.memAlloc(dataRaw.length); + buffer.put(dataRaw); + buffer.flip(); + + //buffer to openal + AL11.alBufferData(bufferId, channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, buffer, (int)sampleRate); + } catch (UnsupportedAudioFileException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } diff --git a/src/main/java/electrosphere/audio/AudioEngine.java b/src/main/java/electrosphere/audio/AudioEngine.java index d669673a..b86885f6 100644 --- a/src/main/java/electrosphere/audio/AudioEngine.java +++ b/src/main/java/electrosphere/audio/AudioEngine.java @@ -69,6 +69,7 @@ public class AudioEngine { LoggerInterface.loggerEngine.ERROR("Error initializing audio device", ex); } if(initialized){ + //recursively load all audio files listener = new AudioListener(); } } diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index 177de5d3..af9a8fbd 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -470,6 +470,7 @@ public class Globals { "/Audio/ambienceWind1SeamlessMono.ogg", "/Audio/weapons/swordUnsheath1.ogg", "/Audio/weapons/swoosh-03.ogg", + "/Audio/movement/Equip A.wav", }; LoggerInterface.loggerStartup.INFO("Loading default audio resources"); for(String path : audioToInit){ diff --git a/src/main/java/electrosphere/entity/state/movement/FallTree.java b/src/main/java/electrosphere/entity/state/movement/FallTree.java index b473e4b0..b1ed3c7d 100644 --- a/src/main/java/electrosphere/entity/state/movement/FallTree.java +++ b/src/main/java/electrosphere/entity/state/movement/FallTree.java @@ -1,5 +1,6 @@ package electrosphere.entity.state.movement; +import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; @@ -10,6 +11,7 @@ import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem; import electrosphere.entity.state.AnimationPriorities; import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.movement.jump.ClientJumpTree; +import electrosphere.game.data.common.TreeDataAudio; import electrosphere.game.data.creature.type.movement.FallMovementSystem; import electrosphere.renderer.actor.Actor; @@ -99,6 +101,20 @@ public class FallTree implements BehaviorTree { } FirstPersonTree.conditionallyPlayAnimation(parent, fallMovementSystem.getLandState().getAnimation()); } + //play animation, audio, etc, for state + TreeDataAudio audioData = fallMovementSystem.getLandState().getAudioData(); + if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson()){ + //first person + //play first person audio + if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){ + Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false); + } + } else { + //play third person audio + if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){ + Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false, EntityUtils.getPosition(parent)); + } + } } }