Implement opus jni

master
sh123 2023-12-09 11:49:28 +02:00
rodzic d8eb26d6fe
commit 52c41ec2a0
1 zmienionych plików z 96 dodań i 3 usunięć

Wyświetl plik

@ -3,10 +3,103 @@
#include "opus.h"
namespace Java_com_radio_opus_Opus {
}
static JNINativeMethod method_table[] = {
};
struct Context {
OpusEncoder* encoder;
OpusDecoder* decoder;
};
static Context *getContext(jlong jp) {
auto p = (unsigned long) jp;
Context *con;
con = (Context *) p;
return con;
}
static jlong create(JNIEnv *env, jclass clazz, jint sampleRate, jint numChannels, jint application, jint bitrate, jint complexity) {
struct Context *con;
con = (struct Context *) malloc(sizeof(struct Context));
int encoderError;
OpusEncoder* encoder = opus_encoder_create(sampleRate, 1, application, &encoderError);
if (!encoderError) {
encoderError = opus_encoder_init(encoder, sampleRate, numChannels, application);
opus_encoder_ctl(encoder, OPUS_SET_BITRATE(bitrate));
opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(complexity));
}
int decoderError;
OpusDecoder* decoder = opus_decoder_create(sampleRate, 1, &decoderError);
if (!decoderError) {
decoderError = opus_decoder_init(decoder, sampleRate, numChannels);
}
if (encoderError || decoderError) {
free(encoder);
free(decoder);
free(con);
return 0;
}
con->decoder = decoder;
con->encoder = encoder;
auto pv = (unsigned long) con;
return pv;
}
static jint destroy(JNIEnv *env, jclass clazz, jlong n) {
Context *con = getContext(n);
free(con->encoder);
free(con->decoder);
free(con);
return 0;
}
static jint decode(JNIEnv *env, jclass clazz, jlong n, jbyteArray in, jshortArray out, jint frames)
{
Context *con = getContext(n);
OpusDecoder *decoder = con->decoder;
jint inputArraySize = env->GetArrayLength(in);
jbyte* encodedData = env->GetByteArrayElements(in, 0);
jshort* decodedData = env->GetShortArrayElements(out, 0);
int samples = opus_decode(decoder, (const unsigned char *)encodedData, inputArraySize, decodedData, frames, 0);
env->ReleaseByteArrayElements(in, encodedData, JNI_ABORT);
env->ReleaseShortArrayElements(out, decodedData, 0);
return samples;
}
static jint encode(JNIEnv *env, jclass clazz, jlong n, jshortArray in, jint frames, jbyteArray out)
{
Context *con = getContext(n);
OpusEncoder *encoder = con->encoder;
jint outputArraySize = env->GetArrayLength(out);
jshort* audioSignal = env->GetShortArrayElements(in, 0);
jbyte* encodedSignal = env->GetByteArrayElements(out, 0);
int dataArraySize = opus_encode(encoder, audioSignal, frames, (unsigned char *)encodedSignal, outputArraySize);
env->ReleaseShortArrayElements(in, audioSignal, JNI_ABORT);
env->ReleaseByteArrayElements(out, encodedSignal, 0);
return dataArraySize;
}
static JNINativeMethod method_table[] = {
{"create", "(IIIII)J", (void *) create },
{"destroy", "(J)I", (void *) destroy },
{"decode", "(J[B[SI)J", (void *) decode },
{"encode", "(J[SI[B)J", (void *) encode }
};
}
using namespace Java_com_radio_opus_Opus;