audio module
This commit is contained in:
@@ -5,10 +5,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import mightypork.gamecore.resources.audio.DeferredAudio;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.newdawn.slick.openal.Audio;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
@@ -124,20 +121,6 @@ public class SlickAudio extends DeferredAudio {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop)
|
||||
{
|
||||
play(pitch, gain, loop, SoundSystem.getListener());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, double x, double y)
|
||||
{
|
||||
play(pitch, gain, loop, x, y, SoundSystem.getListener().z());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, double x, double y, double z)
|
||||
{
|
||||
@@ -151,15 +134,6 @@ public class SlickAudio extends DeferredAudio {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, Vect pos)
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
play(pitch, gain, loop, pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
@@ -7,9 +7,7 @@ import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.audio.AudioModule;
|
||||
import mightypork.gamecore.resources.audio.AudioReadyEvent;
|
||||
import mightypork.gamecore.resources.audio.DeferredAudio;
|
||||
import mightypork.gamecore.util.BufferHelper;
|
||||
import mightypork.utils.logging.Log;
|
||||
@@ -40,8 +38,6 @@ public class SlickAudioModule extends AudioModule {
|
||||
SoundStore.get().setMaxSources(MAX_SOURCES);
|
||||
SoundStore.get().init();
|
||||
setListenerPos(INITIAL_LISTENER_POS);
|
||||
|
||||
App.bus().send(new AudioReadyEvent());
|
||||
} catch (final Throwable t) {
|
||||
Log.e("Error initializing sound system.", t);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract audio backend module
|
||||
* Abstract audio module.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@@ -61,6 +61,10 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deinitialize the soud system, release resources etc.<br>
|
||||
* Audio resources are already destroyed.
|
||||
*/
|
||||
protected abstract void deinitSoundSystem();
|
||||
|
||||
|
||||
@@ -107,7 +111,8 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Create {@link DeferredAudio} for a resource
|
||||
* Create {@link DeferredAudio} for a resource, request deferred load and
|
||||
* add to the resources list.
|
||||
*
|
||||
* @param res a resource name
|
||||
* @return the resource
|
||||
@@ -115,7 +120,7 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
*/
|
||||
protected DeferredAudio createResource(String res)
|
||||
{
|
||||
final DeferredAudio a = doCreateResource(res);;
|
||||
final DeferredAudio a = doCreateResource(res);
|
||||
App.bus().send(new ResourceLoadRequest(a));
|
||||
resources.add(a);
|
||||
return a;
|
||||
@@ -123,7 +128,7 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Create a backend-specific deferred audio resource instance.
|
||||
* Create a backend-specific deferred audio resource
|
||||
*
|
||||
* @param res resource path
|
||||
* @return Deferred Audio
|
||||
@@ -132,7 +137,7 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Fade out all loops (ie. for screen transitions)
|
||||
* Fade out all loops (= fade out the currently playing loops)
|
||||
*/
|
||||
public void fadeOutAllLoops()
|
||||
{
|
||||
@@ -154,42 +159,42 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Set level of master volume
|
||||
* Set level of master volume (volume multiplier)
|
||||
*
|
||||
* @param d level
|
||||
* @param volume level (0..1)
|
||||
*/
|
||||
public void setMasterVolume(double d)
|
||||
public void setMasterVolume(double volume)
|
||||
{
|
||||
masterVolume.set(d);
|
||||
masterVolume.set(volume);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of effects volume
|
||||
* Set level of effects volume (volume multiplier)
|
||||
*
|
||||
* @param d level
|
||||
* @param volume level (0..1)
|
||||
*/
|
||||
public void setEffectsVolume(double d)
|
||||
public void setEffectsVolume(double volume)
|
||||
{
|
||||
effectsVolume.set(d);
|
||||
effectsVolume.set(volume);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of music volume
|
||||
* Set level of loops volume (volume multiplier)
|
||||
*
|
||||
* @param d level
|
||||
* @param volume level (0..1)
|
||||
*/
|
||||
public void setMusicVolume(double d)
|
||||
public void setLoopsVolume(double volume)
|
||||
{
|
||||
loopsVolume.set(d);
|
||||
loopsVolume.set(volume);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get level of master volume
|
||||
* Get level of master volume (volume multiplier)
|
||||
*
|
||||
* @return level
|
||||
* @return level (0..1)
|
||||
*/
|
||||
public double getMasterVolume()
|
||||
{
|
||||
@@ -198,9 +203,9 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Get level of effects volume
|
||||
* Get level of effects volume (volume multiplier)
|
||||
*
|
||||
* @return level
|
||||
* @return level (0..1)
|
||||
*/
|
||||
public double getEffectsVolume()
|
||||
{
|
||||
@@ -209,11 +214,11 @@ public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Get level of music volume
|
||||
* Get level of loops volume (volume multiplier)
|
||||
*
|
||||
* @return level
|
||||
* @return level (0..1)
|
||||
*/
|
||||
public double getMusicVolume()
|
||||
public double getLoopsVolume()
|
||||
{
|
||||
return loopsVolume.get();
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
import mightypork.utils.eventbus.BusEvent;
|
||||
|
||||
|
||||
public class AudioReadyEvent extends BusEvent<AudioReadyListener> {
|
||||
|
||||
@Override
|
||||
protected void handleBy(AudioReadyListener handler)
|
||||
{
|
||||
handler.onInputReady();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
public interface AudioReadyListener {
|
||||
|
||||
void onInputReady();
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.BaseDeferredResource;
|
||||
import mightypork.utils.annotations.Alias;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Base deferred audio
|
||||
* Abstract deferred audio, to be extended in backend.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@@ -14,11 +16,32 @@ import mightypork.utils.annotations.Alias;
|
||||
public abstract class DeferredAudio extends BaseDeferredResource implements IAudio {
|
||||
|
||||
/**
|
||||
* Create deferred primitive audio player
|
||||
* Create audio
|
||||
*
|
||||
* @param resourceName resource to load when needed
|
||||
* @param resourceName resource to load (when needed)
|
||||
*/
|
||||
public DeferredAudio(String resourceName) {
|
||||
super(resourceName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop)
|
||||
{
|
||||
play(pitch, gain, loop, App.audio().getListenerPos());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, double x, double y)
|
||||
{
|
||||
play(pitch, gain, loop, x, y, App.audio().getListenerPos().z());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, Vect pos)
|
||||
{
|
||||
play(pitch, gain, loop, pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,257 +0,0 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import mightypork.gamecore.backend.lwjgl.SlickAudio;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.ResourceLoadRequest;
|
||||
import mightypork.gamecore.resources.audio.players.EffectPlayer;
|
||||
import mightypork.gamecore.resources.audio.players.LoopPlayer;
|
||||
import mightypork.gamecore.util.BufferHelper;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
import mightypork.utils.interfaces.Updateable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
import mightypork.utils.math.constraints.vect.var.VectVar;
|
||||
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
|
||||
/**
|
||||
* Sound system class (only one instance should be made per application)
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class SoundSystem extends BusNode implements Updateable, Destroyable {
|
||||
|
||||
private static final Vect INITIAL_LISTENER_POS = Vect.ZERO;
|
||||
private static final int MAX_SOURCES = 256;
|
||||
|
||||
private static VectVar listener = Vect.makeVar();
|
||||
private static boolean soundSystemInited = false;
|
||||
|
||||
|
||||
/**
|
||||
* Set listener pos
|
||||
*
|
||||
* @param pos
|
||||
*/
|
||||
public static void setListener(Vect pos)
|
||||
{
|
||||
listener.setTo(pos);
|
||||
final FloatBuffer buf3 = BufferHelper.alloc(3);
|
||||
final FloatBuffer buf6 = BufferHelper.alloc(6);
|
||||
buf3.clear();
|
||||
BufferHelper.fill(buf3, (float) pos.x(), (float) pos.y(), (float) pos.z());
|
||||
AL10.alListener(AL10.AL_POSITION, buf3);
|
||||
buf3.clear();
|
||||
BufferHelper.fill(buf3, 0, 0, 0);
|
||||
AL10.alListener(AL10.AL_VELOCITY, buf3);
|
||||
buf6.clear();
|
||||
BufferHelper.fill(buf6, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
|
||||
AL10.alListener(AL10.AL_ORIENTATION, buf6);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return listener coordinate
|
||||
*/
|
||||
public static Vect getListener()
|
||||
{
|
||||
return listener;
|
||||
}
|
||||
|
||||
// -- instance --
|
||||
|
||||
private final Volume masterVolume = new Volume(1D);
|
||||
private final Volume effectsVolume = new JointVolume(masterVolume);
|
||||
private final Volume loopsVolume = new JointVolume(masterVolume);
|
||||
|
||||
private final List<LoopPlayer> loopPlayers = new ArrayList<>();
|
||||
private final List<DeferredAudio> resources = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* @param busAccess app access
|
||||
*/
|
||||
public SoundSystem() {
|
||||
|
||||
if (!soundSystemInited) {
|
||||
soundSystemInited = true;
|
||||
|
||||
try {
|
||||
SoundStore.get().setMaxSources(MAX_SOURCES);
|
||||
SoundStore.get().init();
|
||||
setListener(INITIAL_LISTENER_POS);
|
||||
|
||||
App.bus().send(new AudioReadyEvent());
|
||||
} catch (final Throwable t) {
|
||||
Log.e("Error initializing sound system.", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
for (final DeferredAudio r : resources) {
|
||||
r.destroy();
|
||||
}
|
||||
|
||||
SoundStore.get().clear();
|
||||
AL.destroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
for (final Updateable lp : loopPlayers) {
|
||||
lp.update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create effect resource
|
||||
*
|
||||
* @param resource resource path
|
||||
* @param pitch default pitch (1 = unchanged)
|
||||
* @param gain default gain (0-1)
|
||||
* @return player
|
||||
*/
|
||||
public EffectPlayer createEffect(String resource, double pitch, double gain)
|
||||
{
|
||||
return new EffectPlayer(createResource(resource), pitch, gain, effectsVolume);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register loop resource (music / effect loop)
|
||||
*
|
||||
* @param resource resource path
|
||||
* @param pitch default pitch (1 = unchanged)
|
||||
* @param gain default gain (0-1)
|
||||
* @param fadeIn default time for fadeIn
|
||||
* @param fadeOut default time for fadeOut
|
||||
* @return player
|
||||
*/
|
||||
public LoopPlayer createLoop(String resource, double pitch, double gain, double fadeIn, double fadeOut)
|
||||
{
|
||||
final LoopPlayer p = new LoopPlayer(createResource(resource), pitch, gain, loopsVolume);
|
||||
p.setFadeTimes(fadeIn, fadeOut);
|
||||
loopPlayers.add(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create {@link DeferredAudio} for a resource
|
||||
*
|
||||
* @param res a resource name
|
||||
* @return the resource
|
||||
* @throws IllegalArgumentException if resource is already registered
|
||||
*/
|
||||
private DeferredAudio createResource(String res)
|
||||
{
|
||||
final DeferredAudio a = new SlickAudio(res);
|
||||
App.bus().send(new ResourceLoadRequest(a));
|
||||
resources.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fade out all loops (ie. for screen transitions)
|
||||
*/
|
||||
public void fadeOutAllLoops()
|
||||
{
|
||||
for (final LoopPlayer p : loopPlayers) {
|
||||
p.fadeOut();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pause all loops (leave volume unchanged)
|
||||
*/
|
||||
public void pauseAllLoops()
|
||||
{
|
||||
for (final LoopPlayer p : loopPlayers) {
|
||||
p.pause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of master volume
|
||||
*
|
||||
* @param d level
|
||||
*/
|
||||
public void setMasterVolume(double d)
|
||||
{
|
||||
masterVolume.set(d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of effects volume
|
||||
*
|
||||
* @param d level
|
||||
*/
|
||||
public void setEffectsVolume(double d)
|
||||
{
|
||||
effectsVolume.set(d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of music volume
|
||||
*
|
||||
* @param d level
|
||||
*/
|
||||
public void setMusicVolume(double d)
|
||||
{
|
||||
loopsVolume.set(d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get level of master volume
|
||||
*
|
||||
* @return level
|
||||
*/
|
||||
public double getMasterVolume()
|
||||
{
|
||||
return masterVolume.get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get level of effects volume
|
||||
*
|
||||
* @return level
|
||||
*/
|
||||
public double getEffectsVolume()
|
||||
{
|
||||
return effectsVolume.get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get level of music volume
|
||||
*
|
||||
* @return level
|
||||
*/
|
||||
public double getMusicVolume()
|
||||
{
|
||||
return loopsVolume.get();
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,6 @@ import mightypork.utils.interfaces.Pauseable;
|
||||
import mightypork.utils.interfaces.Updateable;
|
||||
import mightypork.utils.math.animation.NumAnimated;
|
||||
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
|
||||
/**
|
||||
* Audio loop player (with fading, good for music)
|
||||
|
||||
Reference in New Issue
Block a user