Android: Added positional audio and let the user control the overall media volume

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7763 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
kim..ng 2011-06-28 18:43:36 +00:00
parent 59d1b7c894
commit f5ee0ca201
2 changed files with 81 additions and 57 deletions

View File

@ -53,6 +53,7 @@ import com.jme3.audio.Environment;
import com.jme3.audio.Filter; import com.jme3.audio.Filter;
import com.jme3.audio.Listener; import com.jme3.audio.Listener;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
@ -78,6 +79,10 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
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();
// For temp use
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;
@ -110,6 +115,7 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
@Override @Override
public void updateSourceParam(AudioNode src, AudioParam param) public void updateSourceParam(AudioNode src, AudioParam param)
{ {
logger.log(Level.INFO, "updateSourceParam " + param);
if (audioDisabled) if (audioDisabled)
return; return;
@ -204,47 +210,60 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
@Override @Override
public void updateListenerParam(Listener listener, ListenerParam param) public void updateListenerParam(Listener listener, ListenerParam param)
{ {
if (audioDisabled) logger.log(Level.INFO, "updateListenerParam " + param);
return;
switch (param){
case Position:
Vector3f pos = listener.getLocation();
break;
case Rotation:
Vector3f dir = listener.getDirection();
Vector3f up = listener.getUp();
break;
case Velocity:
Vector3f vel = listener.getVelocity();
break;
case Volume:
//alListenerf(AL_GAIN, listener.getVolume());
break;
}
}
/*
public void update(float tpf)
{
// does nothing
}
public void updateInThread(float tpf)
{
if (audioDisabled) if (audioDisabled)
return; return;
if (!audioDisabled)
return; switch (param){
case Position:
listenerPosition.set(listener.getLocation());
break;
case Rotation:
Vector3f dir = listener.getDirection();
Vector3f up = listener.getUp();
break;
case Velocity:
Vector3f vel = listener.getVelocity();
break;
case Volume:
//alListenerf(AL_GAIN, listener.getVolume());
break;
}
} }
*/
@Override
public void update(float tpf)
{
float distance;
float volume;
// Loop over all mediaplayers
for (AudioNode src : musicPlaying.keySet())
{
MediaPlayer mp = musicPlaying.get(src);
{
// Calc the distance to the listener
distanceVector.set(listenerPosition);
distanceVector.subtractLocal(src.getLocalTranslation());
distance = FastMath.abs(distanceVector.length());
if (distance < src.getRefDistance())
distance = src.getRefDistance();
if (distance > src.getMaxDistance())
distance = src.getMaxDistance();
volume = src.getRefDistance() / distance;
// Left / Right channel get the same volume by now, only positional
mp.setVolume(volume, volume);
}
}
}
public void setListener(Listener listener) public void setListener(Listener listener)
{ {
if (audioDisabled) if (audioDisabled)
@ -341,6 +360,7 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
mp.seekTo(0); mp.seekTo(0);
mp.stop(); mp.stop();
src.setStatus(Status.Stopped); src.setStatus(Status.Stopped);
break;
} }
} }
@ -360,7 +380,9 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
if (audioData.getAssetKey() instanceof AudioKey) if (audioData.getAssetKey() instanceof AudioKey)
{ {
AudioKey assetKey = (AudioKey) audioData.getAssetKey(); AudioKey assetKey = (AudioKey) audioData.getAssetKey();
// streaming audionodes get played using android mediaplayer, non streaming uses SoundPool
if (assetKey.isStream()) if (assetKey.isStream())
{ {
MediaPlayer mp; MediaPlayer mp;
@ -381,21 +403,21 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
AssetFileDescriptor afd = am.openFd(assetKey.getName()); AssetFileDescriptor afd = am.openFd(assetKey.getName());
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
//mp.setAudioStreamType(AudioManager.STREAM_MUSIC); mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare(); mp.prepare();
mp.setLooping(src.isLooping()); mp.setLooping(src.isLooping());
mp.start(); mp.start();
src.setStatus(Status.Playing);
src.setChannel(1); src.setChannel(1);
} catch (IllegalArgumentException e) { src.setStatus(Status.Playing);
// TODO Auto-generated catch block } catch (IllegalArgumentException e)
e.printStackTrace(); {
logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); logger.log(Level.SEVERE, "Failed to play " + assetKey.getName(), e);
} }
} }
@ -418,11 +440,11 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
try try
{ {
soundId = soundPool.load(am.openFd(audioData.getAssetKey().getName()), 1); soundId = soundPool.load(am.openFd(assetKey.getName()), 1);
} }
catch (IOException e) catch (IOException e)
{ {
logger.log(Level.SEVERE, "Failed to load sound " + audioData.getAssetKey().getName(), e); logger.log(Level.SEVERE, "Failed to load sound " + assetKey.getName(), e);
soundId = -1; soundId = -1;
} }
audioData.setSoundId(soundId); audioData.setSoundId(soundId);
@ -431,7 +453,7 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
// Sound failed to load ? // Sound failed to load ?
if (audioData.getSoundId() <= 0) if (audioData.getSoundId() <= 0)
{ {
throw new IllegalArgumentException("Failed to load: " + audioData.getAssetKey().getName()); throw new IllegalArgumentException("Failed to load: " + assetKey.getName());
} }
else else
{ {
@ -635,11 +657,5 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
} }
@Override
public void update(float tpf) {
// TODO Auto-generated method stub
}
} }

View File

@ -234,6 +234,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput,
} }
return evt; return evt;
} }
/** /**
* onTouchEvent gets called from android thread on touchpad events * onTouchEvent gets called from android thread on touchpad events
*/ */
@ -399,8 +400,12 @@ public class AndroidInput extends GLSurfaceView implements TouchInput,
// Send the event // Send the event
processEvent(evt); processEvent(evt);
// Handle all keys ourself // Handle all keys ourself except Volume Up/Down
return true; if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))
return false;
else
return true;
} }
@Override @Override
@ -416,8 +421,11 @@ public class AndroidInput extends GLSurfaceView implements TouchInput,
// Send the event // Send the event
processEvent(evt); processEvent(evt);
// Handle all keys ourself // Handle all keys ourself except Volume Up/Down
return true; if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))
return false;
else
return true;
} }