* Applied audio fix patch (thanks prich)

- Pause audio when jME3 app is paused
   - Add WAV to supported formats 
   - Add Android audio test 
 * Minor javadoc fixes in AndroidHarness
 * Made jme3tools.android.Fixed class deprecated

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9152 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Sha..rd 13 years ago
parent 4721c944a2
commit b89b2428af
  1. 61
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 2
      engine/src/android/com/jme3/asset/AndroidAssetManager.java
  3. 23
      engine/src/android/com/jme3/audio/android/AndroidAudioRenderer.java
  4. 40
      engine/src/android/jme3test/android/SimpleSoundTest.java
  5. 4
      engine/src/android/jme3tools/android/Fixed.java

@ -8,15 +8,13 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable; import android.graphics.drawable.NinePatchDrawable;
import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView;
import android.os.Bundle; import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.view.Window; import android.view.*;
import android.view.WindowManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.jme3.audio.AudioRenderer;
import com.jme3.audio.android.AndroidAudioRenderer;
import com.jme3.input.android.AndroidInput; import com.jme3.input.android.AndroidInput;
import com.jme3.input.controls.TouchListener; import com.jme3.input.controls.TouchListener;
import com.jme3.input.event.TouchEvent; import com.jme3.input.event.TouchEvent;
@ -26,7 +24,6 @@ import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import com.jme3.system.android.JmeAndroidSystem; import com.jme3.system.android.JmeAndroidSystem;
import com.jme3.system.android.OGLESContext; import com.jme3.system.android.OGLESContext;
import com.jme3.util.JmeFormatter; import com.jme3.util.JmeFormatter;
import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.logging.Handler; import java.util.logging.Handler;
@ -43,76 +40,63 @@ import java.util.logging.Logger;
public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener { public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener {
protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName()); protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName());
/** /**
* The application class to start * The application class to start
*/ */
protected String appClass = "jme3test.android.Test"; protected String appClass = "jme3test.android.Test";
/** /**
* The jme3 application object * The jme3 application object
*/ */
protected Application app = null; protected Application app = null;
/** /**
* ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is * ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is
* RGBA8888 or better if supported by the hardware * RGBA8888 or better if supported by the hardware
*/ */
protected ConfigType eglConfigType = ConfigType.FASTEST; protected ConfigType eglConfigType = ConfigType.FASTEST;
/** /**
* If true all valid and not valid egl configs are logged * If true all valid and not valid egl configs are logged
*/ */
protected boolean eglConfigVerboseLogging = false; protected boolean eglConfigVerboseLogging = false;
/** /**
* If true MouseEvents are generated from TouchEvents * If true MouseEvents are generated from TouchEvents
*/ */
protected boolean mouseEventsEnabled = true; protected boolean mouseEventsEnabled = true;
/** /**
* Flip X axis * Flip X axis
*/ */
protected boolean mouseEventsInvertX = true; protected boolean mouseEventsInvertX = true;
/** /**
* Flip Y axis * Flip Y axis
*/ */
protected boolean mouseEventsInvertY = true; protected boolean mouseEventsInvertY = true;
/** /**
* Title of the exit dialog, default is "Do you want to exit?" * Title of the exit dialog, default is "Do you want to exit?"
*/ */
protected String exitDialogTitle = "Do you want to exit?"; protected String exitDialogTitle = "Do you want to exit?";
/** /**
* Message of the exit dialog, default is "Use your home key to bring this * Message of the exit dialog, default is "Use your home key to bring this
* app into the background or exit to terminate it." * app into the background or exit to terminate it."
*/ */
protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it."; protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it.";
/** /**
* Set the screen window mode. * Set the screen window mode. If screenFullSize is true, then the
* If screenFullSize is true, then the notification bar and title bar are * notification bar and title bar are removed and the screen covers the
* removed and the screen covers the entire display.   * entire display.   If screenFullSize is false, then the notification bar
* If screenFullSize is false, then the notification bar remains visible if * remains visible if screenShowTitle is true while screenFullScreen is
* screenShowTitle is true while screenFullScreen is false, * false, then the title bar is also displayed under the notification bar.
* then the title bar is also displayed under the notification bar.
*/ */
protected boolean screenFullScreen = true; protected boolean screenFullScreen = true;
/** /**
* if screenShowTitle is true while screenFullScreen is false, then the * if screenShowTitle is true while screenFullScreen is false, then the
* title bar is also displayed under the notification bar * title bar is also displayed under the notification bar
*/ */
protected boolean screenShowTitle = true; protected boolean screenShowTitle = true;
/** /**
* Splash Screen picture Resource ID. If a Splash Screen is desired, set * Splash Screen picture Resource ID. If a Splash Screen is desired, set
* splashPicID to the value of the Resource ID (i.e. R.drawable.picname). If * splashPicID to the value of the Resource ID (i.e. R.drawable.picname). If
* splashPicID = 0, then no splash screen will be displayed. * splashPicID = 0, then no splash screen will be displayed.
*/ */
protected int splashPicID = 0; protected int splashPicID = 0;
/** /**
* Set the screen orientation, default is SENSOR * Set the screen orientation, default is SENSOR
* ActivityInfo.SCREEN_ORIENTATION_* constants package * ActivityInfo.SCREEN_ORIENTATION_* constants package
@ -216,6 +200,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
if (app != null) { if (app != null) {
app.restart(); app.restart();
} }
logger.info("onRestart"); logger.info("onRestart");
} }
@ -231,6 +216,14 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
if (view != null) { if (view != null) {
view.onResume(); view.onResume();
} }
//resume the audio
AudioRenderer result = app.getAudioRenderer();
if (result instanceof AndroidAudioRenderer) {
AndroidAudioRenderer renderer = (AndroidAudioRenderer) result;
renderer.resumeAll();
}
isGLThreadPaused = false; isGLThreadPaused = false;
logger.info("onResume"); logger.info("onResume");
} }
@ -241,6 +234,15 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
if (view != null) { if (view != null) {
view.onPause(); view.onPause();
} }
//pause the audio
AudioRenderer result = app.getAudioRenderer();
logger.info("pause: " + result.getClass().getSimpleName());
if (result instanceof AndroidAudioRenderer) {
AndroidAudioRenderer renderer = (AndroidAudioRenderer) result;
renderer.pauseAll();
}
isGLThreadPaused = true; isGLThreadPaused = true;
logger.info("onPause"); logger.info("onPause");
} }
@ -248,6 +250,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
logger.info("onStop"); logger.info("onStop");
} }
@ -256,6 +259,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
if (app != null) { if (app != null) {
app.stop(!isGLThreadPaused); app.stop(!isGLThreadPaused);
} }
logger.info("onDestroy"); logger.info("onDestroy");
super.onDestroy(); super.onDestroy();
} }
@ -265,15 +269,14 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
} }
/** /**
* Called when an error has occurred. * Called when an error has occurred. By default, will show an error message
* By default, will show an error message to the user * to the user and print the exception/error to the log.
* and print the exception/error to the log.
*/ */
public void handleError(final String errorMsg, final Throwable t) { public void handleError(final String errorMsg, final Throwable t) {
String stackTrace = ""; String stackTrace = "";
String title = "Error"; String title = "Error";
if (t != null){ if (t != null) {
// Convert exception to string // Convert exception to string
StringWriter sw = new StringWriter(100); StringWriter sw = new StringWriter(100);
t.printStackTrace(new PrintWriter(sw)); t.printStackTrace(new PrintWriter(sw));
@ -288,6 +291,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
logger.log(Level.SEVERE, finalMsg); logger.log(Level.SEVERE, finalMsg);
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) // .setIcon(R.drawable.alert_dialog_icon) AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) // .setIcon(R.drawable.alert_dialog_icon)
@ -324,6 +328,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
switch (evt.getType()) { switch (evt.getType()) {
case KEY_UP: case KEY_UP:
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) // .setIcon(R.drawable.alert_dialog_icon) AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) // .setIcon(R.drawable.alert_dialog_icon)

@ -70,7 +70,7 @@ public class AndroidAssetManager extends DesktopAssetManager {
this.registerLocator("", AndroidLocator.class); this.registerLocator("", AndroidLocator.class);
this.registerLocator("", ClasspathLocator.class); this.registerLocator("", ClasspathLocator.class);
this.registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg"); this.registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg");
this.registerLoader(AndroidAudioLoader.class, "ogg", "mp3"); this.registerLoader(AndroidAudioLoader.class, "ogg", "mp3", "wav");
this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3m"); this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3m");
this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3md"); this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3md");
this.registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt"); this.registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt");

@ -408,6 +408,27 @@ public class AndroidAudioRenderer implements AudioRenderer,
} }
} }
/**
* Pause the current playing sounds. Both from the {@link SoundPool} and the
* active {@link MediaPlayer}s
*/
public void pauseAll() {
soundPool.autoPause();
for (MediaPlayer mp : musicPlaying.values()) {
mp.pause();
}
}
/**
* Resume all paused sounds.
*/
public void resumeAll() {
soundPool.autoResume();
for (MediaPlayer mp : musicPlaying.values()) {
mp.start(); //no resume -> api says call start to resume
}
}
public void pauseSource(AudioNode src) { public void pauseSource(AudioNode src) {
if (audioDisabled) { if (audioDisabled) {
return; return;
@ -469,7 +490,7 @@ public class AndroidAudioRenderer implements AudioRenderer,
@Override @Override
public void setEnvironment(Environment env) { public void setEnvironment(Environment env) {
//not yet supported // not yet supported
} }
@Override @Override

@ -0,0 +1,40 @@
package jme3test.android;
import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioNode;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.InputListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.math.Vector3f;
public class SimpleSoundTest extends SimpleApplication implements InputListener {
private AudioNode gun;
private AudioNode nature;
@Override
public void simpleInitApp() {
gun = new AudioNode(assetManager, "Sound/Effects/Gun.wav");
gun.setPositional(true);
gun.setLocalTranslation(new Vector3f(0, 0, 0));
gun.setMaxDistance(100);
gun.setRefDistance(5);
nature = new AudioNode(assetManager, "Sound/Environment/Nature.ogg", true);
nature.setVolume(3);
nature.setLooping(true);
nature.play();
inputManager.addMapping("click", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "click");
rootNode.attachChild(gun);
rootNode.attachChild(nature);
}
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("click") && isPressed) {
gun.playInstance();
}
}
}

@ -13,7 +13,11 @@ import java.util.Random;
* *
* @version 1.0 * @version 1.0
* @author CW * @author CW
*
* @deprecated Most devices with OpenGL ES 2.0 have an FPU. Please use
* floats instead of this class for decimal math.
*/ */
@Deprecated
public final class Fixed { public final class Fixed {
/** /**

Loading…
Cancel
Save