/* * The MIT License (MIT) * * Copyright (c) 2014-2017 Sri Harsha Chilakapati * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.shc.silenceengine.backend.lwjgl; import com.shc.silenceengine.audio.AudioDevice; import com.shc.silenceengine.audio.openal.ALBuffer; import com.shc.silenceengine.backend.lwjgl.soundreaders.OggReader; import com.shc.silenceengine.backend.lwjgl.soundreaders.WaveReader; import com.shc.silenceengine.core.SilenceEngine; import com.shc.silenceengine.core.SilenceException; import com.shc.silenceengine.io.DirectBuffer; import com.shc.silenceengine.utils.TaskManager; import com.shc.silenceengine.utils.functional.UniCallback; import org.lwjgl.openal.AL; import org.lwjgl.openal.AL10; import org.lwjgl.openal.ALC; import org.lwjgl.openal.ALCCapabilities; import java.nio.ByteBuffer; import java.nio.IntBuffer; import static org.lwjgl.openal.ALC10.*; /** * @author Sri Harsha Chilakapati */ class LwjglAudioDevice extends AudioDevice { private long device; private long context; LwjglAudioDevice() { device = alcOpenDevice((ByteBuffer) null); ALCCapabilities deviceCaps = ALC.createCapabilities(device); context = alcCreateContext(device, (IntBuffer) null); alcMakeContextCurrent(context); AL.createCapabilities(deviceCaps); SilenceEngine.eventManager.addDisposeHandler(this::cleanUp); } @Override public int alGenBuffers() { return AL10.alGenBuffers(); } @Override public void alBufferData(int id, int format, DirectBuffer data, int frequency) { AL10.alBufferData(id, format, (ByteBuffer) data.nativeBuffer(), frequency); } @Override public void alDeleteBuffers(int... buffers) { for (int buffer : buffers) AL10.alDeleteBuffers(buffer); } @Override public int alGetError() { return AL10.alGetError(); } @Override public int alGenSources() { return AL10.alGenSources(); } @Override public void alSourcei(int id, int param, int value) { AL10.alSourcei(id, param, value); } @Override public void alSourcef(int id, int param, float value) { AL10.alSourcef(id, param, value); } @Override public void alSource3f(int id, int param, float v1, float v2, float v3) { AL10.alSource3f(id, param, v1, v2, v3); } @Override public void alSourcePlay(int id) { AL10.alSourcePlay(id); } @Override public void alSourcePause(int id) { AL10.alSourcePause(id); } @Override public void alSourceRewind(int id) { AL10.alSourceRewind(id); } @Override public void alSourceStop(int id) { AL10.alSourceStop(id); } @Override public int alGetSourcei(int id, int parameter) { return AL10.alGetSourcei(id, parameter); } @Override public void alDeleteSources(int... sources) { for (int source : sources) AL10.alDeleteSources(source); } @Override public void readToALBuffer(AudioFormat format, DirectBuffer data, UniCallback<ALBuffer> onDecoded, UniCallback<Throwable> onError) { try { if (!isSupported(format)) throw new SilenceException("Error, cannot decode unsupported format"); switch (format) { case OGG: { OggReader reader = new OggReader(data); TaskManager.runOnUpdate(() -> { ALBuffer alBuffer = new ALBuffer(); alBuffer.uploadData(new LwjglDirectBuffer(reader.getData()), reader.getFormat(), reader.getSampleRate()); onDecoded.invoke(alBuffer); }); break; } case WAV: { WaveReader reader = new WaveReader(data); TaskManager.runOnUpdate(() -> { ALBuffer alBuffer = new ALBuffer(); alBuffer.uploadData(new LwjglDirectBuffer(reader.getData()), reader.getFormat(), reader.getSampleRate()); onDecoded.invoke(alBuffer); }); break; } } } catch (Throwable e) { onError.invoke(e); } } @Override public boolean isSupported(AudioFormat format) { switch (format) { case OGG: return true; case MP3: return false; case WAV: return true; case WEBM: return false; } return false; } private void cleanUp() { alcCloseDevice(device); alcDestroyContext(context); } }