You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
AudioTrack: fix getPlaybackHeadPosition and write
this fixes audio sync in exoplayer
This commit is contained in:
@@ -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;
|
int ret;
|
||||||
|
|
||||||
@@ -225,9 +225,9 @@ JNIEXPORT jint JNICALL Java_android_media_AudioTrack_native_1write(JNIEnv *env,
|
|||||||
|
|
||||||
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(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 < 0) {
|
||||||
if (ret == -EPIPE) {
|
if (ret == -EPIPE) {
|
||||||
printf("XRUN.\n");
|
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);
|
// 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;
|
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_t *pcm_handle = _PTR(_GET_LONG_FIELD(this, "pcm_handle"));
|
||||||
snd_pcm_close(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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
#undef android_media_AudioTrack_ERROR_BAD_VALUE
|
||||||
|
#define android_media_AudioTrack_ERROR_BAD_VALUE -2L
|
||||||
#undef android_media_AudioTrack_PLAYSTATE_STOPPED
|
#undef android_media_AudioTrack_PLAYSTATE_STOPPED
|
||||||
#define android_media_AudioTrack_PLAYSTATE_STOPPED 1L
|
#define android_media_AudioTrack_PLAYSTATE_STOPPED 1L
|
||||||
#undef android_media_AudioTrack_PLAYSTATE_PAUSED
|
#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
|
JNIEXPORT jint JNICALL Java_android_media_AudioTrack_getMinBufferSize
|
||||||
(JNIEnv *, jclass, jint, jint, jint);
|
(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
|
* Class: android_media_AudioTrack
|
||||||
* Method: native_play
|
* Method: native_play
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ public class AudioTrack {
|
|||||||
void onPeriodicNotification(AudioTrack track);
|
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_STOPPED = 1;
|
||||||
public static final int PLAYSTATE_PAUSED = 2;
|
public static final int PLAYSTATE_PAUSED = 2;
|
||||||
public static final int PLAYSTATE_PLAYING = 3;
|
public static final int PLAYSTATE_PLAYING = 3;
|
||||||
@@ -67,7 +69,7 @@ public class AudioTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int setPositionNotificationPeriod(int periodInFrames) {
|
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
|
return 0; // SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,16 +84,16 @@ public class AudioTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
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;
|
playbackState = PLAYSTATE_STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() {
|
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() {
|
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();
|
native_release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +102,14 @@ public class AudioTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int write(byte[] audioData, int offsetInBytes, int sizeInBytes) {
|
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 framesToWrite = sizeInBytes / channels / 2; // 2 means PCM16
|
||||||
int ret = native_write(audioData, offsetInBytes, framesToWrite);
|
int ret = native_write(audioData, offsetInBytes, framesToWrite);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
@@ -131,9 +141,10 @@ public class AudioTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getPlaybackHeadPosition() {
|
public int getPlaybackHeadPosition() {
|
||||||
return playbackHeadPosition;
|
return playbackHeadPosition - native_getPlaybackHeadPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native int native_getPlaybackHeadPosition();
|
||||||
public native void native_play();
|
public native void native_play();
|
||||||
public native void native_pause();
|
public native void native_pause();
|
||||||
private native int native_write(byte[] audioData, int offsetInBytes, int sizeInBytes);
|
private native int native_write(byte[] audioData, int offsetInBytes, int sizeInBytes);
|
||||||
|
|||||||
Reference in New Issue
Block a user