kopia lustrzana https://github.com/sh123/codec2_talkie
Implement opus jni
rodzic
d8eb26d6fe
commit
52c41ec2a0
|
@ -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;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue