Added check if hardware AEC is available
This commit is contained in:
@@ -121,4 +121,6 @@ object Api {
|
|||||||
external fun module_load(module: String): Int
|
external fun module_load(module: String): Int
|
||||||
external fun module_unload(module: String)
|
external fun module_unload(module: String)
|
||||||
|
|
||||||
|
external fun create_AAudio_SessionId(): Int
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,6 +151,12 @@ class AudioActivity : AppCompatActivity() {
|
|||||||
aec = binding.Aec
|
aec = binding.Aec
|
||||||
oldAec = modules.contains("webrtc_aecm.so")
|
oldAec = modules.contains("webrtc_aecm.so")
|
||||||
aec.isChecked = oldAec
|
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 = binding.AudioDelay
|
||||||
audioDelay.setText("${BaresipService.audioDelay}")
|
audioDelay.setText("${BaresipService.audioDelay}")
|
||||||
|
|||||||
@@ -440,8 +440,7 @@ class BaresipService: Service() {
|
|||||||
activeNetwork = cm.activeNetwork
|
activeNetwork = cm.activeNetwork
|
||||||
Log.i(TAG, "Active network: $activeNetwork")
|
Log.i(TAG, "Active network: $activeNetwork")
|
||||||
|
|
||||||
Log.d(TAG, "AEC/AGC/NS available = " +
|
Log.d(TAG, "AGC/NS available = $agcAvailable/$nsAvailable")
|
||||||
"$aecAvailable/$agcAvailable/$nsAvailable")
|
|
||||||
|
|
||||||
val userAgent = Config.variable("user_agent")
|
val userAgent = Config.variable("user_agent")
|
||||||
Thread {
|
Thread {
|
||||||
@@ -835,7 +834,7 @@ class BaresipService: Service() {
|
|||||||
am.mode = MODE_IN_COMMUNICATION
|
am.mode = MODE_IN_COMMUNICATION
|
||||||
call!!.status = "connected"
|
call!!.status = "connected"
|
||||||
if (recorderSessionId != 0) {
|
if (recorderSessionId != 0) {
|
||||||
if (aecAvailable && !webrtcAec) {
|
if (Utils.isAecSupported() && !webrtcAec) {
|
||||||
aec = AcousticEchoCanceler.create(recorderSessionId)
|
aec = AcousticEchoCanceler.create(recorderSessionId)
|
||||||
if (aec != null) {
|
if (aec != null) {
|
||||||
if (!aec!!.getEnabled()) {
|
if (!aec!!.getEnabled()) {
|
||||||
@@ -845,9 +844,11 @@ class BaresipService: Service() {
|
|||||||
else
|
else
|
||||||
Log.w(TAG, "Failed to enable AEC")
|
Log.w(TAG, "Failed to enable AEC")
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
Log.w(
|
||||||
Log.w(TAG, "Failed to create AEC")
|
TAG, "Failed to create AEC for session " +
|
||||||
|
"$recorderSessionId"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (agcAvailable) {
|
if (agcAvailable) {
|
||||||
agc = AutomaticGainControl.create(recorderSessionId)
|
agc = AutomaticGainControl.create(recorderSessionId)
|
||||||
@@ -857,8 +858,7 @@ class BaresipService: Service() {
|
|||||||
if (agc!!.getEnabled())
|
if (agc!!.getEnabled())
|
||||||
Log.d(TAG, "AGC is enabled")
|
Log.d(TAG, "AGC is enabled")
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
Log.w(TAG, "Failed to create AGC")
|
Log.w(TAG, "Failed to create AGC")
|
||||||
}
|
}
|
||||||
if (nsAvailable) {
|
if (nsAvailable) {
|
||||||
@@ -869,8 +869,7 @@ class BaresipService: Service() {
|
|||||||
if (ns!!.getEnabled())
|
if (ns!!.getEnabled())
|
||||||
Log.d(TAG, "ns is enabled")
|
Log.d(TAG, "ns is enabled")
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
Log.w(TAG, "Failed to create NS")
|
Log.w(TAG, "Failed to create NS")
|
||||||
}
|
}
|
||||||
recorderSessionId = 0
|
recorderSessionId = 0
|
||||||
@@ -1618,7 +1617,6 @@ class BaresipService: Service() {
|
|||||||
// <aor, password> of those accounts that have auth username without auth password
|
// <aor, password> of those accounts that have auth username without auth password
|
||||||
val aorPasswords = mutableMapOf<String, String>()
|
val aorPasswords = mutableMapOf<String, String>()
|
||||||
var audioFocusRequest: AudioFocusRequestCompat? = null
|
var audioFocusRequest: AudioFocusRequestCompat? = null
|
||||||
var aecAvailable = AcousticEchoCanceler.isAvailable()
|
|
||||||
var agcAvailable = AutomaticGainControl.isAvailable()
|
var agcAvailable = AutomaticGainControl.isAvailable()
|
||||||
private val nsAvailable = NoiseSuppressor.isAvailable()
|
private val nsAvailable = NoiseSuppressor.isAvailable()
|
||||||
private var aec: AcousticEchoCanceler? = null
|
private var aec: AcousticEchoCanceler? = null
|
||||||
@@ -1646,6 +1644,7 @@ class BaresipService: Service() {
|
|||||||
.build()
|
.build()
|
||||||
if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||||
Log.d(TAG, "requestAudioFocus granted")
|
Log.d(TAG, "requestAudioFocus granted")
|
||||||
|
am.mode = MODE_IN_COMMUNICATION
|
||||||
if (isBluetoothHeadsetConnected(ctx))
|
if (isBluetoothHeadsetConnected(ctx))
|
||||||
startBluetoothSco(ctx, 250L, 3)
|
startBluetoothSco(ctx, 250L, 3)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ object Config {
|
|||||||
if ("${module}.so" in previousModules)
|
if ("${module}.so" in previousModules)
|
||||||
config = "${config}module ${module}.so\n"
|
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"
|
config = "${config}module webrtc_aecm.so\n"
|
||||||
BaresipService.webrtcAec = true
|
BaresipService.webrtcAec = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import android.widget.TextView
|
|||||||
import android.media.AudioDeviceInfo
|
import android.media.AudioDeviceInfo
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.media.MediaPlayer
|
import android.media.MediaPlayer
|
||||||
|
import android.media.audiofx.AcousticEchoCanceler
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
@@ -1047,4 +1048,27 @@ object Utils {
|
|||||||
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -365,8 +365,8 @@
|
|||||||
</string>
|
</string>
|
||||||
<string name="failed_to_load_module">Modulin lataaminen epäonnistui.</string>
|
<string name="failed_to_load_module">Modulin lataaminen epäonnistui.</string>
|
||||||
<string name="aec">Akustinen kaiun poisto (AKP)</string>
|
<string name="aec">Akustinen kaiun poisto (AKP)</string>
|
||||||
<string name="aec_help">Jos merkitty, kaikua yritetään poistaa ohjelmiston avulla
|
<string name="aec_help">Jos merkitty, kaikua yritetään poistaa ohjelmiston avulla.</string>
|
||||||
puheluiden aikana.</string>
|
<string name="no_hw_aec">Laitteellasi ei voida poistaa kaikua laitteiston avulla.</string>
|
||||||
<string name="aec_extended_filter">AKP laajennettu suodatin</string>
|
<string name="aec_extended_filter">AKP laajennettu suodatin</string>
|
||||||
<string name="microphone_gain">Mikrofonin äänikerroin</string>
|
<string name="microphone_gain">Mikrofonin äänikerroin</string>
|
||||||
<string name="microphone_gain_help">Kertoo mikrofonin äänen voimakkuuden tällä desimaaliluvulla.
|
<string name="microphone_gain_help">Kertoo mikrofonin äänen voimakkuuden tällä desimaaliluvulla.
|
||||||
|
|||||||
@@ -340,7 +340,8 @@
|
|||||||
available for use by the accounts.</string>
|
available for use by the accounts.</string>
|
||||||
<string name="failed_to_load_module">Failed to load module.</string>
|
<string name="failed_to_load_module">Failed to load module.</string>
|
||||||
<string name="aec">Acoustic Echo Cancellation</string>
|
<string name="aec">Acoustic Echo Cancellation</string>
|
||||||
<string name="aec_help">If checked, software echo cancellation is attempted on call audio.</string>
|
<string name="aec_help">If checked, software based echo cancellation is in use.</string>
|
||||||
|
<string name="no_hw_aec">Hardware based echo canceller cannot be used on you device.</string>
|
||||||
<string name="aec_extended_filter">AEC Extended Filter</string>
|
<string name="aec_extended_filter">AEC Extended Filter</string>
|
||||||
<string name="aec_extended_filter_help">If checked, echo cancellation is using extended filter.</string>
|
<string name="aec_extended_filter_help">If checked, echo cancellation is using extended filter.</string>
|
||||||
<string name="microphone_gain">Microphone Gain</string>
|
<string name="microphone_gain">Microphone Gain</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user