kopia lustrzana https://github.com/sh123/codec2_talkie
Freedv native wrappers
rodzic
de7f82f1b6
commit
5fd11bafc1
|
@ -0,0 +1,70 @@
|
|||
package com.radio.codec2talkie.protocol;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.radio.codec2talkie.protocol.message.TextMessage;
|
||||
import com.radio.codec2talkie.protocol.position.Position;
|
||||
import com.radio.codec2talkie.transport.Transport;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Freedv implements Protocol {
|
||||
|
||||
private final Protocol _childProtocol;
|
||||
private ProtocolCallback _parentProtocolCallback;
|
||||
|
||||
public Freedv(Protocol childProtocol, int freedvMode) {
|
||||
_childProtocol = childProtocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Transport transport, Context context, ProtocolCallback protocolCallback) throws IOException {
|
||||
_parentProtocolCallback = protocolCallback;
|
||||
_childProtocol.initialize(transport, context, _parentProtocolCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPcmAudioBufferSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCompressedAudio(String src, String dst, int codec, byte[] frame) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTextMessage(TextMessage textMessage) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(String src, String dst, byte[] dataPacket) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean receive() throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPosition(Position position) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ public class ProtocolFactory {
|
|||
|
||||
ProtocolFactory.ProtocolType protocolType;
|
||||
|
||||
// Use HDLC instead of KISS for the sound modem as we are the modem
|
||||
if (sharedPreferences.getString(PreferenceKeys.PORTS_TYPE, "loopback").equals("sound_modem")) {
|
||||
protocolType = ProtocolFactory.ProtocolType.HDLC;
|
||||
} else if (sharedPreferences.getBoolean(PreferenceKeys.KISS_ENABLED, true)) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "codec2/codec2_fdmdv.h"
|
||||
#include "codec2/codec2.h"
|
||||
#include "codec2/fsk.h"
|
||||
#include "codec2/freedv_api.h"
|
||||
|
||||
namespace Java_com_ustadmobile_codec2_Codec2 {
|
||||
|
||||
|
@ -28,6 +29,12 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
int gain;
|
||||
};
|
||||
|
||||
struct ContextFreedv {
|
||||
struct freedv *freeDv;
|
||||
short *speechSamples;
|
||||
short *modemSamples;
|
||||
};
|
||||
|
||||
static Context *getContext(jlong jp) {
|
||||
auto p = (unsigned long) jp;
|
||||
Context *con;
|
||||
|
@ -42,6 +49,13 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
return conFsk;
|
||||
}
|
||||
|
||||
static ContextFreedv *getContextFreedv(jlong jp) {
|
||||
auto p = (unsigned long) jp;
|
||||
ContextFreedv *conFreedv;
|
||||
conFreedv = (ContextFreedv *) p;
|
||||
return conFreedv;
|
||||
}
|
||||
|
||||
static jlong create(JNIEnv *env, jclass clazz, int mode) {
|
||||
struct Context *con;
|
||||
con = (struct Context *) malloc(sizeof(struct Context));
|
||||
|
@ -80,8 +94,18 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
fsk_set_freq_est_limits(fsk, 500, sampleFrequency / 4);
|
||||
fsk_set_freq_est_alg(fsk, 0);
|
||||
|
||||
auto pv = (unsigned long) conFsk;
|
||||
return pv;
|
||||
return reinterpret_cast<jlong>(conFsk);
|
||||
}
|
||||
|
||||
static jlong freedvCreate(JNIEnv *env, jclass clazz, int mode) {
|
||||
struct ContextFreedv *conFreedv;
|
||||
conFreedv = (struct ContextFreedv *) malloc(sizeof(struct ContextFreedv));
|
||||
conFreedv->freeDv = freedv_open(mode);
|
||||
conFreedv->speechSamples = static_cast<short *>(malloc(
|
||||
freedv_get_n_max_speech_samples(conFreedv->freeDv) * sizeof(short)));
|
||||
conFreedv->modemSamples = static_cast<short *>(malloc(
|
||||
freedv_get_n_max_modem_samples(conFreedv->freeDv) * sizeof(short)));
|
||||
return reinterpret_cast<jlong>(conFreedv);
|
||||
}
|
||||
|
||||
static jint c2spf(JNIEnv *env, jclass clazz, jlong n) {
|
||||
|
@ -124,6 +148,31 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
return fsk_nin(conFsk->fsk);
|
||||
}
|
||||
|
||||
static jint freedvGetMaxSpeechSamples(JNIEnv * env, jclass clazz, jlong n) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
return freedv_get_n_max_speech_samples(conFreedv->freeDv);
|
||||
}
|
||||
|
||||
static jint freedvGetMaxModemSamples(JNIEnv * env, jclass clazz, jlong n) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
return freedv_get_n_max_modem_samples(conFreedv->freeDv);
|
||||
}
|
||||
|
||||
static jint freedvGetNSpeechSamples(JNIEnv * env, jclass clazz, jlong n) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
return freedv_get_n_speech_samples(conFreedv->freeDv);
|
||||
}
|
||||
|
||||
static jint freedvGetNomModemSamples(JNIEnv * env, jclass clazz, jlong n) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
return freedv_get_n_nom_modem_samples(conFreedv->freeDv);
|
||||
}
|
||||
|
||||
static jint freedvNin(JNIEnv * env, jclass clazz, jlong n) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
return freedv_nin(conFreedv->freeDv);
|
||||
}
|
||||
|
||||
static jint destroy(JNIEnv *env, jclass clazz, jlong n) {
|
||||
Context *con = getContext(n);
|
||||
codec2_destroy(con->c2);
|
||||
|
@ -145,6 +194,15 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static jint freedvDestroy(JNIEnv *env, jclass clazz, jlong n) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
freedv_close(conFreedv->freeDv);
|
||||
free(conFreedv->modemSamples);
|
||||
free(conFreedv->speechSamples);
|
||||
free(conFreedv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static jlong encode(JNIEnv *env, jclass clazz, jlong n, jshortArray inputBuffer, jcharArray outputBits) {
|
||||
Context *con = getContext(n);
|
||||
jshort *jbuf = env->GetShortArrayElements(inputBuffer, nullptr);
|
||||
|
@ -177,6 +235,16 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static jlong freedvTx(JNIEnv *env, jclass clazz, jlong n, jshortArray outputModemSamples, jshortArray inputSpeechSamples) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
int cntSpeechSamples = freedv_get_n_speech_samples(conFreedv->freeDv);
|
||||
env->GetShortArrayRegion(inputSpeechSamples, 0, cntSpeechSamples, conFreedv->speechSamples);
|
||||
int cntModemSamples = freedv_get_n_nom_modem_samples(conFreedv->freeDv);
|
||||
freedv_tx(conFreedv->freeDv, conFreedv->modemSamples, conFreedv->speechSamples);
|
||||
env->SetShortArrayRegion(outputModemSamples, 0, cntModemSamples, conFreedv->modemSamples);
|
||||
return cntModemSamples;
|
||||
}
|
||||
|
||||
static jlong decode(JNIEnv *env, jclass clazz, jlong n, jshortArray outputSamples, jbyteArray inputBits) {
|
||||
Context *con = getContext(n);
|
||||
env->GetByteArrayRegion(inputBits, 0, con->nbyte, reinterpret_cast<jbyte*>(con->bits));
|
||||
|
@ -197,23 +265,44 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static jlong freedvRx(JNIEnv *env, jclass clazz, jlong n, jshortArray outputSpeechSamples, jshortArray inputModemSamples) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
int nin = freedv_nin(conFreedv->freeDv);
|
||||
env->GetShortArrayRegion(inputModemSamples, 0, nin, conFreedv->speechSamples);
|
||||
freedv_rx(conFreedv->freeDv, conFreedv->modemSamples, conFreedv->speechSamples);
|
||||
env->SetShortArrayRegion(outputSpeechSamples, 0, nin, conFreedv->modemSamples);
|
||||
return nin;
|
||||
}
|
||||
|
||||
static JNINativeMethod method_table[] = {
|
||||
{"create", "(I)J", (void *) create},
|
||||
{"getSamplesPerFrame", "(J)I", (void *) c2spf},
|
||||
{"getBitsSize", "(J)I", (void *) c2bits},
|
||||
{"destroy", "(J)I", (void *) destroy},
|
||||
{"encode", "(J[S[C)J", (void *) encode},
|
||||
{"decode", "(J[S[B)J", (void *) decode},
|
||||
{"fskCreate", "(IIIII)J", (void *) fskCreate},
|
||||
{"fskDestroy", "(J)I", (void *) fskDestroy},
|
||||
{"fskModulate", "(J[S[B)J", (void *) fskModulate},
|
||||
{"fskDemodulate", "(J[S[B)J", (void *) fskDemodulate},
|
||||
{"fskDemodBitsBufSize","(J)I", (void *) fskDemodBitsBufSize},
|
||||
{"fskModSamplesBufSize","(J)I", (void *) fskModSamplesBufSize},
|
||||
{"fskDemodSamplesBufSize","(J)I", (void *) fskDemodSamplesBufSize},
|
||||
{"fskModBitsBufSize", "(J)I", (void *) fskModBitsBufSize},
|
||||
{"fskSamplesPerSymbol","(J)I", (void *) fskSamplesPerSymbol},
|
||||
{"fskNin", "(J)I", (void *) fskNin}
|
||||
// codec2
|
||||
{"create", "(I)J", (void *) create},
|
||||
{"getSamplesPerFrame", "(J)I", (void *) c2spf},
|
||||
{"getBitsSize", "(J)I", (void *) c2bits},
|
||||
{"destroy", "(J)I", (void *) destroy},
|
||||
{"encode", "(J[S[C)J", (void *) encode},
|
||||
{"decode", "(J[S[B)J", (void *) decode},
|
||||
// fsk
|
||||
{"fskCreate", "(IIIII)J", (void *) fskCreate},
|
||||
{"fskDestroy", "(J)I", (void *) fskDestroy},
|
||||
{"fskModulate", "(J[S[B)J", (void *) fskModulate},
|
||||
{"fskDemodulate", "(J[S[B)J", (void *) fskDemodulate},
|
||||
{"fskDemodBitsBufSize", "(J)I", (void *) fskDemodBitsBufSize},
|
||||
{"fskModSamplesBufSize", "(J)I", (void *) fskModSamplesBufSize},
|
||||
{"fskDemodSamplesBufSize", "(J)I", (void *) fskDemodSamplesBufSize},
|
||||
{"fskModBitsBufSize", "(J)I", (void *) fskModBitsBufSize},
|
||||
{"fskSamplesPerSymbol", "(J)I", (void *) fskSamplesPerSymbol},
|
||||
{"fskNin", "(J)I", (void *) fskNin},
|
||||
// freedv
|
||||
{"freedvCreate", "(I)J", (void *)freedvCreate},
|
||||
{"freedvDestroy", "(J)I", (void *)freedvDestroy},
|
||||
{"freedvGetMaxSpeechSamples", "(J)I", (void *)freedvGetMaxSpeechSamples},
|
||||
{"freedvGetMaxModemSamples", "(J)I", (void *)freedvGetMaxModemSamples},
|
||||
{"freedvGetNSpeechSamples", "(J)I", (void *)freedvGetNSpeechSamples},
|
||||
{"freedvGetNomModemSamples", "(J)I", (void *)freedvGetNomModemSamples},
|
||||
{"freedvNin", "(J)I", (void *)freedvNin},
|
||||
{"freedvTx", "(J[S[S)J", (void *)freedvTx},
|
||||
{"freedvRx", "(J[S[S)J", (void *)freedvRx}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ public class Codec2 {
|
|||
System.loadLibrary("Codec2JNI");
|
||||
}
|
||||
|
||||
// codec2 modes
|
||||
public static final int CODEC2_MODE_3200 = 0;
|
||||
public static final int CODEC2_MODE_2400 = 1;
|
||||
public static final int CODEC2_MODE_1600 = 2;
|
||||
|
@ -20,12 +21,18 @@ public class Codec2 {
|
|||
public static final int CODEC2_MODE_450=10;
|
||||
public static final int CODEC2_MODE_450PWB=11;
|
||||
|
||||
/**
|
||||
* The size of the file header that is written when using c2enc. When decoding, this must be
|
||||
* skipped.
|
||||
*/
|
||||
public static final int CODEC2_FILE_HEADER_SIZE = 7;
|
||||
// freedv modes
|
||||
public static final int FREEDV_MODE_1600 = 0;
|
||||
public static final int FREEDV_MODE_2400A = 3;
|
||||
public static final int FREEDV_MODE_2400B = 4;
|
||||
public static final int FREEDV_MODE_800XA = 5;
|
||||
public static final int FREEDV_MODE_700C = 6;
|
||||
public static final int FREEDV_MODE_700D = 7;
|
||||
public static final int FREEDV_MODE_2020 = 8;
|
||||
public static final int FREEDV_MODE_2020B = 16;
|
||||
public static final int FREEDV_MODE_700E = 13;
|
||||
|
||||
// raw codec2
|
||||
public native static long create(int mode);
|
||||
public native static int destroy(long con);
|
||||
|
||||
|
@ -35,6 +42,7 @@ public class Codec2 {
|
|||
public native static long encode(long con, short[] inputSamples, char[] outputBits);
|
||||
public native static long decode(long con, short[] outputSamples, byte[] inputsBits);
|
||||
|
||||
// raw fsk
|
||||
public native static long fskCreate(int sampleFrequency, int symbolRate, int toneFreq, int toneSpacing, int gain);
|
||||
public native static int fskDestroy(long conFsk);
|
||||
|
||||
|
@ -47,4 +55,17 @@ public class Codec2 {
|
|||
|
||||
public native static long fskModulate(long conFsk, short[] outputSamples, byte[] inputBits);
|
||||
public native static long fskDemodulate(long conFsk, short[] inputSamples, byte[] outputBits);
|
||||
|
||||
// freedv
|
||||
public native static long freedvCreate(int mode);
|
||||
public native static int freedvDestroy(long conFreedv);
|
||||
|
||||
public native static int freedvGetMaxSpeechSamples(long conFreedv);
|
||||
public native static int freedvGetMaxModemSamples(long conFreedv);
|
||||
public native static int freedvGetNSpeechSamples(long conFreedv);
|
||||
public native static int freedvGetNomModemSamples(long conFreedv);
|
||||
public native static int freedvNin(long conFreedv);
|
||||
|
||||
public native static long freedvTx(long conFsk, short[] outputModemSamples, short[] inputSpeechSamples);
|
||||
public native static long freedvRx(long conFsk, short[] outputSpeechSamples, short[] inputModemSamples);
|
||||
}
|
Ładowanie…
Reference in New Issue