diff --git a/app/src/main/kotlin/com/tutpro/baresip/Api.kt b/app/src/main/kotlin/com/tutpro/baresip/Api.kt index 5bc2988b..0a73d6af 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Api.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Api.kt @@ -121,4 +121,6 @@ object Api { external fun module_load(module: String): Int external fun module_unload(module: String) + external fun create_AAudio_SessionId(): Int + } diff --git a/app/src/main/kotlin/com/tutpro/baresip/AudioActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/AudioActivity.kt index 396895b9..3cd41bbb 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AudioActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AudioActivity.kt @@ -151,6 +151,12 @@ class AudioActivity : AppCompatActivity() { aec = binding.Aec oldAec = modules.contains("webrtc_aecm.so") aec.isChecked = oldAec + aec.setOnClickListener { + if (!aec.isChecked) + if (!Utils.isAecSupported()) + Utils.alertView(this, getString(R.string.notice), + getString(R.string.no_hw_aec)) + } audioDelay = binding.AudioDelay audioDelay.setText("${BaresipService.audioDelay}") diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 7162d2c8..ea360d67 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -440,8 +440,7 @@ class BaresipService: Service() { activeNetwork = cm.activeNetwork Log.i(TAG, "Active network: $activeNetwork") - Log.d(TAG, "AEC/AGC/NS available = " + - "$aecAvailable/$agcAvailable/$nsAvailable") + Log.d(TAG, "AGC/NS available = $agcAvailable/$nsAvailable") val userAgent = Config.variable("user_agent") Thread { @@ -835,7 +834,7 @@ class BaresipService: Service() { am.mode = MODE_IN_COMMUNICATION call!!.status = "connected" if (recorderSessionId != 0) { - if (aecAvailable && !webrtcAec) { + if (Utils.isAecSupported() && !webrtcAec) { aec = AcousticEchoCanceler.create(recorderSessionId) if (aec != null) { if (!aec!!.getEnabled()) { @@ -845,9 +844,11 @@ class BaresipService: Service() { else Log.w(TAG, "Failed to enable AEC") } - } - else - Log.w(TAG, "Failed to create AEC") + } else + Log.w( + TAG, "Failed to create AEC for session " + + "$recorderSessionId" + ) } if (agcAvailable) { agc = AutomaticGainControl.create(recorderSessionId) @@ -857,8 +858,7 @@ class BaresipService: Service() { if (agc!!.getEnabled()) Log.d(TAG, "AGC is enabled") } - } - else + } else Log.w(TAG, "Failed to create AGC") } if (nsAvailable) { @@ -869,8 +869,7 @@ class BaresipService: Service() { if (ns!!.getEnabled()) Log.d(TAG, "ns is enabled") } - } - else + } else Log.w(TAG, "Failed to create NS") } recorderSessionId = 0 @@ -1618,7 +1617,6 @@ class BaresipService: Service() { // of those accounts that have auth username without auth password val aorPasswords = mutableMapOf() var audioFocusRequest: AudioFocusRequestCompat? = null - var aecAvailable = AcousticEchoCanceler.isAvailable() var agcAvailable = AutomaticGainControl.isAvailable() private val nsAvailable = NoiseSuppressor.isAvailable() private var aec: AcousticEchoCanceler? = null @@ -1646,6 +1644,7 @@ class BaresipService: Service() { .build() if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { Log.d(TAG, "requestAudioFocus granted") + am.mode = MODE_IN_COMMUNICATION if (isBluetoothHeadsetConnected(ctx)) startBluetoothSco(ctx, 250L, 3) } else { diff --git a/app/src/main/kotlin/com/tutpro/baresip/Config.kt b/app/src/main/kotlin/com/tutpro/baresip/Config.kt index c0b71aef..8ba61aa9 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Config.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Config.kt @@ -153,7 +153,8 @@ object Config { if ("${module}.so" in previousModules) config = "${config}module ${module}.so\n" - if ("webrtc_aecm.so" in previousModules || !File(configPath).exists()) { + if ((!Utils.isAecSupported() && !File(configPath).exists()) || + "webrtc_aecm.so" in previousModules) { config = "${config}module webrtc_aecm.so\n" BaresipService.webrtcAec = true } diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index 18335867..d669ae85 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -26,6 +26,7 @@ import android.widget.TextView import android.media.AudioDeviceInfo import android.media.AudioManager import android.media.MediaPlayer +import android.media.audiofx.AcousticEchoCanceler import android.os.* import androidx.activity.result.ActivityResultLauncher import androidx.annotation.RequiresApi @@ -1047,4 +1048,27 @@ object Utils { Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES } + fun isAecSupported(): Boolean { + if (!AcousticEchoCanceler.isAvailable()) { + Log.i(TAG, "Hardware AEC is NOT available") + return false + } + + val sessionId = Api.create_AAudio_SessionId() + if (sessionId == -1) { + Log.e(TAG, "Failed to create AAudio stream for session ID") + return false + } + + val aec = AcousticEchoCanceler.create(sessionId) + return if (aec != null) { + aec.release() // Clean up the AEC instance + Log.i(TAG, "Hardware AEC is supported") + true + } else { + Log.w(TAG, "Hardware AEC is NOT supported") + false + } + } + } diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 914c7a5b..193371d2 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -365,8 +365,8 @@ Modulin lataaminen epäonnistui. Akustinen kaiun poisto (AKP) - Jos merkitty, kaikua yritetään poistaa ohjelmiston avulla - puheluiden aikana. + Jos merkitty, kaikua yritetään poistaa ohjelmiston avulla. + Laitteellasi ei voida poistaa kaikua laitteiston avulla. AKP laajennettu suodatin Mikrofonin äänikerroin Kertoo mikrofonin äänen voimakkuuden tällä desimaaliluvulla. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9df0738f..5aa2721c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -340,7 +340,8 @@ available for use by the accounts. Failed to load module. Acoustic Echo Cancellation - If checked, software echo cancellation is attempted on call audio. + If checked, software based echo cancellation is in use. + Hardware based echo canceller cannot be used on you device. AEC Extended Filter If checked, echo cancellation is using extended filter. Microphone Gain