AudioTrack: fix getPlaybackHeadPosition and write

this fixes audio sync in exoplayer
This commit is contained in:
Mis012
2024-04-28 23:39:04 +02:00
parent 639a786056
commit a99dfd80cc
3 changed files with 39 additions and 9 deletions

View File

@@ -217,7 +217,7 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1play(JNIEnv *env, j
/*--↑*/
}
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1write(JNIEnv *env, jobject this, jbyteArray audioData, jint offsetInBytes, jint frames_to_write)
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1write(JNIEnv *env, jobject this, jbyteArray audio_data, jint offset_in_bytes, jint frames_to_write)
{
int ret;
@@ -225,9 +225,9 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1write(JNIEnv *env,
snd_pcm_sframes_t frames_written;
jbyte *buffer = _GET_BYTE_ARRAY_ELEMENTS(audioData);
jbyte *buffer = _GET_BYTE_ARRAY_ELEMENTS(audio_data);
ret = frames_written = snd_pcm_writei(pcm_handle, buffer, frames_to_write);
ret = frames_written = snd_pcm_writei(pcm_handle, buffer + offset_in_bytes, frames_to_write);
if (ret < 0) {
if (ret == -EPIPE) {
printf("XRUN.\n");
@@ -239,7 +239,7 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1write(JNIEnv *env,
// 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(audio_data, buffer);
return frames_written;
}
@@ -254,3 +254,12 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1release(JNIEnv *env
snd_pcm_t *pcm_handle = _PTR(_GET_LONG_FIELD(this, "pcm_handle"));
snd_pcm_close(pcm_handle);
}
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1getPlaybackHeadPosition(JNIEnv *env, jobject this)
{
snd_pcm_t *pcm_handle = _PTR(_GET_LONG_FIELD(this, "pcm_handle"));
snd_pcm_sframes_t delay;
snd_pcm_delay(pcm_handle, &delay);
return delay;
}

View File

@@ -7,6 +7,8 @@
#ifdef __cplusplus
extern "C" {
#endif
#undef android_media_AudioTrack_ERROR_BAD_VALUE
#define android_media_AudioTrack_ERROR_BAD_VALUE -2L
#undef android_media_AudioTrack_PLAYSTATE_STOPPED
#define android_media_AudioTrack_PLAYSTATE_STOPPED 1L
#undef android_media_AudioTrack_PLAYSTATE_PAUSED
@@ -29,6 +31,14 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1constructor
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_getMinBufferSize
(JNIEnv *, jclass, jint, jint, jint);
/*
* Class: android_media_AudioTrack
* Method: native_getPlaybackHeadPosition
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1getPlaybackHeadPosition
(JNIEnv *, jobject);
/*
* Class: android_media_AudioTrack
* Method: native_play

View File

@@ -6,6 +6,8 @@ public class AudioTrack {
void onPeriodicNotification(AudioTrack track);
}
public static final int ERROR_BAD_VALUE = -2; // basically EINVAL
public static final int PLAYSTATE_STOPPED = 1;
public static final int PLAYSTATE_PAUSED = 2;
public static final int PLAYSTATE_PLAYING = 3;
@@ -67,7 +69,7 @@ public class AudioTrack {
}
public int setPositionNotificationPeriod(int periodInFrames) {
System.out.println("\n\n\nsetPositionNotificationPeriod(" + periodInFrames + "); called\n\n\n\n");
System.out.println("\n\nAudioTrack.nsetPositionNotificationPeriod(" + periodInFrames + "); called\n\n\n\n");
return 0; // SUCCESS
}
@@ -82,16 +84,16 @@ public class AudioTrack {
}
public void stop() {
System.out.println("calling stop(), how did this not get reported before DIDREEEEEEEEEEEEEEEEEEEEEEEEE\n");
System.out.println("STUB: AudioTrack.stop()\n");
playbackState = PLAYSTATE_STOPPED;
}
public void flush() {
System.out.println("calling flush(), how did this not get reported before DIDREEEEEEEEEEEEEEEEEEEEEEEEE\n");
System.out.println("STUB: AudioTrack.flush()\n");
}
public void release() {
System.out.println("calling release(), how did this not get reported before DIDREEEEEEEEEEEEEEEEEEEEEEEEE\n");
System.out.println("calling AudioTrack.release()\n");
native_release();
}
@@ -100,6 +102,14 @@ public class AudioTrack {
}
public int write(byte[] audioData, int offsetInBytes, int sizeInBytes) {
/* sanity check the parameters before calling native_write */
if ((audioData == null)
|| (offsetInBytes < 0) || (sizeInBytes < 0)
|| (offsetInBytes + sizeInBytes < 0)
|| (offsetInBytes + sizeInBytes > audioData.length)) {
return ERROR_BAD_VALUE;
}
int framesToWrite = sizeInBytes / channels / 2; // 2 means PCM16
int ret = native_write(audioData, offsetInBytes, framesToWrite);
if (ret > 0) {
@@ -131,9 +141,10 @@ public class AudioTrack {
}
public int getPlaybackHeadPosition() {
return playbackHeadPosition;
return playbackHeadPosition - native_getPlaybackHeadPosition();
}
private native int native_getPlaybackHeadPosition();
public native void native_play();
public native void native_pause();
private native int native_write(byte[] audioData, int offsetInBytes, int sizeInBytes);