audio module

This commit is contained in:
2014-07-26 14:43:25 +02:00
parent 3c0763a4c8
commit d3f392d689
9 changed files with 314 additions and 338 deletions
@@ -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)