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_hw_params_t *params;
jint channels_out;
jint period_time;
unsigned int channels_out;
unsigned int period_time;
int ret;
@@ -158,7 +158,7 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_getMinBufferSize(JNIEnv *en
if((*env)->ExceptionCheck(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)
}
@@ -197,11 +197,8 @@ void periodic_update_callback(snd_async_handler_t *pcm_callback)
// 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");
// 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;
if(!PCM_DEVICE)
return 0; // STUB
jint channels = _GET_INT_FIELD(this, "channels");
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;
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);
_RELEASE_BYTE_ARRAY_ELEMENTS(audioData, buffer);
return frames_written;
}

View File

@@ -7,6 +7,12 @@
#ifdef __cplusplus
extern "C" {
#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
* Method: native_constructor
@@ -25,18 +31,18 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_getMinBufferSize
/*
* Class: android_media_AudioTrack
* Method: play
* Method: native_play
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_android_media_AudioTrack_play
JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1play
(JNIEnv *, jobject);
/*
* Class: android_media_AudioTrack
* Method: write
* Method: native_write
* 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);
#ifdef __cplusplus

View File

@@ -6,6 +6,10 @@ public class AudioTrack {
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 sampleRateInHz;
int channelConfig;
@@ -13,6 +17,8 @@ public class AudioTrack {
int bufferSizeInBytes;
int mode;
private int sessionId;
private int playbackState = PLAYSTATE_STOPPED;
private int playbackHeadPosition = 0;
// for native code's use
long pcm_handle;
@@ -39,6 +45,9 @@ public class AudioTrack {
case 2:
num_channels = 1;
break;
case 12:
num_channels = 2;
break;
default:
num_channels = 1;
}
@@ -66,10 +75,15 @@ public class AudioTrack {
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() {
System.out.println("calling stop(), how did this not get reported before DIDREEEEEEEEEEEEEEEEEEEEEEEEE\n");
playbackState = PLAYSTATE_STOPPED;
}
public void flush() {
@@ -81,12 +95,43 @@ public class AudioTrack {
}
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() {
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);
}