I have managed to get sounds loading off the filesystem on android devices with a few changes to the AndroidAudioRender class.
Adding at the top of the file:
[java]
private com.jme3.asset.AssetManager jme3AssetManager;
class SoundFileInfo{
FileDescriptor fd;
long startOffset;
long length;
}
[/java]
And some changes to playSource and playSourceInstance:
[java]
public void playSource(AudioSource src) {
if (audioDisabled) {
return;
}
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
MediaPlayer mp = musicPlaying.get(src);
if (mp == null) {
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
try {
if (src.getStatus() == Status.Stopped) {
mp.reset();
AssetKey key = audioData.getAssetKey();
// FIXME: Still need to get zip files working.
FileDescriptor fd = null;
long startOffset = 0;
long length = 0;
SoundFileInfo soundInfo = getSoundInfo(key);
mp.setDataSource(soundInfo.fd, soundInfo.startOffset, soundInfo.length);
mp.prepare();
setSourceParams(src, mp);
src.setChannel(0);
src.setStatus(Status.Playing);
musicPlaying.put(src, mp);
mp.start();
} else {
mp.start();
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
[/java]
and…
[java]
public void playSourceInstance(AudioSource src) {
if (audioDisabled) {
return;
}
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
if (!(audioData.getAssetKey() instanceof AudioKey)) {
throw new IllegalArgumentException("Asset is not a AudioKey");
}
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
try {
if (audioData.getId() < 0) { // found something to load
SoundFileInfo soundInfo = getSoundInfo(assetKey);
int soundId = soundPool.load(soundInfo.fd, soundInfo.startOffset, soundInfo.length, 1);
// int soundId = soundPool.load(
// assetManager.openFd(assetKey.getName()), 1);
audioData.setId(soundId);
}
int channel = soundPool.play(audioData.getId(), 1f, 1f, 1, 0, 1f);
if (channel == 0) {
soundpoolStillLoading.put(audioData.getId(), src);
} else {
if (src.getStatus() != Status.Stopped) {
soundPool.stop(channel);
src.setStatus(Status.Stopped);
}
src.setChannel(channel); // receive a channel at the last
setSourceParams(src);
// playing at least
}
} catch (IOException e) {
logger.log(Level.SEVERE,
"Failed to load sound " + assetKey.getName(), e);
audioData.setId(-1);
}
}
[/java]
I also added the method getSoundInfo which returns all three required pieces of info to play the sound in a wrapped block
[java]
private SoundFileInfo getSoundInfo(AssetKey key) throws IOException {
SoundFileInfo ret = new SoundFileInfo();
if(jme3AssetManager != null){
AssetInfo aInfo = jme3AssetManager.locateAsset(key);
System.out.println(key);
if(aInfo != null){
System.out.println(aInfo.getClass());
InputStream is = aInfo.openStream();
if(is instanceof FileInputStream){
ret.fd = ((FileInputStream)is).getFD();
ret.startOffset = 0;
ret.length = is.available();
}
}
}
if(ret.fd == null){
AssetFileDescriptor afd = assetManager.openFd(key.getName()); // assetKey.getName()
ret.fd = afd.getFileDescriptor();
ret.startOffset = afd.getStartOffset();
ret.length = afd.getLength();
}
return ret;
}
[/java]
As far as the fixme comment I made about zip files, I can implement this, but it will require some code provided by Google (Apache license) to do without reinventing the wheel. If that won’t be detremental to the project, I’ll get on it, but wanted to check for opinions on that before I started.