kopia lustrzana https://github.com/sh123/codec2_talkie
APRS transmit over FreeDV data
rodzic
2e48935c67
commit
8aedde6f9c
|
@ -6,7 +6,6 @@ import android.util.Log;
|
|||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.radio.codec2talkie.app.AppWorker;
|
||||
import com.radio.codec2talkie.protocol.message.TextMessage;
|
||||
import com.radio.codec2talkie.protocol.position.Position;
|
||||
import com.radio.codec2talkie.settings.PreferenceKeys;
|
||||
|
@ -25,10 +24,14 @@ public class Freedv implements Protocol {
|
|||
private Transport _transport;
|
||||
|
||||
private long _freedv;
|
||||
private long _freedvData;
|
||||
|
||||
private short[] _modemTxBuffer;
|
||||
private short[] _speechRxBuffer;
|
||||
|
||||
private short[] _dataSamplesBuffer;
|
||||
private byte[] _dataTxBuffer;
|
||||
|
||||
public Freedv() {
|
||||
}
|
||||
|
||||
|
@ -48,6 +51,10 @@ public class Freedv implements Protocol {
|
|||
_freedv = Codec2.freedvCreate(mode, isSquelchEnabled, squelchSnr);
|
||||
_modemTxBuffer = new short[Codec2.freedvGetNomModemSamples(_freedv)];
|
||||
_speechRxBuffer = new short[Codec2.freedvGetMaxSpeechSamples(_freedv)];
|
||||
|
||||
_freedvData = Codec2.freedvCreate(dataMode, isSquelchEnabled, squelchSnr);
|
||||
_dataTxBuffer = new byte[Codec2.freedvGetBitsPerModemFrame(_freedvData) / 8];
|
||||
_dataSamplesBuffer = new short[Codec2.freedvGetNTxSamples(_freedvData)];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,7 +82,24 @@ public class Freedv implements Protocol {
|
|||
|
||||
@Override
|
||||
public void sendData(String src, String dst, byte[] dataPacket) throws IOException {
|
||||
// TODO, send as data
|
||||
Log.v(TAG, "sendData() " + dataPacket.length);
|
||||
if (dataPacket.length > _dataTxBuffer.length - 2) {
|
||||
Log.e(TAG, "Too large packet " + dataPacket.length + " > " + _dataTxBuffer.length);
|
||||
return;
|
||||
}
|
||||
long cnt = Codec2.freedvRawDataPreambleTx(_freedvData, _dataSamplesBuffer);
|
||||
Log.v(TAG, "sendData() write preamble " + cnt);
|
||||
_transport.write(Arrays.copyOf(_dataSamplesBuffer, (int) cnt));
|
||||
|
||||
Arrays.fill(_dataTxBuffer, (byte) 0);
|
||||
System.arraycopy(dataPacket, 0, _dataTxBuffer, 0, dataPacket.length);
|
||||
Codec2.freedvRawDataTx(_freedvData, _dataSamplesBuffer, _dataTxBuffer);
|
||||
Log.v(TAG, "sendData() write data " + _dataSamplesBuffer.length);
|
||||
_transport.write(_dataSamplesBuffer);
|
||||
|
||||
cnt = Codec2.freedvRawDataPostambleTx(_freedvData, _dataSamplesBuffer);
|
||||
Log.v(TAG, "sendData() write postamble " + cnt);
|
||||
_transport.write(Arrays.copyOf(_dataSamplesBuffer, (int) cnt));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,6 +133,7 @@ public class Freedv implements Protocol {
|
|||
|
||||
@Override
|
||||
public void close() {
|
||||
Codec2.freedvDestroy(_freedvData);
|
||||
Codec2.freedvDestroy(_freedv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,9 @@ public class ProtocolFactory {
|
|||
boolean scramblingEnabled = SettingsWrapper.isKissScramblerEnabled(sharedPreferences);
|
||||
String scramblingKey = SettingsWrapper.getKissScramblerKey(sharedPreferences);
|
||||
boolean aprsEnabled = SettingsWrapper.isAprsEnabled(sharedPreferences);
|
||||
boolean freedvEnabled = SettingsWrapper.isFreeDvSoundModemModulation(sharedPreferences);
|
||||
|
||||
// "root" protocol
|
||||
Protocol proto;
|
||||
switch (protocolType) {
|
||||
case KISS:
|
||||
|
@ -84,8 +86,8 @@ public class ProtocolFactory {
|
|||
proto = new Hdlc(sharedPreferences);
|
||||
break;
|
||||
case FREEDV:
|
||||
// standalone
|
||||
return new Freedv();
|
||||
proto = new Freedv();
|
||||
break;
|
||||
case RAW:
|
||||
default:
|
||||
proto = new Raw();
|
||||
|
@ -98,12 +100,14 @@ public class ProtocolFactory {
|
|||
if (aprsEnabled) {
|
||||
proto = new Ax25(proto);
|
||||
}
|
||||
if (!freedvEnabled) {
|
||||
if (recordingEnabled) {
|
||||
proto = new Recorder(proto, codec2ModeId);
|
||||
}
|
||||
|
||||
proto = new AudioFrameAggregator(proto, codec2ModeId);
|
||||
proto = new AudioCodec2(proto, codec2ModeId);
|
||||
}
|
||||
|
||||
if (aprsEnabled) {
|
||||
proto = new Aprs(proto);
|
||||
|
|
|
@ -85,7 +85,6 @@ public class SettingsWrapper {
|
|||
}
|
||||
|
||||
public static boolean isAprsEnabled(SharedPreferences sharedPreferences) {
|
||||
return sharedPreferences.getBoolean(PreferenceKeys.APRS_ENABLED, false) &&
|
||||
!isFreeDvSoundModemModulation(sharedPreferences); // no aprs when in freedv
|
||||
return sharedPreferences.getBoolean(PreferenceKeys.APRS_ENABLED, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public class SoundModemBase implements Runnable {
|
|||
}
|
||||
|
||||
private void constructSystemAudioDevices(boolean disableRx, int sampleRate) {
|
||||
int audioRecorderMinBufferSize = AudioRecord.getMinBufferSize(
|
||||
int audioRecorderMinBufferSize = 10 * AudioRecord.getMinBufferSize(
|
||||
sampleRate,
|
||||
AudioFormat.CHANNEL_IN_MONO,
|
||||
AudioFormat.ENCODING_PCM_16BIT);
|
||||
|
@ -84,12 +84,13 @@ public class SoundModemBase implements Runnable {
|
|||
sampleRate,
|
||||
AudioFormat.CHANNEL_IN_MONO,
|
||||
AudioFormat.ENCODING_PCM_16BIT,
|
||||
10*audioRecorderMinBufferSize);
|
||||
audioRecorderMinBufferSize);
|
||||
|
||||
int audioPlayerMinBufferSize = AudioTrack.getMinBufferSize(
|
||||
int audioPlayerMinBufferSize = 10 * AudioTrack.getMinBufferSize(
|
||||
sampleRate,
|
||||
AudioFormat.CHANNEL_OUT_MONO,
|
||||
AudioFormat.ENCODING_PCM_16BIT);
|
||||
|
||||
if (!disableRx)
|
||||
_systemAudioRecorder.startRecording();
|
||||
|
||||
|
@ -105,9 +106,11 @@ public class SoundModemBase implements Runnable {
|
|||
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
|
||||
.build())
|
||||
.setTransferMode(AudioTrack.MODE_STREAM)
|
||||
.setBufferSizeInBytes(10*audioPlayerMinBufferSize)
|
||||
.setBufferSizeInBytes(audioPlayerMinBufferSize)
|
||||
.build();
|
||||
_systemAudioPlayer.setVolume(AudioTrack.getMaxVolume());
|
||||
|
||||
Log.i(TAG, "Play buffer size " + audioPlayerMinBufferSize + ", recorder " + audioRecorderMinBufferSize);
|
||||
}
|
||||
|
||||
protected int read(short[] sampleBuffer, int samplesToRead) {
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
conFreedv->rawData = static_cast<unsigned char *>(malloc(
|
||||
freedv_get_bits_per_modem_frame(conFreedv->freeDv) / 8));
|
||||
conFreedv->rawDataSamples = static_cast<short *>(malloc(
|
||||
freedv_get_n_tx_modem_samples(conFreedv->freeDv)));
|
||||
freedv_get_n_tx_modem_samples(conFreedv->freeDv) * sizeof(short)));
|
||||
// squelch
|
||||
freedv_set_squelch_en(conFreedv->freeDv, isSquelchEnabled);
|
||||
freedv_set_snr_squelch_thresh(conFreedv->freeDv, squelchSnr);
|
||||
|
@ -278,23 +278,21 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
|
|||
conFreedv->rawData[cntBytes-1] = crc16 & 0xff;
|
||||
freedv_rawdatatx(conFreedv->freeDv, conFreedv->rawDataSamples, conFreedv->rawData);
|
||||
int cntSamples = freedv_get_n_tx_modem_samples(conFreedv->freeDv);
|
||||
env->SetShortArrayRegion(outputModemSamples, 0, cntSamples, conFreedv->modemSamples);
|
||||
env->SetShortArrayRegion(outputModemSamples, 0, cntSamples, conFreedv->rawDataSamples);
|
||||
return cntSamples;
|
||||
}
|
||||
|
||||
static jlong freedvRawDataPreambleTx(JNIEnv *env, jclass clazz, jlong n, jshortArray outputModemSamples) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
freedv_rawdatapreambletx(conFreedv->freeDv, conFreedv->rawDataSamples);
|
||||
int cntSamples = freedv_get_n_tx_modem_samples(conFreedv->freeDv);
|
||||
env->SetShortArrayRegion(outputModemSamples, 0, cntSamples, conFreedv->modemSamples);
|
||||
int cntSamples = freedv_rawdatapreambletx(conFreedv->freeDv, conFreedv->rawDataSamples);
|
||||
env->SetShortArrayRegion(outputModemSamples, 0, cntSamples, conFreedv->rawDataSamples);
|
||||
return cntSamples;
|
||||
}
|
||||
|
||||
static jlong freedvRawDataPostambleTx(JNIEnv *env, jclass clazz, jlong n, jshortArray outputModemSamples) {
|
||||
ContextFreedv *conFreedv = getContextFreedv(n);
|
||||
freedv_rawdatapostambletx(conFreedv->freeDv, conFreedv->rawDataSamples);
|
||||
int cntSamples = freedv_get_n_tx_modem_samples(conFreedv->freeDv);
|
||||
env->SetShortArrayRegion(outputModemSamples, 0, cntSamples, conFreedv->modemSamples);
|
||||
int cntSamples = freedv_rawdatapostambletx(conFreedv->freeDv, conFreedv->rawDataSamples);
|
||||
env->SetShortArrayRegion(outputModemSamples, 0, cntSamples, conFreedv->rawDataSamples);
|
||||
return cntSamples;
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue