diff --git a/android/speex_codec/src/main/cpp/speex_codec.cpp b/android/speex_codec/src/main/cpp/speex_codec.cpp index bd9cad6d..bab880d6 100644 --- a/android/speex_codec/src/main/cpp/speex_codec.cpp +++ b/android/speex_codec/src/main/cpp/speex_codec.cpp @@ -6,6 +6,7 @@ static jfieldID speexDecBits; static jfieldID speexDecState; static jfieldID speexPreprocessState; +static jfieldID gainField; static const int FLAG_PREPROCESSOR_DENOISE = 1; static const int FLAG_PREPROCESSOR_AGC = 2; @@ -20,6 +21,7 @@ Java_com_example_speex_1codec_SpeexCodec_decode(JNIEnv *env, jobject thiz, auto *out_frame_data = reinterpret_cast(env->GetDirectBufferAddress(out_frame)); auto *bits = reinterpret_cast(env->GetLongField(thiz, speexDecBits)); auto *dec_state = reinterpret_cast(env->GetLongField(thiz, speexDecState)); + auto gain = env->GetFloatField(thiz, gainField); int offset = has_header_byte ? 1 : 0; speex_bits_read_from(bits, reinterpret_cast(encoded_frame_data)+offset, encoded_frame_length-offset); int result = speex_decode_int(dec_state, bits, out_frame_data); @@ -29,6 +31,13 @@ Java_com_example_speex_1codec_SpeexCodec_decode(JNIEnv *env, jobject thiz, if (preprocess_state != nullptr) { speex_preprocess_run(preprocess_state, out_frame_data); } + int output_size = 0; + speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &output_size); + for (int i = 0; i < output_size; i++) { + float gained = static_cast(out_frame_data[i]) * gain; + float gained_clipped = std::clamp(gained, static_cast(SHRT_MIN), static_cast(SHRT_MAX)); + out_frame_data[i] = static_cast(gained_clipped); + } return result; } extern "C" @@ -67,6 +76,7 @@ Java_com_example_speex_1codec_SpeexCodec_initNative(JNIEnv *env, jobject thiz) { speexDecBits = env->GetFieldID(clazz, "speexDecBits", "J"); speexDecState = env->GetFieldID(clazz, "speexDecState", "J"); speexPreprocessState = env->GetFieldID(clazz, "speexPreprocessState", "J"); + gainField = env->GetFieldID(clazz, "gain", "F"); } extern "C" JNIEXPORT void JNICALL diff --git a/android/speex_codec/src/main/java/com/example/speex_codec/SpeexCodec.kt b/android/speex_codec/src/main/java/com/example/speex_codec/SpeexCodec.kt index 53b31c63..5b2c2b5a 100644 --- a/android/speex_codec/src/main/java/com/example/speex_codec/SpeexCodec.kt +++ b/android/speex_codec/src/main/java/com/example/speex_codec/SpeexCodec.kt @@ -3,7 +3,7 @@ package com.example.speex_codec import android.media.MediaCodec import java.nio.ByteBuffer -class SpeexCodec(private val sampleRate: Long, private val bitRate: Int, private val frameSize: Int, private val preprocessors: Set = emptySet()): AutoCloseable { +class SpeexCodec(private val sampleRate: Long, private val bitRate: Int, private val frameSize: Int, private val preprocessors: Set = emptySet(), private val gain: Float = 4.0f): AutoCloseable { enum class Preprocessor(val flagValue: Int) { DENOISE(1), AGC(2),