legacy
sh123 2022-07-28 21:14:45 +03:00
rodzic edaec455fe
commit cddc47ed85
11 zmienionych plików z 144 dodań i 48 usunięć

Wyświetl plik

@ -255,9 +255,9 @@ public class MainActivity extends AppCompatActivity implements ServiceConnection
_textConnInfo.setText(R.string.main_status_loopback_test);
startAppService(TransportFactory.TransportType.LOOPBACK);
} else if (requestPermissions()) {
if (_sharedPreferences.getBoolean(PreferenceKeys.PORTS_AUDIO_ENABLED, false)) {
if (_sharedPreferences.getBoolean(PreferenceKeys.PORTS_SOUND_MODEM_ENABLED, false)) {
_textConnInfo.setText(R.string.main_status_sound_modem);
startAppService(TransportFactory.TransportType.AUDIO);
startAppService(TransportFactory.TransportType.SOUND_MODEM);
} else if (_sharedPreferences.getBoolean(PreferenceKeys.PORTS_TCP_IP_ENABLED, false)) {
startTcpIpConnectActivity();
} else {

Wyświetl plik

@ -87,7 +87,7 @@ public class AppWorker extends Thread {
String codec2ModeName = _sharedPreferences.getString(PreferenceKeys.CODEC2_MODE, _context.getResources().getStringArray(R.array.codec2_modes)[0]);
_codec2Mode = AudioTools.extractCodec2ModeId(codec2ModeName);
_transport = TransportFactory.create(transportType);
_transport = TransportFactory.create(transportType, context);
_protocol = ProtocolFactory.create(_codec2Mode, context);
_processPeriodicTimer = new Timer();

Wyświetl plik

@ -66,11 +66,11 @@ public class AudioFrameAggregator implements Protocol {
public void sendCompressedAudio(String src, String dst, int codec2Mode, byte[] frame) throws IOException {
if ( _outputBufferPos + frame.length >= _outputBufferSize) {
_childProtocol.sendCompressedAudio(src, dst, codec2Mode, Arrays.copyOf(_outputBuffer, _outputBufferPos));
_lastSrc = src;
_lastDst = dst;
_lastCodec2Mode = codec2Mode;
_outputBufferPos = 0;
}
_lastSrc = src;
_lastDst = dst;
_lastCodec2Mode = codec2Mode;
System.arraycopy(frame, 0, _outputBuffer, _outputBufferPos, frame.length);
_outputBufferPos += frame.length;
}

Wyświetl plik

@ -17,7 +17,7 @@ public final class PreferenceKeys {
public static String PORTS_TCP_IP_RETRY_COUNT = "ports_tcp_ip_retry_count";
public static String PORTS_TCP_IP_RETRY_DELAY = "ports_tcp_ip_retry_delay";
public static String PORTS_AUDIO_ENABLED = "ports_audio_enabled";
public static String PORTS_SOUND_MODEM_ENABLED = "ports_sound_modem_enable";
public static String CODEC2_MODE = "codec2_mode";
public static String CODEC2_TEST_MODE = "codec2_test_mode";

Wyświetl plik

@ -1,31 +0,0 @@
package com.radio.codec2talkie.transport;
import java.io.IOException;
public class Audio implements Transport {
private final String _name;
public Audio(String name) {
_name = name;
}
@Override
public String name() {
return _name;
}
@Override
public int read(byte[] data) throws IOException {
return 0;
}
@Override
public int write(byte[] data) throws IOException {
return 0;
}
@Override
public void close() throws IOException {
}
}

Wyświetl plik

@ -0,0 +1,109 @@
package com.radio.codec2talkie.transport;
import android.content.Context;
import android.content.SharedPreferences;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.provider.MediaStore;
import androidx.preference.PreferenceManager;
import com.radio.codec2talkie.settings.PreferenceKeys;
import com.ustadmobile.codec2.Codec2;
import java.io.IOException;
public class SoundModem implements Transport {
private static final int AUDIO_SAMPLE_SIZE = 8000;
private final String _name;
private AudioTrack _systemAudioPlayer;
private AudioRecord _systemAudioRecorder;
private final short[] _recordAudioBuffer;
private final byte[] _recordBitBuffer;
private final short[] _playbackAudioBuffer;
private final byte[] _playbackBitBuffer;
private final Context _context;
private final SharedPreferences _sharedPreferences;
private final long _fskModem;
public SoundModem(String name, Context context) {
_name = name;
_context = context;
_sharedPreferences = PreferenceManager.getDefaultSharedPreferences(_context);
_fskModem = Codec2.fskCreate(AUDIO_SAMPLE_SIZE, 300, 1600, 200);
_recordAudioBuffer = new short[Codec2.fskDemodSamplesBufSize(_fskModem)];
_recordBitBuffer = new byte[Codec2.fskDemodBitsBufSize(_fskModem)];
_playbackAudioBuffer = new short[Codec2.fskModSamplesBufSize(_fskModem)];
_playbackBitBuffer = new byte[Codec2.fskModBitsBufSize(_fskModem)];
constructSystemAudioDevices();
}
private void constructSystemAudioDevices() {
int _audioRecorderMinBufferSize = AudioRecord.getMinBufferSize(
AUDIO_SAMPLE_SIZE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
int audioSource = MediaRecorder.AudioSource.MIC;
_systemAudioRecorder = new AudioRecord(
audioSource,
AUDIO_SAMPLE_SIZE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
10 * _audioRecorderMinBufferSize);
int _audioPlayerMinBufferSize = AudioTrack.getMinBufferSize(
AUDIO_SAMPLE_SIZE,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
int usage = AudioAttributes.USAGE_MEDIA;
_systemAudioPlayer = new AudioTrack.Builder()
.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(usage)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build())
.setAudioFormat(new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(AUDIO_SAMPLE_SIZE)
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
.build())
.setTransferMode(AudioTrack.MODE_STREAM)
.setBufferSizeInBytes(10 * _audioPlayerMinBufferSize)
.build();
}
@Override
public String name() {
return _name;
}
@Override
public int read(byte[] data) throws IOException {
return 0;
}
@Override
public int write(byte[] data) throws IOException {
Codec2.fskModulate(_fskModem, _playbackAudioBuffer, _playbackBitBuffer);
_systemAudioPlayer.write(_playbackAudioBuffer, 0, _playbackAudioBuffer.length);
return 0;
}
@Override
public void close() throws IOException {
Codec2.fskDestroy(_fskModem);
}
}

Wyświetl plik

@ -1,5 +1,7 @@
package com.radio.codec2talkie.transport;
import android.content.Context;
import com.radio.codec2talkie.connect.BleHandler;
import com.radio.codec2talkie.connect.BluetoothSocketHandler;
import com.radio.codec2talkie.connect.TcpIpSocketHandler;
@ -15,10 +17,10 @@ public class TransportFactory {
LOOPBACK,
TCP_IP,
BLE,
AUDIO
SOUND_MODEM
};
public static Transport create(TransportType transportType) throws IOException {
public static Transport create(TransportType transportType, Context context) throws IOException {
switch (transportType) {
case USB:
return new UsbSerial(UsbPortHandler.getPort(), UsbPortHandler.getName());
@ -28,8 +30,8 @@ public class TransportFactory {
return new TcpIp(TcpIpSocketHandler.getSocket(), TcpIpSocketHandler.getName());
case BLE:
return new Ble(BleHandler.getGatt(), BleHandler.getName());
case AUDIO:
return new Audio("SoundModem");
case SOUND_MODEM:
return new SoundModem("SoundModem", context);
case LOOPBACK:
default:
return new Loopback();

Wyświetl plik

@ -291,7 +291,7 @@
<string name="log_item_group_holder_unknown_km">\? km</string>
<string name="log_view_group_item_icon_description">APRS icon</string>
<string name="settings_aprs_symbol_image_view_description">APRS symbols</string>
<string name="ports_audio_enable_title">Enable sound modem</string>
<string name="ports_audio_enable_summary">Send data and receive data through sound modem by using phone speaker and mic</string>
<string name="ports_sound_modem_enable_title">Enable sound modem</string>
<string name="ports_sound_modem_enable_summary">Send data and receive data through sound modem by using phone speaker and mic</string>
<string name="main_status_sound_modem">SoundModem</string>
</resources>

Wyświetl plik

@ -142,9 +142,9 @@
</Preference>
<SwitchPreference
app:key="ports_audio_enable"
app:title="@string/ports_audio_enable_title"
app:summary="@string/ports_audio_enable_summary"
app:key="ports_sound_modem_enable"
app:title="@string/ports_sound_modem_enable_title"
app:summary="@string/ports_sound_modem_enable_summary"
app:defaultValue="false">
</SwitchPreference>

Wyświetl plik

@ -24,6 +24,7 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
unsigned char *demodBits;
int Nbits;
int N;
int Ts;
};
static Context *getContext(jlong jp) {
@ -64,6 +65,7 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
conFsk->Nbits = fsk->Nbits;
conFsk->N = fsk->N;
conFsk->Ts = fsk->Ts;
conFsk->modBuf = (float*)malloc(conFsk->N);
conFsk->modBits = (uint8_t*)malloc(conFsk->Nbits);
@ -86,6 +88,11 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
return con->nbyte;
}
static jint fskDemodSamplesBufSize(JNIEnv * env, jclass clazz, jlong n) {
ContextFsk *conFsk = getContextFsk(n);
return sizeof(short) * (conFsk->N + 2 * conFsk->Ts);
}
static jint fskDemodBitsBufSize(JNIEnv * env, jclass clazz, jlong n) {
ContextFsk *conFsk = getContextFsk(n);
return sizeof(uint8_t) * conFsk->Nbits;
@ -96,6 +103,11 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
return conFsk->N;
}
static jint fskModBitsBufSize(JNIEnv * env, jclass clazz, jlong n) {
ContextFsk *conFsk = getContextFsk(n);
return conFsk->Nbits;
}
static jint destroy(JNIEnv *env, jclass clazz, jlong n) {
Context *con = getContext(n);
codec2_destroy(con->c2);
@ -193,7 +205,9 @@ namespace Java_com_ustadmobile_codec2_Codec2 {
{"fskModulate", "(J[S[B)J", (void *) fskModulate},
{"fskDemodulate", "(J[S[B)J", (void *) fskDemodulate},
{"fskDemodBitsBufSize","(J)I", (void *) fskDemodBitsBufSize},
{"fskModSamplesBufSize","(J)I", (void *) fskModSamplesBufSize}
{"fskModSamplesBufSize","(J)I", (void *) fskModSamplesBufSize},
{"fskDemodSamplesBufSize","(J)I", (void *) fskDemodSamplesBufSize},
{"fskModBitsBufSize", "(J)I", (void *) fskModBitsBufSize}
};
}

Wyświetl plik

@ -40,6 +40,8 @@ public class Codec2 {
public native static int fskDemodBitsBufSize(long conFsk);
public native static int fskModSamplesBufSize(long conFsk);
public native static int fskDemodSamplesBufSize(long conFsk);
public native static int fskModBitsBufSize(long conFsk);
public native static long fskModulate(long conFsk, short[] outputSamples, byte[] inputBits);
public native static long fskDemodulate(long conFsk, short[] inputSamples, byte[] outputBits);