* Update to LWJGL 2.8.1
* Audio system to use new NativeObject class for managing audio buffers and filters * Formatting for AndroidAudioRenderer * Changed AndroidAudioData to match new NativeObject class * AudioNode now serializes the audio key as "audio_key" instead "key" git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8423 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
107380afc1
commit
55bfc5f0cf
@ -3,7 +3,7 @@ The following people have helped to make this project what it is today:
|
|||||||
- Brian Matzon <brian@matzon.dk>
|
- Brian Matzon <brian@matzon.dk>
|
||||||
- Elias Naur <elias.naur@gmail.com>
|
- Elias Naur <elias.naur@gmail.com>
|
||||||
- Ioannis Tsakpinis <spasi@users.sourceforge.net>
|
- Ioannis Tsakpinis <spasi@users.sourceforge.net>
|
||||||
- Niels Jørgensen <nj@niemo.com>
|
- Niels J<EFBFBD>rgensen <nj@niemo.com>
|
||||||
- Tristan Campbell <tristan@happypedestrian.com>
|
- Tristan Campbell <tristan@happypedestrian.com>
|
||||||
- Gregory Pierce <gregorypierce@yahoo.com>
|
- Gregory Pierce <gregorypierce@yahoo.com>
|
||||||
- Luke Holden <lholden@users.sf.net>
|
- Luke Holden <lholden@users.sf.net>
|
||||||
@ -12,12 +12,14 @@ The following people have helped to make this project what it is today:
|
|||||||
- Jos Hirth <jhirth@kaioa.com>
|
- Jos Hirth <jhirth@kaioa.com>
|
||||||
- Kevin Glass <kevin@cokeandcode.com>
|
- Kevin Glass <kevin@cokeandcode.com>
|
||||||
- Atsuya Takagi
|
- Atsuya Takagi
|
||||||
- kappaOne
|
- kappaOne <one.kappa@gmail.com>
|
||||||
- Simon Felix
|
- Simon Felix
|
||||||
- Ryan McNally
|
- Ryan McNally
|
||||||
- Ciardhubh <ciardhubh[at]ciardhubh.de>
|
- Ciardhubh <ciardhubh[at]ciardhubh.de>
|
||||||
- Jens von Pilgrim
|
- Jens von Pilgrim
|
||||||
- Ruben Garat
|
- Ruben Garat
|
||||||
|
- Pelle Johnsen <pelle.johnsen@gmail.com>
|
||||||
|
- Jae Kwon
|
||||||
|
|
||||||
additional credits goes to:
|
additional credits goes to:
|
||||||
- Joseph I. Valenzuela [OpenAL stuff]
|
- Joseph I. Valenzuela [OpenAL stuff]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
This is the official readme file for lwjgl!
|
This is the official readme file for lwjgl.
|
||||||
|
|
||||||
Unless otherwise stated, all files distributed or in SVN are covered by
|
Unless otherwise stated, all files distributed or in SVN are covered by
|
||||||
the license as stated in the LICENSE file. If you have not received this
|
the license as stated in the LICENSE file. If you have not received this
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -3,12 +3,20 @@ package com.jme3.audio.android;
|
|||||||
import com.jme3.asset.AssetKey;
|
import com.jme3.asset.AssetKey;
|
||||||
import com.jme3.audio.AudioData;
|
import com.jme3.audio.AudioData;
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
|
import com.jme3.util.NativeObject;
|
||||||
|
|
||||||
|
public class AndroidAudioData extends AudioData {
|
||||||
|
|
||||||
public class AndroidAudioData extends AudioData
|
|
||||||
{
|
|
||||||
protected AssetKey assetKey;
|
protected AssetKey assetKey;
|
||||||
protected int soundId = 0;
|
|
||||||
protected float currentVolume = 0f;
|
protected float currentVolume = 0f;
|
||||||
|
|
||||||
|
public AndroidAudioData(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AndroidAudioData(int id){
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
public AssetKey getAssetKey() {
|
public AssetKey getAssetKey() {
|
||||||
return assetKey;
|
return assetKey;
|
||||||
@ -18,35 +26,25 @@ public class AndroidAudioData extends AudioData
|
|||||||
this.assetKey = assetKey;
|
this.assetKey = assetKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSoundId() {
|
|
||||||
return soundId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSoundId(int soundId) {
|
|
||||||
this.soundId = soundId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataType getDataType() {
|
public DataType getDataType() {
|
||||||
// TODO Auto-generated method stub
|
return DataType.Buffer;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getDuration() {
|
public float getDuration() {
|
||||||
// TODO Auto-generated method stub
|
return 0; // TODO: ???
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetObject() {
|
public void resetObject() {
|
||||||
// TODO Auto-generated method stub
|
this.id = -1;
|
||||||
|
setUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(AudioRenderer r) {
|
public void deleteObject(Object rendererObject) {
|
||||||
r.deleteAudioData(this);
|
((AudioRenderer)rendererObject).deleteAudioData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCurrentVolume() {
|
public float getCurrentVolume() {
|
||||||
@ -56,7 +54,9 @@ public class AndroidAudioData extends AudioData
|
|||||||
public void setCurrentVolume(float currentVolume) {
|
public void setCurrentVolume(float currentVolume) {
|
||||||
this.currentVolume = currentVolume;
|
this.currentVolume = currentVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeObject createDestructableClone() {
|
||||||
|
return new AndroidAudioData(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,165 +64,161 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the android implementation for {@link AudioRenderer}
|
* This class is the android implementation for {@link AudioRenderer}
|
||||||
* @author larynx
|
* @author larynx
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadCompleteListener, MediaPlayer.OnCompletionListener
|
public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadCompleteListener, MediaPlayer.OnCompletionListener {
|
||||||
{
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AndroidAudioRenderer.class.getName());
|
private static final Logger logger = Logger.getLogger(AndroidAudioRenderer.class.getName());
|
||||||
private final static int MAX_NUM_CHANNELS = 16;
|
private final static int MAX_NUM_CHANNELS = 16;
|
||||||
|
|
||||||
private SoundPool soundPool = null;
|
private SoundPool soundPool = null;
|
||||||
private HashMap<AudioNode, MediaPlayer> musicPlaying = new HashMap<AudioNode, MediaPlayer>();
|
private HashMap<AudioNode, MediaPlayer> musicPlaying = new HashMap<AudioNode, MediaPlayer>();
|
||||||
|
|
||||||
private final Vector3f listenerPosition = new Vector3f();
|
private final Vector3f listenerPosition = new Vector3f();
|
||||||
// For temp use
|
// For temp use
|
||||||
private final Vector3f distanceVector = new Vector3f();
|
private final Vector3f distanceVector = new Vector3f();
|
||||||
|
|
||||||
private final AudioManager manager;
|
private final AudioManager manager;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final AssetManager am;
|
private final AssetManager am;
|
||||||
|
|
||||||
private HashMap<Integer, AudioNode> mapLoadingAudioNodes = new HashMap<Integer, AudioNode>();
|
private HashMap<Integer, AudioNode> mapLoadingAudioNodes = new HashMap<Integer, AudioNode>();
|
||||||
|
|
||||||
private final AtomicBoolean lastLoadCompleted = new AtomicBoolean();
|
private final AtomicBoolean lastLoadCompleted = new AtomicBoolean();
|
||||||
|
|
||||||
|
|
||||||
private Listener listener;
|
private Listener listener;
|
||||||
private boolean audioDisabled = false;
|
private boolean audioDisabled = false;
|
||||||
|
|
||||||
|
public AndroidAudioRenderer(Activity context) {
|
||||||
|
|
||||||
public AndroidAudioRenderer(Activity context)
|
|
||||||
{
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
manager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
|
manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||||
am = context.getAssets();
|
am = context.getAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize()
|
public void initialize() {
|
||||||
{
|
soundPool = new SoundPool(MAX_NUM_CHANNELS, AudioManager.STREAM_MUSIC, 0);
|
||||||
soundPool = new SoundPool(MAX_NUM_CHANNELS, AudioManager.STREAM_MUSIC, 0);
|
|
||||||
soundPool.setOnLoadCompleteListener(this);
|
soundPool.setOnLoadCompleteListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateSourceParam(AudioNode src, AudioParam param)
|
public void updateSourceParam(AudioNode src, AudioParam param) {
|
||||||
{
|
|
||||||
//logger.log(Level.INFO, "updateSourceParam " + param);
|
//logger.log(Level.INFO, "updateSourceParam " + param);
|
||||||
|
|
||||||
if (audioDisabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (src.getChannel() < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
assert src.getChannel() >= 0;
|
|
||||||
|
|
||||||
|
if (audioDisabled) {
|
||||||
switch (param){
|
|
||||||
case Position:
|
|
||||||
if (!src.isPositional())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vector3f pos = src.getWorldTranslation();
|
|
||||||
break;
|
|
||||||
case Velocity:
|
|
||||||
if (!src.isPositional())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vector3f vel = src.getVelocity();
|
|
||||||
break;
|
|
||||||
case MaxDistance:
|
|
||||||
if (!src.isPositional())
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case RefDistance:
|
|
||||||
if (!src.isPositional())
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case ReverbFilter:
|
|
||||||
if (!src.isPositional() || !src.isReverbEnabled())
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case ReverbEnabled:
|
|
||||||
if (!src.isPositional())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (src.isReverbEnabled()){
|
|
||||||
updateSourceParam(src, AudioParam.ReverbFilter);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IsPositional:
|
|
||||||
break;
|
|
||||||
case Direction:
|
|
||||||
if (!src.isDirectional())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vector3f dir = src.getDirection();
|
|
||||||
break;
|
|
||||||
case InnerAngle:
|
|
||||||
if (!src.isDirectional())
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case OuterAngle:
|
|
||||||
if (!src.isDirectional())
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case IsDirectional:
|
|
||||||
if (src.isDirectional()){
|
|
||||||
updateSourceParam(src, AudioParam.Direction);
|
|
||||||
updateSourceParam(src, AudioParam.InnerAngle);
|
|
||||||
updateSourceParam(src, AudioParam.OuterAngle);
|
|
||||||
}else{
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DryFilter:
|
|
||||||
if (src.getDryFilter() != null){
|
|
||||||
Filter f = src.getDryFilter();
|
|
||||||
if (f.isUpdateNeeded()){
|
|
||||||
//updateFilter(f);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Looping:
|
|
||||||
if (src.isLooping()){
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Volume:
|
|
||||||
|
|
||||||
soundPool.setVolume(src.getChannel(), src.getVolume(), src.getVolume());
|
|
||||||
|
|
||||||
break;
|
|
||||||
case Pitch:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateListenerParam(Listener listener, ListenerParam param)
|
|
||||||
{
|
|
||||||
//logger.log(Level.INFO, "updateListenerParam " + param);
|
|
||||||
if (audioDisabled)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
switch (param){
|
|
||||||
|
if (src.getChannel() < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert src.getChannel() >= 0;
|
||||||
|
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case Position:
|
||||||
|
if (!src.isPositional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3f pos = src.getWorldTranslation();
|
||||||
|
break;
|
||||||
|
case Velocity:
|
||||||
|
if (!src.isPositional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3f vel = src.getVelocity();
|
||||||
|
break;
|
||||||
|
case MaxDistance:
|
||||||
|
if (!src.isPositional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RefDistance:
|
||||||
|
if (!src.isPositional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ReverbFilter:
|
||||||
|
if (!src.isPositional() || !src.isReverbEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ReverbEnabled:
|
||||||
|
if (!src.isPositional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src.isReverbEnabled()) {
|
||||||
|
updateSourceParam(src, AudioParam.ReverbFilter);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IsPositional:
|
||||||
|
break;
|
||||||
|
case Direction:
|
||||||
|
if (!src.isDirectional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3f dir = src.getDirection();
|
||||||
|
break;
|
||||||
|
case InnerAngle:
|
||||||
|
if (!src.isDirectional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OuterAngle:
|
||||||
|
if (!src.isDirectional()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IsDirectional:
|
||||||
|
if (src.isDirectional()) {
|
||||||
|
updateSourceParam(src, AudioParam.Direction);
|
||||||
|
updateSourceParam(src, AudioParam.InnerAngle);
|
||||||
|
updateSourceParam(src, AudioParam.OuterAngle);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DryFilter:
|
||||||
|
if (src.getDryFilter() != null) {
|
||||||
|
Filter f = src.getDryFilter();
|
||||||
|
if (f.isUpdateNeeded()) {
|
||||||
|
//updateFilter(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Looping:
|
||||||
|
if (src.isLooping()) {
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Volume:
|
||||||
|
|
||||||
|
soundPool.setVolume(src.getChannel(), src.getVolume(), src.getVolume());
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Pitch:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateListenerParam(Listener listener, ListenerParam param) {
|
||||||
|
//logger.log(Level.INFO, "updateListenerParam " + param);
|
||||||
|
if (audioDisabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
case Position:
|
case Position:
|
||||||
listenerPosition.set(listener.getLocation());
|
listenerPosition.set(listener.getLocation());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Rotation:
|
case Rotation:
|
||||||
Vector3f dir = listener.getDirection();
|
Vector3f dir = listener.getDirection();
|
||||||
Vector3f up = listener.getUp();
|
Vector3f up = listener.getUp();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Velocity:
|
case Velocity:
|
||||||
@ -237,436 +233,358 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float tpf)
|
public void update(float tpf) {
|
||||||
{
|
|
||||||
float distance;
|
float distance;
|
||||||
float volume;
|
float volume;
|
||||||
|
|
||||||
// Loop over all mediaplayers
|
// Loop over all mediaplayers
|
||||||
for (AudioNode src : musicPlaying.keySet())
|
for (AudioNode src : musicPlaying.keySet()) {
|
||||||
{
|
|
||||||
|
|
||||||
MediaPlayer mp = musicPlaying.get(src);
|
MediaPlayer mp = musicPlaying.get(src);
|
||||||
{
|
{
|
||||||
// Calc the distance to the listener
|
// Calc the distance to the listener
|
||||||
distanceVector.set(listenerPosition);
|
distanceVector.set(listenerPosition);
|
||||||
distanceVector.subtractLocal(src.getLocalTranslation());
|
distanceVector.subtractLocal(src.getLocalTranslation());
|
||||||
distance = FastMath.abs(distanceVector.length());
|
distance = FastMath.abs(distanceVector.length());
|
||||||
|
|
||||||
if (distance < src.getRefDistance())
|
if (distance < src.getRefDistance()) {
|
||||||
distance = src.getRefDistance();
|
distance = src.getRefDistance();
|
||||||
if (distance > src.getMaxDistance())
|
}
|
||||||
distance = src.getMaxDistance();
|
if (distance > src.getMaxDistance()) {
|
||||||
|
distance = src.getMaxDistance();
|
||||||
|
}
|
||||||
volume = src.getRefDistance() / distance;
|
volume = src.getRefDistance() / distance;
|
||||||
|
|
||||||
AndroidAudioData audioData = (AndroidAudioData)src.getAudioData();
|
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
|
||||||
|
|
||||||
if (FastMath.abs(audioData.getCurrentVolume() - volume) > FastMath.FLT_EPSILON)
|
if (FastMath.abs(audioData.getCurrentVolume() - volume) > FastMath.FLT_EPSILON) {
|
||||||
{
|
|
||||||
// Left / Right channel get the same volume by now, only positional
|
// Left / Right channel get the same volume by now, only positional
|
||||||
mp.setVolume(volume, volume);
|
mp.setVolume(volume, volume);
|
||||||
|
|
||||||
audioData.setCurrentVolume(volume);
|
audioData.setCurrentVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setListener(Listener listener) {
|
||||||
public void setListener(Listener listener)
|
if (audioDisabled) {
|
||||||
{
|
return;
|
||||||
if (audioDisabled)
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
if (this.listener != null){
|
if (this.listener != null) {
|
||||||
// previous listener no longer associated with current
|
// previous listener no longer associated with current
|
||||||
// renderer
|
// renderer
|
||||||
this.listener.setRenderer(null);
|
this.listener.setRenderer(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
this.listener.setRenderer(this);
|
this.listener.setRenderer(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadComplete(SoundPool soundPool, int sampleId, int status)
|
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
|
||||||
{
|
|
||||||
AudioNode src = mapLoadingAudioNodes.get(sampleId);
|
AudioNode src = mapLoadingAudioNodes.get(sampleId);
|
||||||
if (src.getAudioData() instanceof AndroidAudioData)
|
if (src.getAudioData() instanceof AndroidAudioData) {
|
||||||
{
|
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
|
||||||
AndroidAudioData audioData = (AndroidAudioData)src.getAudioData();
|
|
||||||
|
if (status == 0) // load was successfull
|
||||||
if (status == 0) // load was successfull
|
|
||||||
{
|
{
|
||||||
int channelIndex;
|
int channelIndex;
|
||||||
channelIndex = soundPool.play(audioData.getSoundId(), 1f, 1f, 1, -1, 1f);
|
channelIndex = soundPool.play(audioData.getId(), 1f, 1f, 1, -1, 1f);
|
||||||
src.setChannel(channelIndex);
|
src.setChannel(channelIndex);
|
||||||
// Playing started ?
|
// Playing started ?
|
||||||
if (src.getChannel() > 0)
|
if (src.getChannel() > 0) {
|
||||||
{
|
|
||||||
src.setStatus(Status.Playing);
|
src.setStatus(Status.Playing);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
src.setChannel(-1);
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
src.setChannel(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("AudioData is not of type AndroidAudioData for AudioNode " + src.toString());
|
throw new IllegalArgumentException("AudioData is not of type AndroidAudioData for AudioNode " + src.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanup()
|
public void cleanup() {
|
||||||
{
|
|
||||||
// Cleanup sound pool
|
// Cleanup sound pool
|
||||||
if (soundPool != null)
|
if (soundPool != null) {
|
||||||
{
|
for (AudioNode src : mapLoadingAudioNodes.values()) {
|
||||||
for (AudioNode src: mapLoadingAudioNodes.values())
|
if ((src.getStatus() == Status.Playing) && (src.getChannel() > 0)) {
|
||||||
{
|
|
||||||
if ((src.getStatus() == Status.Playing) && (src.getChannel() > 0))
|
|
||||||
{
|
|
||||||
soundPool.stop(src.getChannel());
|
soundPool.stop(src.getChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src.getAudioData() instanceof AndroidAudioData)
|
if (src.getAudioData() instanceof AndroidAudioData) {
|
||||||
{
|
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
|
||||||
AndroidAudioData audioData = (AndroidAudioData)src.getAudioData();
|
if (audioData.getId() > 0) {
|
||||||
if (audioData.getSoundId() > 0)
|
soundPool.unload(audioData.getId());
|
||||||
{
|
}
|
||||||
soundPool.unload(audioData.getSoundId());
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
soundPool.release();
|
soundPool.release();
|
||||||
soundPool = null;
|
soundPool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup media player
|
// Cleanup media player
|
||||||
for (AudioNode src : musicPlaying.keySet())
|
for (AudioNode src : musicPlaying.keySet()) {
|
||||||
{
|
|
||||||
MediaPlayer mp = musicPlaying.get(src);
|
MediaPlayer mp = musicPlaying.get(src);
|
||||||
{
|
{
|
||||||
mp.stop();
|
mp.stop();
|
||||||
mp.release();
|
mp.release();
|
||||||
src.setStatus(Status.Stopped);
|
src.setStatus(Status.Stopped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
musicPlaying.clear();
|
musicPlaying.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCompletion(MediaPlayer mp)
|
public void onCompletion(MediaPlayer mp) {
|
||||||
{
|
for (AudioNode src : musicPlaying.keySet()) {
|
||||||
for (AudioNode src : musicPlaying.keySet())
|
if (musicPlaying.get(src) == mp) {
|
||||||
{
|
mp.seekTo(0);
|
||||||
if (musicPlaying.get(src) == mp)
|
|
||||||
{
|
|
||||||
mp.seekTo(0);
|
|
||||||
mp.stop();
|
mp.stop();
|
||||||
src.setStatus(Status.Stopped);
|
src.setStatus(Status.Stopped);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playSourceInstance(AudioNode src)
|
|
||||||
{
|
|
||||||
if (audioDisabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AndroidAudioData audioData;
|
public void playSourceInstance(AudioNode src) {
|
||||||
int soundId = 0;
|
if (audioDisabled) {
|
||||||
|
return;
|
||||||
if (src.getAudioData() instanceof AndroidAudioData)
|
}
|
||||||
{
|
|
||||||
audioData = (AndroidAudioData)src.getAudioData();
|
|
||||||
|
|
||||||
if (audioData.getAssetKey() instanceof AudioKey)
|
|
||||||
{
|
|
||||||
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
|
||||||
|
|
||||||
// streaming audionodes get played using android mediaplayer, non streaming uses SoundPool
|
|
||||||
if (assetKey.isStream())
|
|
||||||
{
|
|
||||||
MediaPlayer mp;
|
|
||||||
if (musicPlaying.containsKey(src))
|
|
||||||
{
|
|
||||||
mp = musicPlaying.get(src);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mp = new MediaPlayer();
|
|
||||||
mp.setOnCompletionListener(this);
|
|
||||||
//mp = MediaPlayer.create(context, new Ur );
|
|
||||||
musicPlaying.put(src, mp);
|
|
||||||
}
|
|
||||||
if (!mp.isPlaying())
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
AssetFileDescriptor afd = am.openFd(assetKey.getName());
|
|
||||||
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
|
|
||||||
|
|
||||||
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
AndroidAudioData audioData;
|
||||||
mp.prepare();
|
int soundId = 0;
|
||||||
mp.setLooping(src.isLooping());
|
|
||||||
mp.start();
|
if (src.getAudioData() instanceof AndroidAudioData) {
|
||||||
src.setChannel(1);
|
audioData = (AndroidAudioData) src.getAudioData();
|
||||||
src.setStatus(Status.Playing);
|
|
||||||
} catch (IllegalArgumentException e)
|
if (audioData.getAssetKey() instanceof AudioKey) {
|
||||||
{
|
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
||||||
logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
|
|
||||||
} catch (IllegalStateException e) {
|
// streaming audionodes get played using android mediaplayer, non streaming uses SoundPool
|
||||||
// TODO Auto-generated catch block
|
if (assetKey.isStream()) {
|
||||||
logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
|
MediaPlayer mp;
|
||||||
} catch (IOException e) {
|
if (musicPlaying.containsKey(src)) {
|
||||||
// TODO Auto-generated catch block
|
mp = musicPlaying.get(src);
|
||||||
logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
|
} else {
|
||||||
}
|
mp = new MediaPlayer();
|
||||||
|
mp.setOnCompletionListener(this);
|
||||||
}
|
//mp = MediaPlayer.create(context, new Ur );
|
||||||
|
musicPlaying.put(src, mp);
|
||||||
}
|
}
|
||||||
else
|
if (!mp.isPlaying()) {
|
||||||
{
|
try {
|
||||||
// Low latency Sound effect using SoundPool
|
AssetFileDescriptor afd = am.openFd(assetKey.getName());
|
||||||
if (audioData.isUpdateNeeded() || (audioData.getSoundId() <= 0))
|
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
|
||||||
{
|
|
||||||
if (audioData.getSoundId() > 0)
|
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||||
{
|
mp.prepare();
|
||||||
if (src.getChannel() > 0)
|
mp.setLooping(src.isLooping());
|
||||||
{
|
mp.start();
|
||||||
soundPool.stop(src.getChannel());
|
src.setChannel(1);
|
||||||
src.setChannel(-1);
|
|
||||||
}
|
|
||||||
soundPool.unload(audioData.getSoundId());
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
soundId = soundPool.load(am.openFd(assetKey.getName()), 1);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
logger.log(Level.SEVERE, "Failed to load sound " + assetKey.getName(), e);
|
|
||||||
soundId = -1;
|
|
||||||
}
|
|
||||||
audioData.setSoundId(soundId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sound failed to load ?
|
|
||||||
if (audioData.getSoundId() <= 0)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Failed to load: " + assetKey.getName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int channelIndex;
|
|
||||||
channelIndex = soundPool.play(audioData.getSoundId(), 1f, 1f, 1, -1, 1f);
|
|
||||||
if (channelIndex == 0)
|
|
||||||
{
|
|
||||||
// Loading is not finished
|
|
||||||
// Store the soundId and the AudioNode for async loading and later play start
|
|
||||||
mapLoadingAudioNodes.put(audioData.getSoundId(), src);
|
|
||||||
}
|
|
||||||
src.setChannel(channelIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Playing started ?
|
|
||||||
if (src.getChannel() > 0)
|
|
||||||
{
|
|
||||||
src.setStatus(Status.Playing);
|
src.setStatus(Status.Playing);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("AudioData is not of type AndroidAudioData for AudioNode " + src.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
}
|
// Low latency Sound effect using SoundPool
|
||||||
|
if (audioData.isUpdateNeeded() || (audioData.getId() <= 0)) {
|
||||||
|
if (audioData.getId() > 0) {
|
||||||
public void playSource(AudioNode src)
|
if (src.getChannel() > 0) {
|
||||||
{
|
|
||||||
if (audioDisabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//assert src.getStatus() == Status.Stopped || src.getChannel() == -1;
|
|
||||||
|
|
||||||
if (src.getStatus() == Status.Playing)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (src.getStatus() == Status.Stopped)
|
|
||||||
{
|
|
||||||
playSourceInstance(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void pauseSource(AudioNode src)
|
|
||||||
{
|
|
||||||
if (audioDisabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (src.getStatus() == Status.Playing)
|
|
||||||
{
|
|
||||||
if (src.getAudioData() instanceof AndroidAudioData)
|
|
||||||
{
|
|
||||||
AndroidAudioData audioData = (AndroidAudioData)src.getAudioData();
|
|
||||||
if (audioData.getAssetKey() instanceof AudioKey)
|
|
||||||
{
|
|
||||||
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
|
||||||
|
|
||||||
if (assetKey.isStream())
|
|
||||||
{
|
|
||||||
MediaPlayer mp;
|
|
||||||
if (musicPlaying.containsKey(src))
|
|
||||||
{
|
|
||||||
mp = musicPlaying.get(src);
|
|
||||||
mp.pause();
|
|
||||||
src.setStatus(Status.Paused);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert src.getChannel() != -1;
|
|
||||||
|
|
||||||
if (src.getChannel() > 0)
|
|
||||||
{
|
|
||||||
soundPool.pause(src.getChannel());
|
|
||||||
src.setStatus(Status.Paused);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void stopSource(AudioNode src)
|
|
||||||
{
|
|
||||||
if (audioDisabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
if (src.getStatus() != Status.Stopped)
|
|
||||||
{
|
|
||||||
if (src.getAudioData() instanceof AndroidAudioData)
|
|
||||||
{
|
|
||||||
AndroidAudioData audioData = (AndroidAudioData)src.getAudioData();
|
|
||||||
if (audioData.getAssetKey() instanceof AudioKey)
|
|
||||||
{
|
|
||||||
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
|
||||||
if (assetKey.isStream())
|
|
||||||
{
|
|
||||||
MediaPlayer mp;
|
|
||||||
if (musicPlaying.containsKey(src))
|
|
||||||
{
|
|
||||||
mp = musicPlaying.get(src);
|
|
||||||
mp.stop();
|
|
||||||
src.setStatus(Status.Stopped);
|
|
||||||
src.setChannel(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int chan = src.getChannel();
|
|
||||||
assert chan != -1; // if it's not stopped, must have id
|
|
||||||
|
|
||||||
if (src.getChannel() > 0)
|
|
||||||
{
|
|
||||||
soundPool.stop(src.getChannel());
|
soundPool.stop(src.getChannel());
|
||||||
src.setChannel(-1);
|
src.setChannel(-1);
|
||||||
}
|
}
|
||||||
|
soundPool.unload(audioData.getId());
|
||||||
src.setStatus(Status.Stopped);
|
}
|
||||||
|
|
||||||
if (audioData.getSoundId() > 0)
|
try {
|
||||||
{
|
soundId = soundPool.load(am.openFd(assetKey.getName()), 1);
|
||||||
soundPool.unload(audioData.getSoundId());
|
} catch (IOException e) {
|
||||||
}
|
logger.log(Level.SEVERE, "Failed to load sound " + assetKey.getName(), e);
|
||||||
audioData.setSoundId(-1);
|
soundId = -1;
|
||||||
|
}
|
||||||
|
audioData.setId(soundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sound failed to load ?
|
||||||
|
if (audioData.getId() <= 0) {
|
||||||
|
throw new IllegalArgumentException("Failed to load: " + assetKey.getName());
|
||||||
|
} else {
|
||||||
|
int channelIndex;
|
||||||
|
channelIndex = soundPool.play(audioData.getId(), 1f, 1f, 1, -1, 1f);
|
||||||
|
if (channelIndex == 0) {
|
||||||
|
// Loading is not finished
|
||||||
|
// Store the soundId and the AudioNode for async loading and later play start
|
||||||
|
mapLoadingAudioNodes.put(audioData.getId(), src);
|
||||||
|
}
|
||||||
|
src.setChannel(channelIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Playing started ?
|
||||||
|
if (src.getChannel() > 0) {
|
||||||
|
src.setStatus(Status.Playing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("AudioData is not of type AndroidAudioData for AudioNode " + src.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playSource(AudioNode src) {
|
||||||
|
if (audioDisabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//assert src.getStatus() == Status.Stopped || src.getChannel() == -1;
|
||||||
|
|
||||||
|
if (src.getStatus() == Status.Playing) {
|
||||||
|
return;
|
||||||
|
} else if (src.getStatus() == Status.Stopped) {
|
||||||
|
playSourceInstance(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseSource(AudioNode src) {
|
||||||
|
if (audioDisabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src.getStatus() == Status.Playing) {
|
||||||
|
if (src.getAudioData() instanceof AndroidAudioData) {
|
||||||
|
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
|
||||||
|
if (audioData.getAssetKey() instanceof AudioKey) {
|
||||||
|
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
||||||
|
|
||||||
|
if (assetKey.isStream()) {
|
||||||
|
MediaPlayer mp;
|
||||||
|
if (musicPlaying.containsKey(src)) {
|
||||||
|
mp = musicPlaying.get(src);
|
||||||
|
mp.pause();
|
||||||
|
src.setStatus(Status.Paused);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert src.getChannel() != -1;
|
||||||
|
|
||||||
|
if (src.getChannel() > 0) {
|
||||||
|
soundPool.pause(src.getChannel());
|
||||||
|
src.setStatus(Status.Paused);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stopSource(AudioNode src) {
|
||||||
|
if (audioDisabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateAudioData(AndroidAudioData data)
|
|
||||||
{
|
if (src.getStatus() != Status.Stopped) {
|
||||||
|
if (src.getAudioData() instanceof AndroidAudioData) {
|
||||||
|
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
|
||||||
|
if (audioData.getAssetKey() instanceof AudioKey) {
|
||||||
|
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
||||||
|
if (assetKey.isStream()) {
|
||||||
|
MediaPlayer mp;
|
||||||
|
if (musicPlaying.containsKey(src)) {
|
||||||
|
mp = musicPlaying.get(src);
|
||||||
|
mp.stop();
|
||||||
|
src.setStatus(Status.Stopped);
|
||||||
|
src.setChannel(-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int chan = src.getChannel();
|
||||||
|
assert chan != -1; // if it's not stopped, must have id
|
||||||
|
|
||||||
|
if (src.getChannel() > 0) {
|
||||||
|
soundPool.stop(src.getChannel());
|
||||||
|
src.setChannel(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
src.setStatus(Status.Stopped);
|
||||||
|
|
||||||
|
if (audioData.getId() > 0) {
|
||||||
|
soundPool.unload(audioData.getId());
|
||||||
|
}
|
||||||
|
audioData.setId(-1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateAudioData(AndroidAudioData data) {
|
||||||
throw new UnsupportedOperationException("updateAudioData");
|
throw new UnsupportedOperationException("updateAudioData");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteFilter(Filter filter) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAudioData(AudioData ad)
|
public void deleteAudioData(AudioData ad) {
|
||||||
{
|
if (ad instanceof AndroidAudioData) {
|
||||||
if (ad instanceof AndroidAudioData)
|
AndroidAudioData audioData = (AndroidAudioData) ad;
|
||||||
{
|
if (audioData.getAssetKey() instanceof AudioKey) {
|
||||||
AndroidAudioData audioData = (AndroidAudioData)ad;
|
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
||||||
if (audioData.getAssetKey() instanceof AudioKey)
|
if (assetKey.isStream()) {
|
||||||
{
|
for (AudioNode src : musicPlaying.keySet()) {
|
||||||
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
|
if (src.getAudioData() == ad) {
|
||||||
if (assetKey.isStream())
|
|
||||||
{
|
|
||||||
for (AudioNode src : musicPlaying.keySet())
|
|
||||||
{
|
|
||||||
if (src.getAudioData() == ad)
|
|
||||||
{
|
|
||||||
MediaPlayer mp = musicPlaying.get(src);
|
MediaPlayer mp = musicPlaying.get(src);
|
||||||
mp.stop();
|
mp.stop();
|
||||||
mp.release();
|
mp.release();
|
||||||
musicPlaying.remove(src);
|
musicPlaying.remove(src);
|
||||||
src.setStatus(Status.Stopped);
|
src.setStatus(Status.Stopped);
|
||||||
src.setChannel(-1);
|
src.setChannel(-1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (audioData.getId() > 0) {
|
||||||
{
|
soundPool.unload(audioData.getId());
|
||||||
if (audioData.getSoundId() > 0)
|
|
||||||
{
|
|
||||||
soundPool.unload(audioData.getSoundId());
|
|
||||||
}
|
}
|
||||||
audioData.setSoundId(0);
|
audioData.setId(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("AudioData is not of type AndroidAudioData in deleteAudioData");
|
throw new IllegalArgumentException("AudioData is not of type AndroidAudioData in deleteAudioData");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnvironment(Environment env) {
|
public void setEnvironment(Environment env) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2010 jMonkeyEngine
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.jme3.audio;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for managing AL (Audio Library) objects.
|
|
||||||
*
|
|
||||||
* @author Kirill Vainer
|
|
||||||
*/
|
|
||||||
public abstract class ALObject {
|
|
||||||
|
|
||||||
protected int id = -1;
|
|
||||||
protected Object handleRef = null;
|
|
||||||
protected boolean updateNeeded = true;
|
|
||||||
|
|
||||||
public void setId(int id){
|
|
||||||
if (this.id != -1)
|
|
||||||
throw new IllegalStateException("ID has already been set for this AL object.");
|
|
||||||
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(){
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdateNeeded(){
|
|
||||||
updateNeeded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearUpdateNeeded(){
|
|
||||||
updateNeeded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUpdateNeeded(){
|
|
||||||
return updateNeeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(){
|
|
||||||
return getClass().getSimpleName() + " " + Integer.toHexString(hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void resetObject();
|
|
||||||
|
|
||||||
public abstract void deleteObject(AudioRenderer r);
|
|
||||||
|
|
||||||
}
|
|
@ -33,6 +33,7 @@
|
|||||||
package com.jme3.audio;
|
package com.jme3.audio;
|
||||||
|
|
||||||
import com.jme3.audio.AudioData.DataType;
|
import com.jme3.audio.AudioData.DataType;
|
||||||
|
import com.jme3.util.NativeObject;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,6 +52,11 @@ public class AudioBuffer extends AudioData {
|
|||||||
protected ByteBuffer audioData;
|
protected ByteBuffer audioData;
|
||||||
|
|
||||||
public AudioBuffer(){
|
public AudioBuffer(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AudioBuffer(int id){
|
||||||
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataType getDataType() {
|
public DataType getDataType() {
|
||||||
@ -98,7 +104,17 @@ public class AudioBuffer extends AudioData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deleteObject(AudioRenderer ar) {
|
public void deleteObject(AudioRenderer ar) {
|
||||||
ar.deleteAudioData(this);
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteObject(Object rendererObject) {
|
||||||
|
((AudioRenderer)rendererObject).deleteAudioData(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeObject createDestructableClone() {
|
||||||
|
return new AudioBuffer(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
package com.jme3.audio;
|
package com.jme3.audio;
|
||||||
|
|
||||||
|
import com.jme3.util.NativeObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>AudioData</code> is an abstract representation
|
* <code>AudioData</code> is an abstract representation
|
||||||
* of audio data. There are two ways to handle audio data, short audio files
|
* of audio data. There are two ways to handle audio data, short audio files
|
||||||
@ -40,7 +42,7 @@ package com.jme3.audio;
|
|||||||
*
|
*
|
||||||
* @author Kirill Vainer
|
* @author Kirill Vainer
|
||||||
*/
|
*/
|
||||||
public abstract class AudioData extends ALObject {
|
public abstract class AudioData extends NativeObject {
|
||||||
|
|
||||||
protected int sampleRate;
|
protected int sampleRate;
|
||||||
protected int channels;
|
protected int channels;
|
||||||
@ -50,7 +52,15 @@ public abstract class AudioData extends ALObject {
|
|||||||
Buffer,
|
Buffer,
|
||||||
Stream
|
Stream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AudioData(){
|
||||||
|
super(AudioData.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AudioData(int id){
|
||||||
|
super(AudioData.class, id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The data type, either <code>Buffer</code> or <code>Stream</code>.
|
* @return The data type, either <code>Buffer</code> or <code>Stream</code>.
|
||||||
*/
|
*/
|
||||||
|
@ -64,7 +64,7 @@ public class AudioNode extends Node {
|
|||||||
protected float pitch = 1;
|
protected float pitch = 1;
|
||||||
protected float timeOffset = 0;
|
protected float timeOffset = 0;
|
||||||
protected Filter dryFilter;
|
protected Filter dryFilter;
|
||||||
protected AudioKey key;
|
protected AudioKey audioKey;
|
||||||
protected transient AudioData data = null;
|
protected transient AudioData data = null;
|
||||||
protected transient volatile Status status = Status.Stopped;
|
protected transient volatile Status status = Status.Stopped;
|
||||||
protected transient volatile int channel = -1;
|
protected transient volatile int channel = -1;
|
||||||
@ -123,22 +123,22 @@ public class AudioNode extends Node {
|
|||||||
*
|
*
|
||||||
* @param audioRenderer The audio renderer to use for playing. Cannot be null.
|
* @param audioRenderer The audio renderer to use for playing. Cannot be null.
|
||||||
* @param audioData The audio data contains the audio track to play.
|
* @param audioData The audio data contains the audio track to play.
|
||||||
* @param key The audio key that was used to load the AudioData
|
* @param audioKey The audio key that was used to load the AudioData
|
||||||
*
|
*
|
||||||
* @deprecated AudioRenderer parameter is ignored.
|
* @deprecated AudioRenderer parameter is ignored.
|
||||||
*/
|
*/
|
||||||
public AudioNode(AudioRenderer audioRenderer, AudioData audioData, AudioKey key) {
|
public AudioNode(AudioRenderer audioRenderer, AudioData audioData, AudioKey audioKey) {
|
||||||
setAudioData(audioData, key);
|
setAudioData(audioData, audioKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new <code>AudioNode</code> with the given data and key.
|
* Creates a new <code>AudioNode</code> with the given data and key.
|
||||||
*
|
*
|
||||||
* @param audioData The audio data contains the audio track to play.
|
* @param audioData The audio data contains the audio track to play.
|
||||||
* @param key The audio key that was used to load the AudioData
|
* @param audioKey The audio key that was used to load the AudioData
|
||||||
*/
|
*/
|
||||||
public AudioNode(AudioData audioData, AudioKey key) {
|
public AudioNode(AudioData audioData, AudioKey audioKey) {
|
||||||
setAudioData(audioData, key);
|
setAudioData(audioData, audioKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,8 +157,8 @@ public class AudioNode extends Node {
|
|||||||
* @deprecated AudioRenderer parameter is ignored.
|
* @deprecated AudioRenderer parameter is ignored.
|
||||||
*/
|
*/
|
||||||
public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name, boolean stream, boolean streamCache) {
|
public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name, boolean stream, boolean streamCache) {
|
||||||
this.key = new AudioKey(name, stream, streamCache);
|
this.audioKey = new AudioKey(name, stream, streamCache);
|
||||||
this.data = (AudioData) assetManager.loadAsset(key);
|
this.data = (AudioData) assetManager.loadAsset(audioKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,8 +174,8 @@ public class AudioNode extends Node {
|
|||||||
* seeking, looping and determining duration.
|
* seeking, looping and determining duration.
|
||||||
*/
|
*/
|
||||||
public AudioNode(AssetManager assetManager, String name, boolean stream, boolean streamCache) {
|
public AudioNode(AssetManager assetManager, String name, boolean stream, boolean streamCache) {
|
||||||
this.key = new AudioKey(name, stream, streamCache);
|
this.audioKey = new AudioKey(name, stream, streamCache);
|
||||||
this.data = (AudioData) assetManager.loadAsset(key);
|
this.data = (AudioData) assetManager.loadAsset(audioKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,15 +309,15 @@ public class AudioNode extends Node {
|
|||||||
* without an {@link AudioData}.
|
* without an {@link AudioData}.
|
||||||
*
|
*
|
||||||
* @param audioData The audio data contains the audio track to play.
|
* @param audioData The audio data contains the audio track to play.
|
||||||
* @param key The audio key that was used to load the AudioData
|
* @param audioKey The audio key that was used to load the AudioData
|
||||||
*/
|
*/
|
||||||
public void setAudioData(AudioData audioData, AudioKey key) {
|
public void setAudioData(AudioData audioData, AudioKey audioKey) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
throw new IllegalStateException("Cannot change data once its set");
|
throw new IllegalStateException("Cannot change data once its set");
|
||||||
}
|
}
|
||||||
|
|
||||||
data = audioData;
|
data = audioData;
|
||||||
this.key = key;
|
this.audioKey = audioKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -713,7 +713,7 @@ public class AudioNode extends Node {
|
|||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
super.write(ex);
|
super.write(ex);
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(key, "key", null);
|
oc.write(audioKey, "audio_key", null);
|
||||||
oc.write(loop, "looping", false);
|
oc.write(loop, "looping", false);
|
||||||
oc.write(volume, "volume", 1);
|
oc.write(volume, "volume", 1);
|
||||||
oc.write(pitch, "pitch", 1);
|
oc.write(pitch, "pitch", 1);
|
||||||
@ -738,7 +738,16 @@ public class AudioNode extends Node {
|
|||||||
public void read(JmeImporter im) throws IOException {
|
public void read(JmeImporter im) throws IOException {
|
||||||
super.read(im);
|
super.read(im);
|
||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
key = (AudioKey) ic.readSavable("key", null);
|
|
||||||
|
// NOTE: In previous versions of jME3, audioKey was actually
|
||||||
|
// written with the name "key". This has been changed
|
||||||
|
// to "audio_key" in case Spatial's key will be written as "key".
|
||||||
|
if (ic.getSavableVersion(AudioNode.class) == 0){
|
||||||
|
audioKey = (AudioKey) ic.readSavable("key", null);
|
||||||
|
}else{
|
||||||
|
audioKey = (AudioKey) ic.readSavable("audio_key", null);
|
||||||
|
}
|
||||||
|
|
||||||
loop = ic.readBoolean("looping", false);
|
loop = ic.readBoolean("looping", false);
|
||||||
volume = ic.readFloat("volume", 1);
|
volume = ic.readFloat("volume", 1);
|
||||||
pitch = ic.readFloat("pitch", 1);
|
pitch = ic.readFloat("pitch", 1);
|
||||||
@ -758,8 +767,9 @@ public class AudioNode extends Node {
|
|||||||
|
|
||||||
positional = ic.readBoolean("positional", false);
|
positional = ic.readBoolean("positional", false);
|
||||||
|
|
||||||
if (key != null)
|
if (audioKey != null) {
|
||||||
data = im.getAssetManager().loadAudio(key);
|
data = im.getAssetManager().loadAudio(audioKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,6 +61,7 @@ public interface AudioRenderer {
|
|||||||
public void updateSourceParam(AudioNode src, AudioParam param);
|
public void updateSourceParam(AudioNode src, AudioParam param);
|
||||||
public void updateListenerParam(Listener listener, ListenerParam param);
|
public void updateListenerParam(Listener listener, ListenerParam param);
|
||||||
|
|
||||||
|
public void deleteFilter(Filter filter);
|
||||||
public void deleteAudioData(AudioData ad);
|
public void deleteAudioData(AudioData ad);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
package com.jme3.audio;
|
package com.jme3.audio;
|
||||||
|
|
||||||
|
import com.jme3.util.NativeObject;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -52,6 +53,16 @@ public class AudioStream extends AudioData implements Closeable{
|
|||||||
protected int[] ids;
|
protected int[] ids;
|
||||||
|
|
||||||
public AudioStream(){
|
public AudioStream(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AudioStream(int[] ids){
|
||||||
|
// Pass some dummy ID so handle
|
||||||
|
// doesn't get created.
|
||||||
|
super(-1);
|
||||||
|
|
||||||
|
// This is what gets destroyed in reality
|
||||||
|
this.ids = ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateData(InputStream in, float duration){
|
public void updateData(InputStream in, float duration){
|
||||||
@ -142,10 +153,17 @@ public class AudioStream extends AudioData implements Closeable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(AudioRenderer r) {
|
public void deleteObject(Object rendererObject) {
|
||||||
r.deleteAudioData(this);
|
// It seems that the audio renderer is already doing a good
|
||||||
|
// job at deleting audio streams when they finish playing.
|
||||||
|
// ((AudioRenderer)rendererObject).deleteAudioData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeObject createDestructableClone() {
|
||||||
|
return new AudioStream(ids);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether the stream is open or not. Reading from a closed
|
* @return Whether the stream is open or not. Reading from a closed
|
||||||
* stream will always return eof.
|
* stream will always return eof.
|
||||||
|
@ -35,29 +35,19 @@ package com.jme3.audio;
|
|||||||
import com.jme3.export.JmeExporter;
|
import com.jme3.export.JmeExporter;
|
||||||
import com.jme3.export.JmeImporter;
|
import com.jme3.export.JmeImporter;
|
||||||
import com.jme3.export.Savable;
|
import com.jme3.export.Savable;
|
||||||
|
import com.jme3.util.NativeObject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class Filter implements Savable {
|
public abstract class Filter extends NativeObject implements Savable {
|
||||||
|
|
||||||
protected int id = -1;
|
public Filter(){
|
||||||
protected boolean updateNeeded = true;
|
super(Filter.class);
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(int id) {
|
protected Filter(int id){
|
||||||
this.id = id;
|
super(Filter.class, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearUpdateNeeded(){
|
|
||||||
this.updateNeeded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUpdateNeeded() {
|
|
||||||
return updateNeeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
// nothing to save
|
// nothing to save
|
||||||
}
|
}
|
||||||
@ -66,4 +56,18 @@ public class Filter implements Savable {
|
|||||||
// nothing to read
|
// nothing to read
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetObject() {
|
||||||
|
this.id = -1;
|
||||||
|
setUpdateNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteObject(Object rendererObject) {
|
||||||
|
((AudioRenderer)rendererObject).deleteFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract NativeObject createDestructableClone();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import com.jme3.export.JmeExporter;
|
|||||||
import com.jme3.export.JmeImporter;
|
import com.jme3.export.JmeImporter;
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.InputCapsule;
|
||||||
import com.jme3.export.OutputCapsule;
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.util.NativeObject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class LowPassFilter extends Filter {
|
public class LowPassFilter extends Filter {
|
||||||
@ -43,9 +44,14 @@ public class LowPassFilter extends Filter {
|
|||||||
protected float volume, highFreqVolume;
|
protected float volume, highFreqVolume;
|
||||||
|
|
||||||
public LowPassFilter(float volume, float highFreqVolume) {
|
public LowPassFilter(float volume, float highFreqVolume) {
|
||||||
|
super();
|
||||||
setVolume(volume);
|
setVolume(volume);
|
||||||
setHighFreqVolume(highFreqVolume);
|
setHighFreqVolume(highFreqVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected LowPassFilter(int id){
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
public float getHighFreqVolume() {
|
public float getHighFreqVolume() {
|
||||||
return highFreqVolume;
|
return highFreqVolume;
|
||||||
@ -86,4 +92,9 @@ public class LowPassFilter extends Filter {
|
|||||||
highFreqVolume = ic.readFloat("hf_volume", 0);
|
highFreqVolume = ic.readFloat("hf_volume", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeObject createDestructableClone() {
|
||||||
|
return new LowPassFilter(id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ import com.jme3.audio.Listener;
|
|||||||
import com.jme3.audio.LowPassFilter;
|
import com.jme3.audio.LowPassFilter;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
|
import com.jme3.util.NativeObjectManager;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
@ -68,6 +69,8 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(LwjglAudioRenderer.class.getName());
|
private static final Logger logger = Logger.getLogger(LwjglAudioRenderer.class.getName());
|
||||||
|
|
||||||
|
private final NativeObjectManager objManager = new NativeObjectManager();
|
||||||
|
|
||||||
// When multiplied by STREAMING_BUFFER_COUNT, will equal 44100 * 2 * 2
|
// When multiplied by STREAMING_BUFFER_COUNT, will equal 44100 * 2 * 2
|
||||||
// which is exactly 1 second of audio.
|
// which is exactly 1 second of audio.
|
||||||
private static final int BUFFER_SIZE = 35280;
|
private static final int BUFFER_SIZE = 35280;
|
||||||
@ -228,7 +231,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
EFX10.alEffecti(reverbFx, EFX10.AL_EFFECT_TYPE, EFX10.AL_EFFECT_REVERB);
|
EFX10.alEffecti(reverbFx, EFX10.AL_EFFECT_TYPE, EFX10.AL_EFFECT_REVERB);
|
||||||
|
|
||||||
// attach reverb effect to effect slot
|
// attach reverb effect to effect slot
|
||||||
// EFX10.alAuxiliaryEffectSloti(reverbFxSlot, EFX10.AL_EFFECTSLOT_EFFECT, reverbFx);
|
EFX10.alAuxiliaryEffectSloti(reverbFxSlot, EFX10.AL_EFFECTSLOT_EFFECT, reverbFx);
|
||||||
}else{
|
}else{
|
||||||
logger.log(Level.WARNING, "OpenAL EFX not available! Audio effects won't work.");
|
logger.log(Level.WARNING, "OpenAL EFX not available! Audio effects won't work.");
|
||||||
}
|
}
|
||||||
@ -252,19 +255,22 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
ib.put(channels);
|
ib.put(channels);
|
||||||
ib.flip();
|
ib.flip();
|
||||||
alDeleteSources(ib);
|
alDeleteSources(ib);
|
||||||
|
|
||||||
|
// delete audio buffers and filters
|
||||||
|
objManager.deleteAllObjects(this);
|
||||||
|
|
||||||
if (supportEfx){
|
if (supportEfx){
|
||||||
ib.position(0).limit(1);
|
ib.position(0).limit(1);
|
||||||
ib.put(0, reverbFx);
|
ib.put(0, reverbFx);
|
||||||
EFX10.alDeleteEffects(ib);
|
EFX10.alDeleteEffects(ib);
|
||||||
|
|
||||||
|
// If this is not allocated, why is it deleted?
|
||||||
|
// Commented out to fix native crash in OpenAL.
|
||||||
ib.position(0).limit(1);
|
ib.position(0).limit(1);
|
||||||
ib.put(0, reverbFxSlot);
|
ib.put(0, reverbFxSlot);
|
||||||
EFX10.alDeleteAuxiliaryEffectSlots(ib);
|
EFX10.alDeleteAuxiliaryEffectSlots(ib);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Cleanup buffers allocated for audio buffers and streams
|
|
||||||
|
|
||||||
AL.destroy();
|
AL.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +288,8 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
EFX10.alGenFilters(ib);
|
EFX10.alGenFilters(ib);
|
||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
f.setId(id);
|
f.setId(id);
|
||||||
|
|
||||||
|
objManager.registerForCleanup(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f instanceof LowPassFilter){
|
if (f instanceof LowPassFilter){
|
||||||
@ -296,7 +304,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
|
|
||||||
f.clearUpdateNeeded();
|
f.clearUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSourceParam(AudioNode src, AudioParam param){
|
public void updateSourceParam(AudioNode src, AudioParam param){
|
||||||
checkDead();
|
checkDead();
|
||||||
synchronized (threadLock){
|
synchronized (threadLock){
|
||||||
@ -792,6 +800,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete any unused objects.
|
||||||
|
objManager.deleteUnused(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setListener(Listener listener) {
|
public void setListener(Listener listener) {
|
||||||
@ -983,6 +994,8 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
alGenBuffers(ib);
|
alGenBuffers(ib);
|
||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
ab.setId(id);
|
ab.setId(id);
|
||||||
|
|
||||||
|
objManager.registerForCleanup(ab);
|
||||||
}
|
}
|
||||||
|
|
||||||
ab.getData().clear();
|
ab.getData().clear();
|
||||||
@ -1001,6 +1014,10 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
||||||
ib.get(ids);
|
ib.get(ids);
|
||||||
|
|
||||||
|
// Not registered with object manager.
|
||||||
|
// AudioStreams can be handled without object manager
|
||||||
|
// since their lifecycle is known to the audio renderer.
|
||||||
|
|
||||||
as.setIds(ids);
|
as.setIds(ids);
|
||||||
as.clearUpdateNeeded();
|
as.clearUpdateNeeded();
|
||||||
}
|
}
|
||||||
@ -1012,6 +1029,13 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
updateAudioStream((AudioStream) ad);
|
updateAudioStream((AudioStream) ad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteFilter(Filter filter) {
|
||||||
|
int id = filter.getId();
|
||||||
|
if (id != -1){
|
||||||
|
EFX10.alDeleteFilters(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteAudioData(AudioData ad){
|
public void deleteAudioData(AudioData ad){
|
||||||
synchronized (threadLock){
|
synchronized (threadLock){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user