Add more AudioTrack APIs needed for exoplayer.

Also fix compiler warnings
This commit is contained in:
Julian Winkler
2023-10-08 16:16:36 +02:00
parent b340032e9f
commit f4251af2a2
3 changed files with 64 additions and 17 deletions

View File

@@ -42,8 +42,8 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1constructor(JNIEnv
snd_pcm_t *pcm_handle; snd_pcm_t *pcm_handle;
snd_pcm_hw_params_t *params; snd_pcm_hw_params_t *params;
jint channels_out; unsigned int channels_out;
jint period_time; unsigned int period_time;
int ret; int ret;
@@ -158,7 +158,7 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_getMinBufferSize(JNIEnv *en
if((*env)->ExceptionCheck(env)) if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env); (*env)->ExceptionDescribe(env);
printf("\n\nJava_android_media_AudioTrack_getMinBufferSize is returning: %d\n\n\n", frames * num_channels * 2); printf("\n\nJava_android_media_AudioTrack_getMinBufferSize is returning: %ld\n\n\n", frames * num_channels * 2);
return frames * num_channels * 2; // FIXME: 2 bytes = 16 bits (s16) return frames * num_channels * 2; // FIXME: 2 bytes = 16 bits (s16)
} }
@@ -197,11 +197,8 @@ void periodic_update_callback(snd_async_handler_t *pcm_callback)
// return G_SOURCE_REMOVE; // return G_SOURCE_REMOVE;
} }
JNIEXPORT void JNICALL Java_android_media_AudioTrack_play(JNIEnv *env, jobject this) JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1play(JNIEnv *env, jobject this)
{ {
pthread_t periodic_notification_thread;
int ret;
jint period_time = _GET_INT_FIELD(this, "period_time"); jint period_time = _GET_INT_FIELD(this, "period_time");
// FIXME - this callback should probably be set up elsewhere // FIXME - this callback should probably be set up elsewhere
@@ -229,17 +226,15 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_play(JNIEnv *env, jobject t
/*--↑*/ /*--↑*/
} }
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_write(JNIEnv *env, jobject this, jbyteArray audioData, jint offsetInBytes, jint sizeInBytes) JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1write(JNIEnv *env, jobject this, jbyteArray audioData, jint offsetInBytes, jint frames_to_write)
{ {
int ret; int ret;
if(!PCM_DEVICE) if(!PCM_DEVICE)
return 0; // STUB return 0; // STUB
jint channels = _GET_INT_FIELD(this, "channels");
snd_pcm_t *pcm_handle = _PTR(_GET_LONG_FIELD(this, "pcm_handle")); snd_pcm_t *pcm_handle = _PTR(_GET_LONG_FIELD(this, "pcm_handle"));
snd_pcm_sframes_t frames_to_write = sizeInBytes / channels / 2; // FIXME - 2 means PCM16
snd_pcm_sframes_t frames_written; snd_pcm_sframes_t frames_written;
jbyte *buffer = _GET_BYTE_ARRAY_ELEMENTS(audioData); jbyte *buffer = _GET_BYTE_ARRAY_ELEMENTS(audioData);
@@ -257,4 +252,5 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_write(JNIEnv *env, jobject
// printf("::::> tried to write %d frames, actually wrote %d frames.\n", frames_to_write, frames_written); // printf("::::> tried to write %d frames, actually wrote %d frames.\n", frames_to_write, frames_written);
_RELEASE_BYTE_ARRAY_ELEMENTS(audioData, buffer); _RELEASE_BYTE_ARRAY_ELEMENTS(audioData, buffer);
return frames_written;
} }

View File

@@ -7,6 +7,12 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#undef android_media_AudioTrack_PLAYSTATE_STOPPED
#define android_media_AudioTrack_PLAYSTATE_STOPPED 1L
#undef android_media_AudioTrack_PLAYSTATE_PAUSED
#define android_media_AudioTrack_PLAYSTATE_PAUSED 2L
#undef android_media_AudioTrack_PLAYSTATE_PLAYING
#define android_media_AudioTrack_PLAYSTATE_PLAYING 3L
/* /*
* Class: android_media_AudioTrack * Class: android_media_AudioTrack
* Method: native_constructor * Method: native_constructor
@@ -25,18 +31,18 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_getMinBufferSize
/* /*
* Class: android_media_AudioTrack * Class: android_media_AudioTrack
* Method: play * Method: native_play
* Signature: ()V * Signature: ()V
*/ */
JNIEXPORT void JNICALL Java_android_media_AudioTrack_play JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1play
(JNIEnv *, jobject); (JNIEnv *, jobject);
/* /*
* Class: android_media_AudioTrack * Class: android_media_AudioTrack
* Method: write * Method: native_write
* Signature: ([BII)I * Signature: ([BII)I
*/ */
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_write JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1write
(JNIEnv *, jobject, jbyteArray, jint, jint); (JNIEnv *, jobject, jbyteArray, jint, jint);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -6,6 +6,10 @@ public class AudioTrack {
void onPeriodicNotification(AudioTrack track); void onPeriodicNotification(AudioTrack track);
} }
public static final int PLAYSTATE_STOPPED = 1;
public static final int PLAYSTATE_PAUSED = 2;
public static final int PLAYSTATE_PLAYING = 3;
int streamType; int streamType;
int sampleRateInHz; int sampleRateInHz;
int channelConfig; int channelConfig;
@@ -13,6 +17,8 @@ public class AudioTrack {
int bufferSizeInBytes; int bufferSizeInBytes;
int mode; int mode;
private int sessionId; private int sessionId;
private int playbackState = PLAYSTATE_STOPPED;
private int playbackHeadPosition = 0;
// for native code's use // for native code's use
long pcm_handle; long pcm_handle;
@@ -39,6 +45,9 @@ public class AudioTrack {
case 2: case 2:
num_channels = 1; num_channels = 1;
break; break;
case 12:
num_channels = 2;
break;
default: default:
num_channels = 1; num_channels = 1;
} }
@@ -66,10 +75,15 @@ public class AudioTrack {
return this.frames; return this.frames;
} }
public native void play(); public void play() {
System.out.println("calling AudioTrack.play()\n");
playbackState = PLAYSTATE_PLAYING;
native_play();
}
public void stop() { public void stop() {
System.out.println("calling stop(), how did this not get reported before DIDREEEEEEEEEEEEEEEEEEEEEEEEE\n"); System.out.println("calling stop(), how did this not get reported before DIDREEEEEEEEEEEEEEEEEEEEEEEEE\n");
playbackState = PLAYSTATE_STOPPED;
} }
public void flush() { public void flush() {
@@ -81,12 +95,43 @@ public class AudioTrack {
} }
public int getState() { public int getState() {
return 0; // TODO: fix up the native part and make this work properly return 1; // TODO: fix up the native part and make this work properly
} }
public native int write(byte[] audioData, int offsetInBytes, int sizeInBytes); public int write(byte[] audioData, int offsetInBytes, int sizeInBytes) {
int framesToWrite = sizeInBytes / channels / 2; // 2 means PCM16
int ret = native_write(audioData, offsetInBytes, framesToWrite);
if (ret > 0) {
playbackHeadPosition += ret;
}
return ret * channels * 2; // 2 means PCM16
}
public int getAudioSessionId() { public int getAudioSessionId() {
return sessionId; return sessionId;
} }
public int getSampleRate() {
return sampleRateInHz;
}
public int setStereoVolume(float leftVolume, float rightVolume) {
return 0;
}
public int getPlayState() {
return playbackState;
}
public void pause() {
System.out.println("calling AudioTrack.pause()\n");
playbackState = PLAYSTATE_PAUSED;
}
public int getPlaybackHeadPosition() {
return playbackHeadPosition;
}
public native void native_play();
private native int native_write(byte[] audioData, int offsetInBytes, int sizeInBytes);
} }