diff --git a/quiet/src/main/java/org/quietmodem/Quiet/FrameReceiverConfig.java b/quiet/src/main/java/org/quietmodem/Quiet/FrameReceiverConfig.java index 863f23c..2bec16e 100644 --- a/quiet/src/main/java/org/quietmodem/Quiet/FrameReceiverConfig.java +++ b/quiet/src/main/java/org/quietmodem/Quiet/FrameReceiverConfig.java @@ -5,6 +5,7 @@ import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; +import android.media.MediaRecorder; import android.os.Build; import android.util.Log; @@ -18,17 +19,20 @@ public class FrameReceiverConfig { private final long defaultNumBuffers = 3; private final long defaultBufferLength = 4096; private final int defaultSampleRate = 44100; + private final int defaultRecordingPreset = MediaRecorder.AudioSource.VOICE_RECOGNITION; long profile_ptr; long numBuffers; long bufferLength; int sampleRate; + int recordingPreset; public FrameReceiverConfig(android.content.Context c, String key) throws IOException { profile_ptr = nativeOpen(getDefaultProfiles(c), key); numBuffers = defaultNumBuffers; bufferLength = defaultBufferLength; sampleRate = defaultSampleRate; + recordingPreset = defaultRecordingPreset; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { AudioManager m = (AudioManager) c.getSystemService(Context.AUDIO_SERVICE); @@ -42,6 +46,7 @@ public FrameReceiverConfig(String profiles, String key) { numBuffers = defaultNumBuffers; bufferLength = defaultBufferLength; sampleRate = defaultSampleRate; + recordingPreset = defaultRecordingPreset; } public void setNumBuffers(long numBuffers) { @@ -54,6 +59,8 @@ public void setBufferLength(long bufferLength) { public void setSampleRate(int sampleRate) { this.sampleRate = sampleRate; } + public void setRecordingPreset(int recordingPreset) { this.recordingPreset = recordingPreset; } + public long getNumBuffers() { return numBuffers; } @@ -64,6 +71,8 @@ public long getBufferLength() { public int getSampleRate() { return sampleRate; } + public int getRecordingPreset() { return recordingPreset; } + public static String getDefaultProfiles(android.content.Context c) throws IOException { InputStream s = c.getResources().openRawResource(R.raw.quiet_profiles); byte[] profile_bytes = new byte[s.available()]; diff --git a/quiet/src/main/jni/network_interface.c b/quiet/src/main/jni/network_interface.c index 338769d..bc1eb88 100644 --- a/quiet/src/main/jni/network_interface.c +++ b/quiet/src/main/jni/network_interface.c @@ -75,7 +75,8 @@ quiet_lwip_android *lwip_android_create(JNIEnv *env, quiet_lwip_driver_config *c int encoder_sample_rate, size_t decoder_num_bufs, size_t decoder_buf_len, - int decoder_sample_rate) { + int decoder_sample_rate, + int decoder_recording_preset) { quiet_lwip_android *e = malloc(sizeof(quiet_lwip_android)); e->interface = quiet_lwip_create(conf, local_address, netmask, gateway); if (!e->interface) { @@ -98,7 +99,8 @@ quiet_lwip_android *lwip_android_create(JNIEnv *env, quiet_lwip_driver_config *c e->producer->produce = quiet_lwip_get_next_audio_packet; e->producer->produce_arg = e->interface; - e->consumer = opensl_consumer_create(decoder_num_bufs, decoder_buf_len, decoder_sample_rate); + e->consumer = opensl_consumer_create(decoder_num_bufs, decoder_buf_len, decoder_sample_rate, + decoder_recording_preset); e->consumer->consume = quiet_lwip_recv_audio_packet; e->consumer->consume_arg = e->interface; @@ -163,6 +165,7 @@ JNIEXPORT jvm_pointer JNICALL Java_org_quietmodem_Quiet_BaseNetworkInterface_nat } size_t decoder_num_bufs = (*env)->GetLongField(env, j_dec_profile, cache.decoder_profile.num_bufs); size_t decoder_buf_len = (*env)->GetLongField(env, j_dec_profile, cache.decoder_profile.buf_len); + int decoder_recording_preset = (*env)->GetIntField(env, j_dec_profile, cache.decoder_profile.recording_preset); jbyteArray j_hardware_addr = (jbyteArray)((*env)->GetObjectField(env, j_conf, cache.network_interface_config.hardware_address)); size_t hardware_addr_len = (*env)->GetArrayLength(env, j_hardware_addr); @@ -187,7 +190,8 @@ JNIEXPORT jvm_pointer JNICALL Java_org_quietmodem_Quiet_BaseNetworkInterface_nat l = lwip_android_create(env, conf, local_addr, netmask, gateway, sys, is_loopback, encoder_num_bufs, encoder_buf_len, conf->encoder_rate, - decoder_num_bufs, decoder_buf_len, conf->decoder_rate); + decoder_num_bufs, decoder_buf_len, conf->decoder_rate, + decoder_recording_preset); // l could be NULL and we may have exception thrown -- lwip_android_create handles this diff --git a/quiet/src/main/jni/opensl.c b/quiet/src/main/jni/opensl.c index 39c1646..0780afb 100644 --- a/quiet/src/main/jni/opensl.c +++ b/quiet/src/main/jni/opensl.c @@ -1,5 +1,18 @@ #include "quiet-jni.h" +typedef enum { + AUDIO_SOURCE_DEFAULT = 0, + AUDIO_SOURCE_MIC = 1, + AUDIO_SOURCE_VOICE_UPLINK = 2, + AUDIO_SOURCE_VOICE_DOWNLINK = 3, + AUDIO_SOURCE_VOICE_CALL = 4, + AUDIO_SOURCE_CAMCORDER = 5, + AUDIO_SOURCE_VOICE_RECOGNITION = 6, + AUDIO_SOURCE_VOICE_COMMUNICATION = 7, + AUDIO_SOURCE_CNT, + AUDIO_SOURCE_MAX = AUDIO_SOURCE_CNT - 1, +} audio_source_t; + SLresult quiet_opensl_system_create(quiet_opensl_system **sys_dest) { *sys_dest = calloc(1, sizeof(quiet_opensl_system)); quiet_opensl_system *sys_deref = *sys_dest; @@ -89,11 +102,13 @@ void opensl_producer_destroy(quiet_opensl_producer *p) { quiet_opensl_consumer *opensl_consumer_create(size_t num_buf, size_t num_frames, - int sample_rate) { + int sample_rate, + int recording_preset) { quiet_opensl_consumer *c = malloc(sizeof(quiet_opensl_consumer)); c->num_buf = num_buf; c->num_frames = num_frames; c->sample_rate = sample_rate; + c->recording_preset = recording_preset; c->buf = malloc(c->num_buf * sizeof(opensl_sample_t *)); c->buf_idx = 0; c->scratch = malloc(c->num_frames * sizeof(quiet_sample_t)); @@ -168,7 +183,6 @@ SLresult quiet_opensl_create_player(quiet_opensl_system *sys, bufferQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; bufferQueue.numBuffers = p->num_buf; - printf("sample rate %d\n", p->sample_rate); #ifdef QUIET_JNI_USE_FLOAT SLAndroidDataFormat_PCM_EX pcm; pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX; @@ -372,7 +386,18 @@ SLresult quiet_opensl_create_recorder(quiet_opensl_system *sys, SLAndroidConfigurationItf inputConfiguration; if ((*recorder)->GetInterface(recorder, SL_IID_ANDROIDCONFIGURATION, &inputConfiguration) == SL_RESULT_SUCCESS) { - SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; + SLuint32 presetValue; + if (c->recording_preset == AUDIO_SOURCE_MIC) { + presetValue = SL_ANDROID_RECORDING_PRESET_GENERIC; + } else if (c->recording_preset == AUDIO_SOURCE_VOICE_RECOGNITION) { + presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; + } else if (c->recording_preset == AUDIO_SOURCE_CAMCORDER) { + presetValue = SL_ANDROID_RECORDING_PRESET_CAMCORDER; + } else if (c->recording_preset == AUDIO_SOURCE_VOICE_COMMUNICATION) { + presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; + } else { + presetValue = SL_ANDROID_RECORDING_PRESET_NONE; + } SLuint32 performanceValue = SL_ANDROID_PERFORMANCE_NONE; (*inputConfiguration)->SetConfiguration(inputConfiguration, SL_ANDROID_KEY_RECORDING_PRESET, &presetValue, sizeof(SLuint32)); (*inputConfiguration)->SetConfiguration(inputConfiguration, SL_ANDROID_KEY_PERFORMANCE_MODE, &performanceValue, sizeof(SLuint32)); diff --git a/quiet/src/main/jni/quiet-jni.h b/quiet/src/main/jni/quiet-jni.h index ac07d33..f22dbcc 100644 --- a/quiet/src/main/jni/quiet-jni.h +++ b/quiet/src/main/jni/quiet-jni.h @@ -76,6 +76,7 @@ typedef struct { // number of samples is num_record_channels * buf_len size_t num_frames; int sample_rate; + int recording_preset; // scratch is a mono floating point buffer that we can give to // quiet_decoder_consume float *scratch; @@ -85,7 +86,8 @@ typedef struct { quiet_opensl_consumer *opensl_consumer_create(size_t num_buf, size_t num_frames, - int sample_rate); + int sample_rate, + int recording_preset); void opensl_consumer_destroy(quiet_opensl_consumer *c); typedef struct { @@ -240,6 +242,7 @@ typedef struct { jfieldID num_bufs; jfieldID buf_len; jfieldID sample_rate; + jfieldID recording_preset; } java_decoder_profile_cache; typedef struct { diff --git a/quiet/src/main/jni/receiver.c b/quiet/src/main/jni/receiver.c index d39b44a..479c528 100644 --- a/quiet/src/main/jni/receiver.c +++ b/quiet/src/main/jni/receiver.c @@ -32,7 +32,8 @@ void android_decoder_terminate(quiet_android_decoder *dec) { quiet_android_decoder *android_decoder_create(JNIEnv *env, const quiet_decoder_options *opt, quiet_android_system *sys, bool is_loopback, - size_t num_bufs, size_t buf_len, int sample_rate) { + size_t num_bufs, size_t buf_len, int sample_rate, + int recording_preset) { if (is_loopback) { // ignore user-supplied buffer lengths for loopback @@ -47,7 +48,7 @@ quiet_android_decoder *android_decoder_create(JNIEnv *env, const quiet_decoder_o throw_error(env, cache.system.init_exc_klass, decoder_error_format, quiet_get_last_error()); return NULL; } - d->consumer = opensl_consumer_create(num_bufs, buf_len, sample_rate); + d->consumer = opensl_consumer_create(num_bufs, buf_len, sample_rate, recording_preset); d->consumer->consume = quiet_android_record_callback; d->consumer->consume_arg = d->dec; d->is_loopback = is_loopback; @@ -75,8 +76,10 @@ JNIEXPORT jvm_pointer JNICALL Java_org_quietmodem_Quiet_BaseFrameReceiver_native size_t num_bufs = (*env)->GetLongField(env, conf, cache.decoder_profile.num_bufs); size_t buf_len = (*env)->GetLongField(env, conf, cache.decoder_profile.buf_len); int sample_rate = (*env)->GetIntField(env, conf, cache.decoder_profile.sample_rate); + int recording_preset = (*env)->GetIntField(env, conf, cache.decoder_profile.recording_preset); - quiet_android_decoder *dec = android_decoder_create(env, opt, sys, is_loopback, num_bufs, buf_len, sample_rate); + quiet_android_decoder *dec = android_decoder_create(env, opt, sys, is_loopback, num_bufs, + buf_len, sample_rate, recording_preset); return jvm_opaque_pointer(dec); } diff --git a/quiet/src/main/jni/system.c b/quiet/src/main/jni/system.c index b6764f7..964666c 100644 --- a/quiet/src/main/jni/system.c +++ b/quiet/src/main/jni/system.c @@ -300,6 +300,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { cache.decoder_profile.sample_rate = (*env)->GetFieldID(env, cache.decoder_profile.klass, "sampleRate", "I"); + cache.decoder_profile.recording_preset = + (*env)->GetFieldID(env, cache.decoder_profile.klass, "recordingPreset", "I"); + cache.encoder.ptr = (*env)->GetFieldID(env, cache.encoder.klass, "enc_ptr", "J");