|
|
@@ -17,7 +17,7 @@ import android.view.inputmethod.BaseInputConnection;
|
|
|
import android.view.inputmethod.EditorInfo;
|
|
|
import android.view.inputmethod.InputConnection;
|
|
|
import android.view.inputmethod.InputMethodManager;
|
|
|
-import android.widget.AbsoluteLayout;
|
|
|
+import android.widget.RelativeLayout;
|
|
|
import android.widget.Button;
|
|
|
import android.widget.LinearLayout;
|
|
|
import android.widget.TextView;
|
|
|
@@ -59,6 +59,7 @@ public class SDLActivity extends Activity {
|
|
|
|
|
|
// Audio
|
|
|
protected static AudioTrack mAudioTrack;
|
|
|
+ protected static AudioRecord mAudioRecord;
|
|
|
|
|
|
/**
|
|
|
* This method is called by SDL before loading the native shared libraries.
|
|
|
@@ -106,6 +107,7 @@ public class SDLActivity extends Activity {
|
|
|
mJoystickHandler = null;
|
|
|
mSDLThread = null;
|
|
|
mAudioTrack = null;
|
|
|
+ mAudioRecord = null;
|
|
|
mExitCalledFromJava = false;
|
|
|
mBrokenLibraries = false;
|
|
|
mIsPaused = false;
|
|
|
@@ -171,7 +173,7 @@ public class SDLActivity extends Activity {
|
|
|
mJoystickHandler = new SDLJoystickHandler();
|
|
|
}
|
|
|
|
|
|
- mLayout = new AbsoluteLayout(this);
|
|
|
+ mLayout = new RelativeLayout(this);
|
|
|
mLayout.addView(mSurface);
|
|
|
|
|
|
setContentView(mLayout);
|
|
|
@@ -504,8 +506,9 @@ public class SDLActivity extends Activity {
|
|
|
|
|
|
@Override
|
|
|
public void run() {
|
|
|
- AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
|
|
|
- w, h + HEIGHT_PADDING, x, y);
|
|
|
+ RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h + HEIGHT_PADDING);
|
|
|
+ params.leftMargin = x;
|
|
|
+ params.topMargin = y;
|
|
|
|
|
|
if (mTextEdit == null) {
|
|
|
mTextEdit = new DummyEdit(getContext());
|
|
|
@@ -543,7 +546,7 @@ public class SDLActivity extends Activity {
|
|
|
/**
|
|
|
* This method is called by SDL using JNI.
|
|
|
*/
|
|
|
- public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
|
|
|
+ public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
|
|
|
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
|
|
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
|
|
|
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
|
|
|
@@ -622,13 +625,72 @@ public class SDLActivity extends Activity {
|
|
|
/**
|
|
|
* This method is called by SDL using JNI.
|
|
|
*/
|
|
|
- public static void audioQuit() {
|
|
|
+ public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
|
|
|
+ int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
|
|
+ int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
|
|
|
+ int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
|
|
|
+
|
|
|
+ Log.v(TAG, "SDL capture: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
|
|
+
|
|
|
+ // Let the user pick a larger buffer if they really want -- but ye
|
|
|
+ // gods they probably shouldn't, the minimums are horrifyingly high
|
|
|
+ // latency already
|
|
|
+ desiredFrames = Math.max(desiredFrames, (AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
|
|
|
+
|
|
|
+ if (mAudioRecord == null) {
|
|
|
+ mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate,
|
|
|
+ channelConfig, audioFormat, desiredFrames * frameSize);
|
|
|
+
|
|
|
+ // see notes about AudioTrack state in audioOpen(), above. Probably also applies here.
|
|
|
+ if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
|
|
|
+ Log.e(TAG, "Failed during initialization of AudioRecord");
|
|
|
+ mAudioRecord.release();
|
|
|
+ mAudioRecord = null;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ mAudioRecord.startRecording();
|
|
|
+ }
|
|
|
+
|
|
|
+ Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** This method is called by SDL using JNI. */
|
|
|
+ public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
|
|
|
+ // !!! FIXME: this is available in API Level 23. Until then, we always block. :(
|
|
|
+ //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
|
|
+ return mAudioRecord.read(buffer, 0, buffer.length);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** This method is called by SDL using JNI. */
|
|
|
+ public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
|
|
|
+ // !!! FIXME: this is available in API Level 23. Until then, we always block. :(
|
|
|
+ //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
|
|
+ return mAudioRecord.read(buffer, 0, buffer.length);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /** This method is called by SDL using JNI. */
|
|
|
+ public static void audioClose() {
|
|
|
if (mAudioTrack != null) {
|
|
|
mAudioTrack.stop();
|
|
|
+ mAudioTrack.release();
|
|
|
mAudioTrack = null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /** This method is called by SDL using JNI. */
|
|
|
+ public static void captureClose() {
|
|
|
+ if (mAudioRecord != null) {
|
|
|
+ mAudioRecord.stop();
|
|
|
+ mAudioRecord.release();
|
|
|
+ mAudioRecord = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
// Input
|
|
|
|
|
|
/**
|
|
|
@@ -670,15 +732,6 @@ public class SDLActivity extends Activity {
|
|
|
/** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */
|
|
|
private Method expansionFileMethod;
|
|
|
|
|
|
- /**
|
|
|
- * This method was called by SDL using JNI.
|
|
|
- * @deprecated because of an incorrect name
|
|
|
- */
|
|
|
- @Deprecated
|
|
|
- public InputStream openAPKExtensionInputStream(String fileName) throws IOException {
|
|
|
- return openAPKExpansionInputStream(fileName);
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* This method is called by SDL using JNI.
|
|
|
* @return an InputStream on success or null if no expansion file was used.
|
|
|
@@ -1393,7 +1446,7 @@ class DummyEdit extends View implements View.OnKeyListener {
|
|
|
// As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
|
|
|
// FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
|
|
|
// FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
|
|
|
- // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear
|
|
|
+ // FIXME: A more effective solution would be to assume our Layout to be RelativeLayout or LinearLayout
|
|
|
// FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
|
|
|
// FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
|
|
|
if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|