mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2026-04-19 06:49:55 +00:00
Replace Javax Sound with direct alsa access
This commit is contained in:
4
jni/nv_alsa/build.sh
Normal file
4
jni/nv_alsa/build.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
rm *.o libnv_alsa.so
|
||||
gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -I /opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -I ./inc -fPIC -L. -c *.c
|
||||
gcc -shared -Wl,-soname,libnv_alsa.so -Wl,--no-undefined -o libnv_alsa.so *.o -L. -lasound
|
||||
rm *.o
|
||||
54
jni/nv_alsa/nv_alsa.c
Normal file
54
jni/nv_alsa/nv_alsa.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* Use the newer ALSA API */
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
|
||||
/* All of the ALSA library API is defined
|
||||
* in this header */
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
snd_pcm_t *handle;
|
||||
|
||||
int nv_alsa_init(unsigned int channelCount, unsigned int sampleRate) {
|
||||
int rc;
|
||||
snd_pcm_hw_params_t *params;
|
||||
int dir;
|
||||
|
||||
/* Open PCM device for playback. */
|
||||
if ((rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) != 0)
|
||||
return rc;
|
||||
|
||||
snd_pcm_hw_params_alloca(¶ms);
|
||||
snd_pcm_hw_params_any(handle, params);
|
||||
|
||||
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
|
||||
snd_pcm_hw_params_set_channels(handle, params, channelCount);
|
||||
snd_pcm_hw_params_set_rate_near(handle, params, &sampleRate, &dir);
|
||||
|
||||
snd_pcm_uframes_t frames = 32;
|
||||
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
|
||||
|
||||
if ((rc = snd_pcm_hw_params(handle, params)) != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int nv_alsa_play(const unsigned char* indata, int data_len) {
|
||||
int frames = data_len/4; /* 2 bytes/sample, 2 channels */
|
||||
int rc = snd_pcm_writei(handle, indata, frames);
|
||||
if (rc == -EPIPE) {
|
||||
/* EPIPE means underrun */
|
||||
fprintf(stderr, "underrun occurred\n");
|
||||
snd_pcm_prepare(handle);
|
||||
} else if (rc < 0) {
|
||||
fprintf(stderr,
|
||||
"error from writei: %s\n",
|
||||
snd_strerror(rc));
|
||||
} else if (rc != (int) frames) {
|
||||
fprintf(stderr,
|
||||
"short write, write %d frames\n", rc);
|
||||
}
|
||||
}
|
||||
|
||||
int nv_alsa_close(void) {
|
||||
snd_pcm_drain(handle);
|
||||
snd_pcm_close(handle);
|
||||
}
|
||||
5
jni/nv_alsa/nv_alsa.h
Normal file
5
jni/nv_alsa/nv_alsa.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <jni.h>
|
||||
|
||||
int nv_alsa_init(unsigned int channelCount, unsigned int sampleRate);
|
||||
int nv_alsa_play(unsigned char* indata, int inlen);
|
||||
void nv_alsa_close(void);
|
||||
36
jni/nv_alsa/nv_alsa_jni.c
Normal file
36
jni/nv_alsa/nv_alsa_jni.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "nv_alsa.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
|
||||
// This function must be called before
|
||||
// any other decoding functions
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_limelight_binding_audio_AlsaAudio_init(JNIEnv *env, jobject this, jint channelCount, jint sampleRate)
|
||||
{
|
||||
return nv_alsa_init(channelCount, sampleRate);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_limelight_binding_audio_AlsaAudio_close(JNIEnv *env, jobject this)
|
||||
{
|
||||
nv_alsa_close();
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_limelight_binding_audio_AlsaAudio_play(
|
||||
JNIEnv *env, jobject this, // JNI parameters
|
||||
jbyteArray indata, jint inoff, jint inlen)
|
||||
{
|
||||
jint ret;
|
||||
jbyte* jni_input_data;
|
||||
|
||||
jni_input_data = (*env)->GetByteArrayElements(env, indata, 0);
|
||||
|
||||
ret = nv_alsa_play(&jni_input_data[inoff], inlen);
|
||||
|
||||
// The input data isn't changed so it can be safely aborted
|
||||
(*env)->ReleaseByteArrayElements(env, indata, jni_input_data, JNI_ABORT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user