WIP audio recording, it crashes yet.
This commit is contained in:
@@ -359,6 +359,18 @@ if [ -n "$var" ] ; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "$AppRecordsAudio" -o -z "$AUTO" ]; then
|
||||||
|
echo
|
||||||
|
echo "Application records audio (it will use any available source, such a s microphone)"
|
||||||
|
echo "API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);"
|
||||||
|
echo -n "This option will add additional permission to Android manifest ($AppRecordsAudio): "
|
||||||
|
read var
|
||||||
|
if [ -n "$var" ] ; then
|
||||||
|
AppRecordsAudio="$var"
|
||||||
|
CHANGED=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "$NonBlockingSwapBuffers" -o -z "$AUTO" ]; then
|
if [ -z "$NonBlockingSwapBuffers" -o -z "$AUTO" ]; then
|
||||||
echo
|
echo
|
||||||
echo "Application implements Android-specific routines to put to background, and will not draw anything to screen"
|
echo "Application implements Android-specific routines to put to background, and will not draw anything to screen"
|
||||||
@@ -723,6 +735,7 @@ echo AppUsesJoystick=$AppUsesJoystick >> AndroidAppSettings.cfg
|
|||||||
echo AppUsesAccelerometer=$AppUsesAccelerometer >> AndroidAppSettings.cfg
|
echo AppUsesAccelerometer=$AppUsesAccelerometer >> AndroidAppSettings.cfg
|
||||||
echo AppUsesGyroscope=$AppUsesGyroscope >> AndroidAppSettings.cfg
|
echo AppUsesGyroscope=$AppUsesGyroscope >> AndroidAppSettings.cfg
|
||||||
echo AppUsesMultitouch=$AppUsesMultitouch >> AndroidAppSettings.cfg
|
echo AppUsesMultitouch=$AppUsesMultitouch >> AndroidAppSettings.cfg
|
||||||
|
echo AppRecordsAudio=$AppRecordsAudio >> AndroidAppSettings.cfg
|
||||||
echo NonBlockingSwapBuffers=$NonBlockingSwapBuffers >> AndroidAppSettings.cfg
|
echo NonBlockingSwapBuffers=$NonBlockingSwapBuffers >> AndroidAppSettings.cfg
|
||||||
echo RedefinedKeys=\"$RedefinedKeys\" >> AndroidAppSettings.cfg
|
echo RedefinedKeys=\"$RedefinedKeys\" >> AndroidAppSettings.cfg
|
||||||
echo AppTouchscreenKeyboardKeysAmount=$AppTouchscreenKeyboardKeysAmount >> AndroidAppSettings.cfg
|
echo AppTouchscreenKeyboardKeysAmount=$AppTouchscreenKeyboardKeysAmount >> AndroidAppSettings.cfg
|
||||||
@@ -1004,6 +1017,10 @@ else
|
|||||||
cat $F | sed "s/package .*;/package $AppFullName;/" >> project/src/Advertisement.java
|
cat $F | sed "s/package .*;/package $AppFullName;/" >> project/src/Advertisement.java
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$AppRecordsAudio" = "n" -o -z "$AppRecordsAudio" ] ; then
|
||||||
|
sed -i "/==RECORD_AUDIO==/ d" project/AndroidManifest.xml
|
||||||
|
fi
|
||||||
|
|
||||||
case "$MinimumScreenSize" in
|
case "$MinimumScreenSize" in
|
||||||
n|m)
|
n|m)
|
||||||
sed -i "/==SCREEN-SIZE-SMALL==/ d" project/AndroidManifest.xml
|
sed -i "/==SCREEN-SIZE-SMALL==/ d" project/AndroidManifest.xml
|
||||||
|
|||||||
@@ -29,9 +29,11 @@
|
|||||||
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15"/>
|
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||||
|
<!-- ==RECORD_AUDIO== --> <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
|
||||||
<!-- ==ADMOB== --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
|
<!-- ==ADMOB== --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
|
||||||
<!-- <uses-permission android:name="android.permission.VIBRATE"></uses-permission> --> <!-- Vibrator not supported yet by SDL -->
|
<!-- <uses-permission android:name="android.permission.VIBRATE"></uses-permission> --> <!-- Vibrator not supported yet by SDL -->
|
||||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
|
||||||
|
<uses-feature android:name="android.hardware.touchscreen" android:required="false" /> <!-- Allow TV boxes -->
|
||||||
<!-- ==SCREEN-SIZE-SMALL== --> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
|
<!-- ==SCREEN-SIZE-SMALL== --> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
|
||||||
<!-- ==SCREEN-SIZE-NORMAL== --> <supports-screens android:smallScreens="false" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
|
<!-- ==SCREEN-SIZE-NORMAL== --> <supports-screens android:smallScreens="false" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
|
||||||
<!-- ==SCREEN-SIZE-LARGE== --> <supports-screens android:smallScreens="false" android:normalScreens="false" android:largeScreens="true" android:xlargeScreens="true" />
|
<!-- ==SCREEN-SIZE-LARGE== --> <supports-screens android:smallScreens="false" android:normalScreens="false" android:largeScreens="true" android:xlargeScreens="true" />
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import android.view.WindowManager;
|
|||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
|
import android.media.AudioRecord;
|
||||||
|
import android.media.MediaRecorder.AudioSource;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import java.lang.Thread;
|
import java.lang.Thread;
|
||||||
@@ -132,9 +134,12 @@ class AudioThread
|
|||||||
if( mAudio != null )
|
if( mAudio != null )
|
||||||
{
|
{
|
||||||
mAudio.pause();
|
mAudio.pause();
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
if( mRecorder != null )
|
||||||
|
{
|
||||||
|
mRecorder.stop();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int resumeAudioPlayback()
|
public int resumeAudioPlayback()
|
||||||
@@ -142,11 +147,118 @@ class AudioThread
|
|||||||
if( mAudio != null )
|
if( mAudio != null )
|
||||||
{
|
{
|
||||||
mAudio.play();
|
mAudio.play();
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
if( mRecorder != null )
|
||||||
|
{
|
||||||
|
mRecorder.startRecording();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native int nativeAudioInitJavaCallbacks();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private native int nativeAudioInitJavaCallbacks();
|
||||||
|
|
||||||
|
// ----- Audio recording -----
|
||||||
|
|
||||||
|
private AudioRecord mRecorder = null;
|
||||||
|
private RecordingThread mRecordThread = null;
|
||||||
|
//private int mRecordSize;
|
||||||
|
//private int mRecordPos;
|
||||||
|
|
||||||
|
private int startRecording(int rate, int channels, int encoding, int bufsize)
|
||||||
|
{
|
||||||
|
//mRecordSize = bufsize;
|
||||||
|
//mRecordPos = 0;
|
||||||
|
if( mRecordThread != null )
|
||||||
|
{
|
||||||
|
System.out.println("SDL: error: application already opened audio recording device");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
channels = ( channels == 1 ) ? AudioFormat.CHANNEL_IN_MONO :
|
||||||
|
AudioFormat.CHANNEL_IN_STEREO;
|
||||||
|
encoding = ( encoding == 1 ) ? AudioFormat.ENCODING_PCM_16BIT :
|
||||||
|
AudioFormat.ENCODING_PCM_8BIT;
|
||||||
|
|
||||||
|
int minBufDevice = AudioRecord.getMinBufferSize(rate, channels, encoding);
|
||||||
|
int minBufferSize = Math.max(bufsize * 8, minBufDevice + (bufsize - (minBufDevice % bufsize)));
|
||||||
|
System.out.println("SDL: app opened recording device, rate " + rate + " channels " + channels + " sample size " + (encoding+1) + " bufsize " + bufsize + " internal bufsize " + minBufferSize);
|
||||||
|
try {
|
||||||
|
mRecorder = new AudioRecord(AudioSource.DEFAULT, rate, channels, encoding, minBufferSize);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.out.println("SDL: error: failed to open recording device!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
mRecordThread = new RecordingThread(bufsize);
|
||||||
|
mRecorder.startRecording();
|
||||||
|
mRecordThread.start();
|
||||||
|
return minBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopRecording()
|
||||||
|
{
|
||||||
|
if( mRecordThread == null )
|
||||||
|
{
|
||||||
|
System.out.println("SDL: error: application already closed audio recording device");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mRecordThread.terminate = true;
|
||||||
|
while( !mRecordThread.stopped )
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {}
|
||||||
|
}
|
||||||
|
mRecordThread = null;
|
||||||
|
mRecorder.stop();
|
||||||
|
mRecorder.release();
|
||||||
|
mRecorder = null;
|
||||||
|
System.out.println("SDL: app closed recording device");
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RecordingThread extends Thread
|
||||||
|
{
|
||||||
|
public boolean terminate = false;
|
||||||
|
public boolean stopped = false;
|
||||||
|
private byte[] mRecordBuffer;
|
||||||
|
|
||||||
|
RecordingThread(int bufsize)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
mRecordBuffer = new byte[bufsize];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
while( !terminate )
|
||||||
|
{
|
||||||
|
int got = mRecorder.read(mRecordBuffer, 0, mRecordBuffer.length);
|
||||||
|
if( got != mRecordBuffer.length )
|
||||||
|
{
|
||||||
|
System.out.println("SDL: warning: RecordingThread: mRecorder.read returned short byte count " + got + " for bufsize " + mRecordBuffer.length);
|
||||||
|
// TODO: record in a loop?
|
||||||
|
}
|
||||||
|
System.out.println("SDL: nativeAudioRecordCallback with len " + mRecordBuffer.length);
|
||||||
|
nativeAudioRecordCallback(mRecordBuffer);
|
||||||
|
System.out.println("SDL: nativeAudioRecordCallback returned");
|
||||||
|
}
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void nativeAudioRecordCallback(byte[] buffer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
private int recordRead()
|
||||||
|
{
|
||||||
|
mRecordPos += mRecordSize;
|
||||||
|
if( mRecordPos >= mRecordBuffer.length )
|
||||||
|
mRecordPos = 0;
|
||||||
|
mRecorder.read(mRecordBuffer, mRecordPos, mRecordSize);
|
||||||
|
return mRecordPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getRecordBuffer()
|
||||||
|
{
|
||||||
|
return mRecordBuffer;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ AppUsesJoystick=y
|
|||||||
AppUsesAccelerometer=n
|
AppUsesAccelerometer=n
|
||||||
AppUsesGyroscope=y
|
AppUsesGyroscope=y
|
||||||
AppUsesMultitouch=y
|
AppUsesMultitouch=y
|
||||||
|
AppRecordsAudio=y
|
||||||
NonBlockingSwapBuffers=n
|
NonBlockingSwapBuffers=n
|
||||||
RedefinedKeys="SPACE SPACE NO_REMAP NO_REMAP RETURN ESCAPE LCTRL"
|
RedefinedKeys="SPACE SPACE NO_REMAP NO_REMAP RETURN ESCAPE LCTRL"
|
||||||
AppTouchscreenKeyboardKeysAmount=5
|
AppTouchscreenKeyboardKeysAmount=5
|
||||||
@@ -42,8 +43,8 @@ HiddenMenuOptions='OptionalDownloadConfig DisplaySizeConfig'
|
|||||||
FirstStartMenuOptions=''
|
FirstStartMenuOptions=''
|
||||||
MultiABI=y
|
MultiABI=y
|
||||||
AppMinimumRAM=300
|
AppMinimumRAM=300
|
||||||
AppVersionCode=08820
|
AppVersionCode=08821
|
||||||
AppVersionName="0.8.8.20"
|
AppVersionName="0.8.8.21"
|
||||||
ResetSdlConfigForThisVersion=n
|
ResetSdlConfigForThisVersion=n
|
||||||
DeleteFilesOnUpgrade="libsdl-DownloadFinished-10.flag"
|
DeleteFilesOnUpgrade="libsdl-DownloadFinished-10.flag"
|
||||||
CompiledLibraries="sdl_mixer sdl_image freetype curl vorbis ogg"
|
CompiledLibraries="sdl_mixer sdl_image freetype curl vorbis ogg"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ env NO_SHARED_LIBS=1 BUILD_EXECUTABLE=1 V=1 ../setEnvironment-armeabi.sh make -C
|
|||||||
|
|
||||||
../setEnvironment-$1.sh make -j8 -C engine release \
|
../setEnvironment-$1.sh make -j8 -C engine release \
|
||||||
PLATFORM=android ARCH=$1 USE_GLES=1 USE_LOCAL_HEADERS=0 \
|
PLATFORM=android ARCH=$1 USE_GLES=1 USE_LOCAL_HEADERS=0 \
|
||||||
USE_OPENAL=0 USE_CURL=1 USE_CURL_DLOPEN=0 USE_CODEC_VORBIS=1 USE_MUMBLE=0 USE_FREETYPE=1 \
|
USE_OPENAL=0 USE_VOIP=1 USE_CURL=1 USE_CURL_DLOPEN=0 USE_CODEC_VORBIS=1 USE_MUMBLE=0 USE_FREETYPE=1 \
|
||||||
USE_RENDERER_DLOPEN=0 USE_INTERNAL_ZLIB=0 USE_INTERNAL_JPEG=1 BUILD_RENDERER_REND2=0 && \
|
USE_RENDERER_DLOPEN=0 USE_INTERNAL_ZLIB=0 USE_INTERNAL_JPEG=1 BUILD_RENDERER_REND2=0 && \
|
||||||
echo "Copying engine/build/release-android-$1/openarena.$1 -> libapplication-$1.so" && \
|
echo "Copying engine/build/release-android-$1/openarena.$1 -> libapplication-$1.so" && \
|
||||||
cp -f engine/build/release-android-$1/openarena.$1 libapplication-$1.so || exit 1
|
cp -f engine/build/release-android-$1/openarena.$1 libapplication-$1.so || exit 1
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "SDL_video.h"
|
#include "SDL_video.h"
|
||||||
#include "SDL_screenkeyboard.h"
|
#include "SDL_screenkeyboard.h"
|
||||||
|
#include "SDL_audio.h"
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#include "begin_code.h"
|
#include "begin_code.h"
|
||||||
@@ -82,6 +83,18 @@ extern DECLSPEC int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void);
|
|||||||
extern DECLSPEC JNIEnv* SDL_ANDROID_JniEnv();
|
extern DECLSPEC JNIEnv* SDL_ANDROID_JniEnv();
|
||||||
extern DECLSPEC jobject SDL_ANDROID_JniVideoObject();
|
extern DECLSPEC jobject SDL_ANDROID_JniVideoObject();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open audio recording device, it will use parameters freq, format, channels, size and callback,
|
||||||
|
and return internal buffer size on success, which you may ignore,
|
||||||
|
because your callback will always be called with buffer size you specified.
|
||||||
|
Returns 0 on failure (most probably hardware does not support requested audio rate).
|
||||||
|
SDL_Init(SDL_INIT_AUDIO) has to be done before calling this function.
|
||||||
|
*/
|
||||||
|
extern DECLSPEC int SDLCALL SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec);
|
||||||
|
/* Close audio recording device, SDL_Init(SDL_INIT_AUDIO) has to be done before calling this function. */
|
||||||
|
extern DECLSPEC void SDLCALL SDL_ANDROID_CloseAudioRecording(void);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -146,6 +146,12 @@ static jmethodID JavaDeinitAudio = NULL;
|
|||||||
static jmethodID JavaPauseAudioPlayback = NULL;
|
static jmethodID JavaPauseAudioPlayback = NULL;
|
||||||
static jmethodID JavaResumeAudioPlayback = NULL;
|
static jmethodID JavaResumeAudioPlayback = NULL;
|
||||||
|
|
||||||
|
// Audio recording
|
||||||
|
|
||||||
|
static SDL_AudioSpec recording;
|
||||||
|
static jmethodID JavaStartRecording = NULL;
|
||||||
|
static jmethodID JavaStopRecording = NULL;
|
||||||
|
|
||||||
|
|
||||||
static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS)
|
static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS)
|
||||||
{
|
{
|
||||||
@@ -199,7 +205,7 @@ static int ANDROIDAUD_OpenAudio (_THIS, SDL_AudioSpec *spec)
|
|||||||
if( !jniEnv )
|
if( !jniEnv )
|
||||||
{
|
{
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_OpenAudio: Java VM AttachCurrentThread() failed");
|
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_OpenAudio: Java VM AttachCurrentThread() failed");
|
||||||
return (-1); // TODO: enable format conversion? Don't know how to do that in SDL
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The returned audioBufferSize may be huge, up to 100 Kb for 44100 because user may have selected large audio buffer to get rid of choppy sound
|
// The returned audioBufferSize may be huge, up to 100 Kb for 44100 because user may have selected large audio buffer to get rid of choppy sound
|
||||||
@@ -312,6 +318,10 @@ static void ANDROIDAUD_ThreadInit(_THIS)
|
|||||||
|
|
||||||
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_ThreadInit()");
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_ThreadInit()");
|
||||||
SDL_memset(audioBuffer, this->spec.silence, this->spec.size);
|
SDL_memset(audioBuffer, this->spec.silence, this->spec.size);
|
||||||
|
|
||||||
|
// Audio recording
|
||||||
|
JavaStartRecording = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "startRecording", "(IIII)I");
|
||||||
|
JavaStopRecording = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "stopRecording", "()V");
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ANDROIDAUD_ThreadDeinit(_THIS)
|
static void ANDROIDAUD_ThreadDeinit(_THIS)
|
||||||
@@ -322,19 +332,19 @@ static void ANDROIDAUD_ThreadDeinit(_THIS)
|
|||||||
static void ANDROIDAUD_SendAudioToJava(void)
|
static void ANDROIDAUD_SendAudioToJava(void)
|
||||||
{
|
{
|
||||||
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio()");
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio()");
|
||||||
jboolean isCopy = JNI_TRUE;
|
//jboolean isCopy = JNI_TRUE;
|
||||||
|
|
||||||
(*jniEnvPlaying)->ReleaseByteArrayElements(jniEnvPlaying, audioBufferJNI, (jbyte *)audioBuffer, 0);
|
(*jniEnvPlaying)->ReleaseByteArrayElements(jniEnvPlaying, audioBufferJNI, (jbyte *)audioBuffer, 0);
|
||||||
audioBuffer = NULL;
|
audioBuffer = NULL;
|
||||||
|
|
||||||
(*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaFillBuffer );
|
(*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaFillBuffer );
|
||||||
|
|
||||||
audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, &isCopy);
|
audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, NULL);
|
||||||
if( !audioBuffer )
|
if( !audioBuffer )
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_PlayAudio() JNI::GetByteArrayElements() failed! we will crash now");
|
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_PlayAudio() JNI::GetByteArrayElements() failed! we will crash now");
|
||||||
|
|
||||||
if( isCopy == JNI_TRUE )
|
//if( isCopy == JNI_TRUE )
|
||||||
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio() JNI returns a copy of byte array - that's slow");
|
// __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio() JNI returns a copy of byte array - that's slow");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDL_AUDIO_APP_IGNORES_RETURNED_BUFFER_SIZE
|
#ifdef SDL_AUDIO_APP_IGNORES_RETURNED_BUFFER_SIZE
|
||||||
@@ -403,3 +413,51 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
|
|||||||
jniVM = vm;
|
jniVM = vm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----- Audio recording -----
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL JAVA_EXPORT_NAME(AudioThread_nativeAudioRecordCallback) (JNIEnv * jniEnv, jobject thiz, jbyteArray jbuffer)
|
||||||
|
{
|
||||||
|
int len = (*jniEnv)->GetArrayLength(jniEnv, jbuffer);
|
||||||
|
Uint8 *buffer = (Uint8 *) (*jniEnv)->GetByteArrayElements(jniEnv, jbuffer, NULL);
|
||||||
|
if( !buffer )
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "AudioThread_nativeAudioRecordCallbacks() JNI::GetByteArrayElements() failed! we will crash now");
|
||||||
|
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "libSDL", "AudioThread_nativeAudioRecordCallbacks(): got buffer %p len %d", buffer, len);
|
||||||
|
|
||||||
|
recording.callback(recording.userdata, buffer, len);
|
||||||
|
|
||||||
|
(*jniEnv)->ReleaseByteArrayElements(jniEnv, jbuffer, (jbyte *)buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern DECLSPEC int SDLCALL SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec)
|
||||||
|
{
|
||||||
|
JNIEnv * jniEnv = NULL;
|
||||||
|
|
||||||
|
recording = *spec;
|
||||||
|
|
||||||
|
if( ! (recording.format == AUDIO_S8 || recording.format == AUDIO_S16) )
|
||||||
|
{
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "Application requested unsupported audio format - only S8 and S16 are supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! recording.callback )
|
||||||
|
{
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "Application did not provide callback");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL);
|
||||||
|
|
||||||
|
return (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaStartRecording, (jint)recording.freq, (jint)recording.channels,
|
||||||
|
(jint)(recording.format == AUDIO_S16 ? 1 : 0), (jint)recording.size );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern DECLSPEC void SDLCALL SDL_ANDROID_CloseAudioRecording(void)
|
||||||
|
{
|
||||||
|
JNIEnv * jniEnv = NULL;
|
||||||
|
|
||||||
|
(*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL);
|
||||||
|
|
||||||
|
(*jniEnv)->CallVoidMethod( jniEnv, JavaAudioThread, JavaStopRecording );
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user