Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libSDL
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
libSDL
Commits
4f9db82a
Commit
4f9db82a
authored
Jan 13, 2011
by
Sam Lantinga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working audio implementation contributed by Joseph Lunderville
parent
a409f985
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
287 additions
and
144 deletions
+287
-144
SDLActivity.java
android-project/src/org/libsdl/app/SDLActivity.java
+82
-17
SDL_android.cpp
src/SDL_android.cpp
+122
-74
SDL_android.h
src/SDL_android.h
+6
-1
SDL_androidaudio.c
src/audio/android/SDL_androidaudio.c
+76
-50
SDL_androidaudio.h
src/audio/android/SDL_androidaudio.h
+1
-2
No files found.
android-project/src/org/libsdl/app/SDLActivity.java
View file @
4f9db82a
...
@@ -29,11 +29,15 @@ public class SDLActivity extends Activity {
...
@@ -29,11 +29,15 @@ public class SDLActivity extends Activity {
private
static
SDLSurface
mSurface
;
private
static
SDLSurface
mSurface
;
// Audio
// Audio
private
static
Thread
mAudioThread
;
private
static
AudioTrack
mAudioTrack
;
private
static
AudioTrack
mAudioTrack
;
// Load the .so
// Load the .so
static
{
static
{
System
.
loadLibrary
(
"SDL"
);
System
.
loadLibrary
(
"SDL"
);
//System.loadLibrary("SDL_image");
//System.loadLibrary("SDL_mixer");
//System.loadLibrary("SDL_ttf");
System
.
loadLibrary
(
"main"
);
System
.
loadLibrary
(
"main"
);
}
}
...
@@ -67,12 +71,13 @@ public class SDLActivity extends Activity {
...
@@ -67,12 +71,13 @@ public class SDLActivity extends Activity {
// C functions we call
// C functions we call
public
static
native
void
nativeInit
();
public
static
native
void
nativeInit
();
public
static
native
void
nativeQuit
();
public
static
native
void
nativeQuit
();
public
static
native
void
onNativeResize
(
int
x
,
int
y
,
int
format
);
public
static
native
void
onNativeKeyDown
(
int
keycode
);
public
static
native
void
onNativeKeyDown
(
int
keycode
);
public
static
native
void
onNativeKeyUp
(
int
keycode
);
public
static
native
void
onNativeKeyUp
(
int
keycode
);
public
static
native
void
onNativeTouch
(
int
action
,
float
x
,
public
static
native
void
onNativeTouch
(
int
action
,
float
x
,
float
y
,
float
p
);
float
y
,
float
p
);
public
static
native
void
onNativeResize
(
int
x
,
int
y
,
int
format
);
public
static
native
void
onNativeAccel
(
float
x
,
float
y
,
float
z
);
public
static
native
void
onNativeAccel
(
float
x
,
float
y
,
float
z
);
public
static
native
void
nativeRunAudioThread
();
// Java functions called from C
// Java functions called from C
...
@@ -84,23 +89,83 @@ public class SDLActivity extends Activity {
...
@@ -84,23 +89,83 @@ public class SDLActivity extends Activity {
mSurface
.
flipEGL
();
mSurface
.
flipEGL
();
}
}
public
static
void
updateAudio
(
byte
[]
buf
)
{
// Audio
private
static
Object
buf
;
if
(
mAudioTrack
==
null
)
{
public
static
Object
audioInit
(
int
sampleRate
,
boolean
is16Bit
,
boolean
isStereo
,
int
desiredFrames
)
{
// Hardcoded things are bad. FIXME when we have more sound stuff
int
channelConfig
=
isStereo
?
AudioFormat
.
CHANNEL_CONFIGURATION_STEREO
:
AudioFormat
.
CHANNEL_CONFIGURATION_MONO
;
// working properly.
int
audioFormat
=
is16Bit
?
AudioFormat
.
ENCODING_PCM_16BIT
:
AudioFormat
.
ENCODING_PCM_8BIT
;
mAudioTrack
=
new
AudioTrack
(
AudioManager
.
STREAM_MUSIC
,
int
frameSize
=
(
isStereo
?
2
:
1
)
*
(
is16Bit
?
2
:
1
);
11025
,
AudioFormat
.
CHANNEL_CONFIGURATION_MONO
,
Log
.
v
(
"SDL"
,
"SDL audio: wanted "
+
(
isStereo
?
"stereo"
:
"mono"
)
+
" "
+
(
is16Bit
?
"16-bit"
:
"8-bit"
)
+
" "
+
((
float
)
sampleRate
/
1000
f
)
+
"kHz, "
+
desiredFrames
+
" frames buffer"
);
AudioFormat
.
ENCODING_PCM_8BIT
,
2048
,
// Let the user pick a larger buffer if they really want -- but ye
AudioTrack
.
MODE_STREAM
);
// gods they probably shouldn't, the minimums are horrifyingly high
// latency already
desiredFrames
=
Math
.
max
(
desiredFrames
,
(
AudioTrack
.
getMinBufferSize
(
sampleRate
,
channelConfig
,
audioFormat
)
+
frameSize
-
1
)
/
frameSize
);
mAudioTrack
=
new
AudioTrack
(
AudioManager
.
STREAM_MUSIC
,
sampleRate
,
channelConfig
,
audioFormat
,
desiredFrames
*
frameSize
,
AudioTrack
.
MODE_STREAM
);
audioStartThread
();
Log
.
v
(
"SDL"
,
"SDL audio: got "
+
((
mAudioTrack
.
getChannelCount
()
>=
2
)
?
"stereo"
:
"mono"
)
+
" "
+
((
mAudioTrack
.
getAudioFormat
()
==
AudioFormat
.
ENCODING_PCM_16BIT
)
?
"16-bit"
:
"8-bit"
)
+
" "
+
((
float
)
mAudioTrack
.
getSampleRate
()
/
1000
f
)
+
"kHz, "
+
desiredFrames
+
" frames buffer"
);
if
(
is16Bit
)
{
buf
=
new
short
[
desiredFrames
*
(
isStereo
?
2
:
1
)];
}
else
{
buf
=
new
byte
[
desiredFrames
*
(
isStereo
?
2
:
1
)];
}
}
return
buf
;
mAudioTrack
.
write
(
buf
,
0
,
buf
.
length
);
}
mAudioTrack
.
play
();
public
static
void
audioStartThread
()
{
mAudioThread
=
new
Thread
(
new
Runnable
()
{
public
void
run
()
{
mAudioTrack
.
play
();
nativeRunAudioThread
();
}
});
Log
.
v
(
"SDL"
,
"Played some audio"
);
// I'd take REALTIME if I could get it!
mAudioThread
.
setPriority
(
Thread
.
MAX_PRIORITY
);
mAudioThread
.
start
();
}
public
static
void
audioWriteShortBuffer
(
short
[]
buffer
)
{
for
(
int
i
=
0
;
i
<
buffer
.
length
;
)
{
int
result
=
mAudioTrack
.
write
(
buffer
,
i
,
buffer
.
length
-
i
);
if
(
result
>
0
)
{
i
+=
result
;
}
else
if
(
result
==
0
)
{
try
{
Thread
.
sleep
(
10
);
}
catch
(
InterruptedException
e
)
{
// Nom nom
}
}
else
{
Log
.
w
(
"SDL"
,
"SDL audio: error return from write(short)"
);
return
;
}
}
}
public
static
void
audioWriteByteBuffer
(
byte
[]
buffer
)
{
for
(
int
i
=
0
;
i
<
buffer
.
length
;
)
{
int
result
=
mAudioTrack
.
write
(
buffer
,
i
,
buffer
.
length
-
i
);
if
(
result
>
0
)
{
i
+=
result
;
}
else
if
(
result
==
0
)
{
try
{
Thread
.
sleep
(
10
);
}
catch
(
InterruptedException
e
)
{
// Nom nom
}
}
else
{
Log
.
w
(
"SDL"
,
"SDL audio: error return from write(short)"
);
return
;
}
}
}
}
}
}
...
@@ -279,7 +344,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
...
@@ -279,7 +344,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
v
(
"SDL"
,
e
+
""
);
Log
.
v
(
"SDL"
,
e
+
""
);
for
(
StackTraceElement
s
:
e
.
getStackTrace
())
{
for
(
StackTraceElement
s
:
e
.
getStackTrace
())
{
Log
.
v
(
"SDL"
,
s
.
toString
());
Log
.
v
(
"SDL"
,
s
.
toString
());
}
}
}
}
...
@@ -303,7 +368,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
...
@@ -303,7 +368,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
v
(
"SDL"
,
"flipEGL(): "
+
e
);
Log
.
v
(
"SDL"
,
"flipEGL(): "
+
e
);
for
(
StackTraceElement
s
:
e
.
getStackTrace
())
{
for
(
StackTraceElement
s
:
e
.
getStackTrace
())
{
Log
.
v
(
"SDL"
,
s
.
toString
());
Log
.
v
(
"SDL"
,
s
.
toString
());
}
}
}
}
...
...
src/SDL_android.cpp
View file @
4f9db82a
...
@@ -27,7 +27,10 @@ extern "C" {
...
@@ -27,7 +27,10 @@ extern "C" {
#include "events/SDL_events_c.h"
#include "events/SDL_events_c.h"
#include "video/android/SDL_androidkeyboard.h"
#include "video/android/SDL_androidkeyboard.h"
#include "video/android/SDL_androidvideo.h"
#include "video/android/SDL_androidvideo.h"
}
/* Impelemented in audio/android/SDL_androidaudio.c */
extern
void
Android_RunAudioThread
();
}
// C
/*******************************************************************************
/*******************************************************************************
This file links the Java side of Android with libsdl
This file links the Java side of Android with libsdl
...
@@ -39,23 +42,21 @@ extern "C" {
...
@@ -39,23 +42,21 @@ extern "C" {
/*******************************************************************************
/*******************************************************************************
Globals
Globals
*******************************************************************************/
*******************************************************************************/
JavaVM
*
mVM
=
NULL
;
static
JavaVM
*
mVM
=
NULL
;
JNIEnv
*
mEnv
=
NULL
;
static
JNIEnv
*
mEnv
=
NULL
;
JNIEnv
*
mAudioThreadEnv
=
NULL
;
//See the note below for why this is necessary
static
JNIEnv
*
mAudioEnv
=
NULL
;
//Main activity
//
Main activity
jclass
mActivityInstance
;
static
jclass
mActivityInstance
;
//method signatures
// method signatures
jmethodID
midCreateGLContext
;
static
jmethodID
midCreateGLContext
;
jmethodID
midFlipBuffers
;
static
jmethodID
midFlipBuffers
;
jmethodID
midUpdateAudio
;
static
jmethodID
midAudioInit
;
static
jmethodID
midAudioWriteShortBuffer
;
static
jmethodID
midAudioWriteByteBuffer
;
//Feature IDs
// Accelerometer data storage
static
const
int
FEATURE_AUDIO
=
1
;
static
const
int
FEATURE_ACCEL
=
2
;
//Accelerometer data storage
float
fLastAccelerometer
[
3
];
float
fLastAccelerometer
[
3
];
...
@@ -82,42 +83,42 @@ extern "C" void SDL_Android_Init(JNIEnv* env)
...
@@ -82,42 +83,42 @@ extern "C" void SDL_Android_Init(JNIEnv* env)
mActivityInstance
=
cls
;
mActivityInstance
=
cls
;
midCreateGLContext
=
mEnv
->
GetStaticMethodID
(
cls
,
"createGLContext"
,
"()V"
);
midCreateGLContext
=
mEnv
->
GetStaticMethodID
(
cls
,
"createGLContext"
,
"()V"
);
midFlipBuffers
=
mEnv
->
GetStaticMethodID
(
cls
,
"flipBuffers"
,
"()V"
);
midFlipBuffers
=
mEnv
->
GetStaticMethodID
(
cls
,
"flipBuffers"
,
"()V"
);
midUpdateAudio
=
mEnv
->
GetStaticMethodID
(
cls
,
"updateAudio"
,
"([B)V"
);
midAudioInit
=
mEnv
->
GetStaticMethodID
(
cls
,
"audioInit"
,
"(IZZI)Ljava/lang/Object;"
);
midAudioWriteShortBuffer
=
mEnv
->
GetStaticMethodID
(
cls
,
"audioWriteShortBuffer"
,
"([S)V"
);
midAudioWriteByteBuffer
=
mEnv
->
GetStaticMethodID
(
cls
,
"audioWriteByteBuffer"
,
"([B)V"
);
if
(
!
midCreateGLContext
||
!
midFlipBuffers
||
!
midUpdateAudio
)
{
if
(
!
midCreateGLContext
||
!
midFlipBuffers
||
!
midAudioInit
||
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: Bad mids
\n
"
);
!
midAudioWriteShortBuffer
||
!
midAudioWriteByteBuffer
)
{
}
else
{
__android_log_print
(
ANDROID_LOG_WARN
,
"SDL"
,
"SDL: Couldn't locate Java callbacks, check that they're named and typed correctly"
);
#ifdef DEBUG
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: Good mids
\n
"
);
#endif
}
}
}
}
// Resize
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeResize
(
JNIEnv
*
env
,
jobject
obj
,
jint
width
,
jint
height
,
jint
format
)
{
Android_SetScreenResolution
(
width
,
height
,
format
);
}
// Keydown
// Keydown
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeKeyDown
(
JNIEnv
*
env
,
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeKeyDown
(
jobject
obj
,
jint
keycode
)
JNIEnv
*
env
,
jobject
obj
,
jint
keycode
)
{
{
#ifdef DEBUG
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: native key down %d
\n
"
,
keycode
);
#endif
Android_OnKeyDown
(
keycode
);
Android_OnKeyDown
(
keycode
);
}
}
// Keyup
// Keyup
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeKeyUp
(
JNIEnv
*
env
,
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeKeyUp
(
jobject
obj
,
jint
keycode
)
JNIEnv
*
env
,
jobject
obj
,
jint
keycode
)
{
{
#ifdef DEBUG
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: native key up %d
\n
"
,
keycode
);
#endif
Android_OnKeyUp
(
keycode
);
Android_OnKeyUp
(
keycode
);
}
}
// Touch
// Touch
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeTouch
(
JNIEnv
*
env
,
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeTouch
(
jobject
obj
,
jint
action
,
jfloat
x
,
jfloat
y
,
jfloat
p
)
JNIEnv
*
env
,
jobject
obj
,
jint
action
,
jfloat
x
,
jfloat
y
,
jfloat
p
)
{
{
#ifdef DEBUG
#ifdef DEBUG
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
...
@@ -128,32 +129,31 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env,
...
@@ -128,32 +129,31 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env,
//TODO: Pass this off to the SDL multitouch stuff
//TODO: Pass this off to the SDL multitouch stuff
}
}
// Accelerometer
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeAccel
(
JNIEnv
*
env
,
jobject
obj
,
jfloat
x
,
jfloat
y
,
jfloat
z
)
{
fLastAccelerometer
[
0
]
=
x
;
fLastAccelerometer
[
1
]
=
y
;
fLastAccelerometer
[
2
]
=
z
;
}
// Quit
// Quit
extern
"C"
void
Java_org_libsdl_app_SDLActivity_nativeQuit
(
JNIEnv
*
env
,
extern
"C"
void
Java_org_libsdl_app_SDLActivity_nativeQuit
(
jobject
obj
)
JNIEnv
*
env
,
jobject
obj
)
{
{
// Inject a SDL_QUIT event
// Inject a SDL_QUIT event
SDL_SendQuit
();
SDL_SendQuit
();
}
}
// Resize
extern
"C"
void
Java_org_libsdl_app_SDLActivity_nativeRunAudioThread
(
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeResize
(
JNIEnv
*
env
)
JNIEnv
*
env
,
jobject
obj
,
jint
width
,
jint
height
,
jint
format
)
{
{
Android_SetScreenResolution
(
width
,
height
,
format
);
mVM
->
AttachCurrentThread
(
&
mAudioEnv
,
NULL
);
Android_RunAudioThread
();
}
}
extern
"C"
void
Java_org_libsdl_app_SDLActivity_onNativeAccel
(
JNIEnv
*
env
,
jobject
obj
,
jfloat
x
,
jfloat
y
,
jfloat
z
)
{
fLastAccelerometer
[
0
]
=
x
;
fLastAccelerometer
[
1
]
=
y
;
fLastAccelerometer
[
2
]
=
z
;
}
/*******************************************************************************
/*******************************************************************************
Functions called by SDL into Java
Functions called by SDL into Java
...
@@ -168,33 +168,81 @@ extern "C" void Android_JNI_SwapWindow()
...
@@ -168,33 +168,81 @@ extern "C" void Android_JNI_SwapWindow()
mEnv
->
CallStaticVoidMethod
(
mActivityInstance
,
midFlipBuffers
);
mEnv
->
CallStaticVoidMethod
(
mActivityInstance
,
midFlipBuffers
);
}
}
extern
"C"
void
Android_JNI_UpdateAudioBuffer
(
unsigned
char
*
buf
,
int
len
)
//
// Audio support
//
static
jint
audioBufferFrames
=
0
;
static
bool
audioBuffer16Bit
=
false
;
static
bool
audioBufferStereo
=
false
;
static
jobject
audioBuffer
;
static
void
*
audioPinnedBuffer
;
extern
"C"
int
Android_JNI_OpenAudioDevice
(
int
sampleRate
,
int
is16Bit
,
int
channelCount
,
int
desiredBufferFrames
)
{
{
//Annoyingly we can't just call into Java from any thread. Because the audio
__android_log_print
(
ANDROID_LOG_VERBOSE
,
"SDL"
,
"SDL audio: opening device"
);
//callback is dispatched from the SDL audio thread (that wasn't made from
audioBuffer16Bit
=
is16Bit
;
//java, we have to do some magic here to let the JVM know about the thread.
audioBufferStereo
=
channelCount
>
1
;
//Because everything it touches on the Java side is static anyway, it's
//not a big deal, just annoying.
if
(
!
mAudioThreadEnv
)
{
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: Need to set up audio thread env
\n
"
);
mVM
->
AttachCurrentThread
(
&
mAudioThreadEnv
,
NULL
);
audioBuffer
=
mEnv
->
CallStaticObjectMethod
(
mActivityInstance
,
midAudioInit
,
sampleRate
,
audioBuffer16Bit
,
audioBufferStereo
,
desiredBufferFrames
);
audioBuffer
=
mEnv
->
NewGlobalRef
(
audioBuffer
);
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: ok
\n
"
);
if
(
audioBuffer
==
NULL
)
{
}
__android_log_print
(
ANDROID_LOG_WARN
,
"SDL"
,
"SDL audio: didn't get back a good audio buffer!"
);
return
0
;
jbyteArray
arr
=
mAudioThreadEnv
->
NewByteArray
(
len
);
}
//blah. We probably should rework this so we avoid the copy.
if
(
audioBufferStereo
)
{
mAudioThreadEnv
->
SetByteArrayRegion
(
arr
,
0
,
len
,
(
jbyte
*
)
buf
);
audioBufferFrames
=
mEnv
->
GetArrayLength
((
jshortArray
)
audioBuffer
)
/
2
;
}
else
{
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: copied
\n
"
);
audioBufferFrames
=
mEnv
->
GetArrayLength
((
jbyteArray
)
audioBuffer
);
}
mAudioThreadEnv
->
CallStaticVoidMethod
(
mActivityInstance
,
return
audioBufferFrames
;
midUpdateAudio
,
arr
);
}
extern
"C"
void
*
Android_JNI_PinAudioBuffer
()
{
jboolean
isCopy
=
JNI_FALSE
;
if
(
audioPinnedBuffer
!=
NULL
)
{
return
audioPinnedBuffer
;
}
if
(
audioBuffer16Bit
)
{
audioPinnedBuffer
=
mAudioEnv
->
GetShortArrayElements
((
jshortArray
)
audioBuffer
,
&
isCopy
);
}
else
{
audioPinnedBuffer
=
mAudioEnv
->
GetByteArrayElements
((
jbyteArray
)
audioBuffer
,
&
isCopy
);
}
return
audioPinnedBuffer
;
}
extern
"C"
void
Android_JNI_WriteAudioBufferAndUnpin
()
{
if
(
audioPinnedBuffer
==
NULL
)
{
return
;
}
if
(
audioBuffer16Bit
)
{
mAudioEnv
->
ReleaseShortArrayElements
((
jshortArray
)
audioBuffer
,
(
jshort
*
)
audioPinnedBuffer
,
JNI_COMMIT
);
mAudioEnv
->
CallStaticVoidMethod
(
mActivityInstance
,
midAudioWriteShortBuffer
,
(
jshortArray
)
audioBuffer
);
}
else
{
mAudioEnv
->
ReleaseByteArrayElements
((
jbyteArray
)
audioBuffer
,
(
jbyte
*
)
audioPinnedBuffer
,
JNI_COMMIT
);
mAudioEnv
->
CallStaticVoidMethod
(
mActivityInstance
,
midAudioWriteByteBuffer
,
(
jbyteArray
)
audioBuffer
);
}
audioPinnedBuffer
=
NULL
;
}
extern
"C"
void
Android_JNI_CloseAudioDevice
()
{
if
(
audioBuffer
)
{
mEnv
->
DeleteGlobalRef
(
audioBuffer
);
audioBuffer
=
NULL
;
}
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"SDL: invoked
\n
"
);
// TODO: Implement
}
}
/* vi: set ts=4 sw=4 expandtab: */
/* vi: set ts=4 sw=4 expandtab: */
src/SDL_android.h
View file @
4f9db82a
...
@@ -31,7 +31,12 @@ extern "C" {
...
@@ -31,7 +31,12 @@ extern "C" {
/* Interface from the SDL library into the Android Java activity */
/* Interface from the SDL library into the Android Java activity */
void
Android_JNI_CreateContext
();
void
Android_JNI_CreateContext
();
void
Android_JNI_SwapWindow
();
void
Android_JNI_SwapWindow
();
void
Android_JNI_UpdateAudioBuffer
(
unsigned
char
*
buf
,
int
len
);
// Audio support
int
Android_JNI_OpenAudioDevice
(
int
sampleRate
,
int
is16Bit
,
int
channelCount
,
int
desiredBufferFrames
);
void
*
Android_JNI_PinAudioBuffer
();
void
Android_JNI_WriteAudioBufferAndUnpin
();
void
Android_JNI_CloseAudioDevice
();
/* Ends C function definitions when using C++ */
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
#ifdef __cplusplus
...
...
src/audio/android/SDL_androidaudio.c
View file @
4f9db82a
...
@@ -18,8 +18,6 @@
...
@@ -18,8 +18,6 @@
Sam Lantinga
Sam Lantinga
slouken@libsdl.org
slouken@libsdl.org
This file written by Ryan C. Gordon (icculus@icculus.org)
*/
*/
#include "SDL_config.h"
#include "SDL_config.h"
...
@@ -28,18 +26,31 @@
...
@@ -28,18 +26,31 @@
#include "SDL_audio.h"
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "../SDL_audio_c.h"
#include "SDL_androidaudio.h"
#include "SDL_androidaudio.h"
#include "../../SDL_android.h"
#include "../../SDL_android.h"
#include <android/log.h>
#include <android/log.h>
static
void
*
audioDevice
;
static
int
static
int
AndroidAUD_OpenDevice
(
_THIS
,
const
char
*
devname
,
int
iscapture
)
AndroidAUD_OpenDevice
(
_THIS
,
const
char
*
devname
,
int
iscapture
)
{
{
SDL_AudioFormat
test_format
=
SDL_FirstAudioFormat
(
this
->
spec
.
format
)
;
SDL_AudioFormat
test_format
;
int
valid_datatype
=
0
;
int
valid_datatype
=
0
;
//TODO: Sample rates etc
if
(
iscapture
)
{
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"AndroidAudio Open
\n
"
);
//TODO: implement capture
SDL_SetError
(
"Capture not supported on Android"
);
return
0
;
}
if
(
audioDevice
!=
NULL
)
{
SDL_SetError
(
"Only one audio device at a time please!"
);
return
0
;
}
audioDevice
=
this
;
this
->
hidden
=
SDL_malloc
(
sizeof
(
*
(
this
->
hidden
)));
this
->
hidden
=
SDL_malloc
(
sizeof
(
*
(
this
->
hidden
)));
if
(
!
this
->
hidden
)
{
if
(
!
this
->
hidden
)
{
...
@@ -48,68 +59,78 @@ AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
...
@@ -48,68 +59,78 @@ AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
}
}
SDL_memset
(
this
->
hidden
,
0
,
(
sizeof
*
this
->
hidden
));
SDL_memset
(
this
->
hidden
,
0
,
(
sizeof
*
this
->
hidden
));
while
((
!
valid_datatype
)
&&
(
test_format
))
{
test_format
=
SDL_FirstAudioFormat
(
this
->
spec
.
format
);
this
->
spec
.
format
=
test_format
;
while
(
test_format
!=
0
)
{
// no "UNKNOWN" constant
switch
(
test_format
)
{
if
((
test_format
==
AUDIO_U8
)
||
(
test_format
==
AUDIO_S16LSB
))
{
case
AUDIO_S8
:
this
->
spec
.
format
=
test_format
;
/*case AUDIO_S16LSB: */
valid_datatype
=
1
;
break
;
default:
test_format
=
SDL_NextAudioFormat
();
break
;
break
;
}
}
test_format
=
SDL_NextAudioFormat
();
}
}
if
(
test_format
==
0
)
{
// Didn't find a compatible format :(
SDL_SetError
(
"No compatible audio format!"
);
return
0
;
}
if
(
this
->
spec
.
channels
>
1
)
{
this
->
spec
.
channels
=
2
;
}
else
{
this
->
spec
.
channels
=
1
;
}
if
(
this
->
spec
.
freq
<
8000
)
{
this
->
spec
.
freq
=
8000
;
}
if
(
this
->
spec
.
freq
>
48000
)
{
this
->
spec
.
freq
=
48000
;
}
// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
this
->
spec
.
samples
=
Android_JNI_OpenAudioDevice
(
this
->
spec
.
freq
,
this
->
spec
.
format
==
AUDIO_U8
?
0
:
1
,
this
->
spec
.
channels
,
this
->
spec
.
samples
);
SDL_CalculateAudioSpec
(
&
this
->
spec
);
if
(
this
->
spec
.
samples
==
0
)
{
// Init failed?
SDL_SetError
(
"Java-side initialization failed!"
);
return
0
;
}
return
1
;
return
1
;
}
}
static
void
static
void
AndroidAUD_PlayDevice
(
_THIS
)
AndroidAUD_PlayDevice
(
_THIS
)
{
{
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"AndroidAudio Play
\n
"
);
Android_JNI_WriteAudioBufferAndUnpin
();
this
->
hidden
->
mixbuf
=
NULL
;
//playGenericSound(this->hidden->mixbuf, this->hidden->mixlen);
#if 0
// sound->rate = 22050; /* sample rate = 22050Hz */
// sound->vol = 127; /* volume [0..127] for [min..max] */
// sound->pan = 64; /* balance [0..127] for [left..right] */
// sound->format = 0; /* 0 for 16-bit, 1 for 8-bit */
// playSound(sound);
#endif
}
}
static
Uint8
*
static
Uint8
*
AndroidAUD_GetDeviceBuf
(
_THIS
)
AndroidAUD_GetDeviceBuf
(
_THIS
)
{
{
//__android_log_print(ANDROID_LOG_INFO, "SDL", "****** get device buf\n");
if
(
this
->
hidden
->
mixbuf
==
NULL
)
{
this
->
hidden
->
mixbuf
=
Android_JNI_PinAudioBuffer
();
}
// sound->data = this->hidden->mixbuf;/* pointer to raw audio data */
return
this
->
hidden
->
mixbuf
;
// sound->len = this->hidden->mixlen; /* size of raw data pointed to above */
Android_JNI_UpdateAudioBuffer
(
this
->
hidden
->
mixbuf
,
this
->
hidden
->
mixlen
);
return
this
->
hidden
->
mixbuf
;
/* is this right? */
}
static
void
AndroidAUD_WaitDevice
(
_THIS
)
{
/* stub */
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"****** wait device buf
\n
"
);
}
}
static
void
static
void
AndroidAUD_CloseDevice
(
_THIS
)
AndroidAUD_CloseDevice
(
_THIS
)
{
{
/* stub */
if
(
this
->
hidden
!=
NULL
)
{
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"****** close device buf
\n
"
);
if
(
this
->
hidden
->
mixbuf
!=
NULL
)
{
Android_JNI_WriteAudioBufferAndUnpin
();
}
SDL_free
(
this
->
hidden
);
this
->
hidden
=
NULL
;
}
Android_JNI_CloseAudioDevice
();
if
(
audioDevice
==
this
)
{
audioDevice
=
NULL
;
}
}
}
static
int
static
int
...
@@ -118,17 +139,15 @@ AndroidAUD_Init(SDL_AudioDriverImpl * impl)
...
@@ -118,17 +139,15 @@ AndroidAUD_Init(SDL_AudioDriverImpl * impl)
/* Set the function pointers */
/* Set the function pointers */
impl
->
OpenDevice
=
AndroidAUD_OpenDevice
;
impl
->
OpenDevice
=
AndroidAUD_OpenDevice
;
impl
->
PlayDevice
=
AndroidAUD_PlayDevice
;
impl
->
PlayDevice
=
AndroidAUD_PlayDevice
;
impl
->
WaitDevice
=
AndroidAUD_WaitDevice
;
impl
->
GetDeviceBuf
=
AndroidAUD_GetDeviceBuf
;
impl
->
GetDeviceBuf
=
AndroidAUD_GetDeviceBuf
;
impl
->
CloseDevice
=
AndroidAUD_CloseDevice
;
impl
->
CloseDevice
=
AndroidAUD_CloseDevice
;
/* and the capabilities */
/* and the capabilities */
impl
->
ProvidesOwnCallbackThread
=
1
;
impl
->
HasCaptureSupport
=
0
;
//TODO
impl
->
HasCaptureSupport
=
0
;
//TODO
impl
->
OnlyHasDefaultOutputDevice
=
1
;
impl
->
OnlyHasDefaultOutputDevice
=
1
;
impl
->
OnlyHasDefaultInputDevice
=
1
;
impl
->
OnlyHasDefaultInputDevice
=
1
;
__android_log_print
(
ANDROID_LOG_INFO
,
"SDL"
,
"Audio init
\n
"
);
return
1
;
/* this audio target is available. */
return
1
;
/* this audio target is available. */
}
}
...
@@ -136,4 +155,11 @@ AudioBootStrap ANDROIDAUD_bootstrap = {
...
@@ -136,4 +155,11 @@ AudioBootStrap ANDROIDAUD_bootstrap = {
"android"
,
"SDL Android audio driver"
,
AndroidAUD_Init
,
0
/*1? */
"android"
,
"SDL Android audio driver"
,
AndroidAUD_Init
,
0
/*1? */
};
};
/* Called by the Java code to start the audio processing on a thread */
void
Android_RunAudioThread
()
{
SDL_RunAudio
(
audioDevice
);
}
/* vi: set ts=4 sw=4 expandtab: */
/* vi: set ts=4 sw=4 expandtab: */
src/audio/android/SDL_androidaudio.h
View file @
4f9db82a
...
@@ -34,9 +34,8 @@ struct SDL_PrivateAudioData
...
@@ -34,9 +34,8 @@ struct SDL_PrivateAudioData
/* The file descriptor for the audio device */
/* The file descriptor for the audio device */
Uint8
*
mixbuf
;
Uint8
*
mixbuf
;
Uint32
mixlen
;
Uint32
mixlen
;
Uint32
write_delay
;
Uint32
initial_calls
;
};
};
#endif
/* _SDL_androidaudio_h */
#endif
/* _SDL_androidaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
/* vi: set ts=4 sw=4 expandtab: */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment