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:
parent
59d1b7c894
commit
f5ee0ca201
@ -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,12 +210,13 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
|
|||||||
@Override
|
@Override
|
||||||
public void updateListenerParam(Listener listener, ListenerParam param)
|
public void updateListenerParam(Listener listener, ListenerParam param)
|
||||||
{
|
{
|
||||||
|
logger.log(Level.INFO, "updateListenerParam " + param);
|
||||||
if (audioDisabled)
|
if (audioDisabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (param){
|
switch (param){
|
||||||
case Position:
|
case Position:
|
||||||
Vector3f pos = listener.getLocation();
|
listenerPosition.set(listener.getLocation());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Rotation:
|
case Rotation:
|
||||||
@ -228,22 +235,34 @@ public class AndroidAudioRenderer implements AudioRenderer, SoundPool.OnLoadComp
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
@Override
|
||||||
|
|
||||||
public void update(float tpf)
|
public void update(float tpf)
|
||||||
{
|
{
|
||||||
// does nothing
|
float distance;
|
||||||
}
|
float volume;
|
||||||
|
|
||||||
public void updateInThread(float tpf)
|
// Loop over all mediaplayers
|
||||||
|
for (AudioNode src : musicPlaying.keySet())
|
||||||
{
|
{
|
||||||
if (audioDisabled)
|
MediaPlayer mp = musicPlaying.get(src);
|
||||||
return;
|
{
|
||||||
if (!audioDisabled)
|
// Calc the distance to the listener
|
||||||
return;
|
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)
|
||||||
{
|
{
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,6 +381,8 @@ 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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -416,7 +421,10 @@ 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
|
||||||
|
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user