Improved creation of AEC, AGC and NS
Added 500 ms delay to unloading mixminus module after last call close Improved ensuring communication mode
This commit is contained in:
@ -19,6 +19,7 @@ import android.content.res.Configuration
|
|||||||
import android.database.ContentObserver
|
import android.database.ContentObserver
|
||||||
import android.graphics.ImageDecoder
|
import android.graphics.ImageDecoder
|
||||||
import android.media.AudioAttributes
|
import android.media.AudioAttributes
|
||||||
|
import android.media.AudioDeviceInfo
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.media.AudioManager.MODE_IN_COMMUNICATION
|
import android.media.AudioManager.MODE_IN_COMMUNICATION
|
||||||
import android.media.AudioManager.MODE_NORMAL
|
import android.media.AudioManager.MODE_NORMAL
|
||||||
@ -671,47 +672,49 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ev[0] == "recorder sessionid") {
|
if (ev[0] == "recorder sessionid") {
|
||||||
recorderSessionId = ev[1].toInt()
|
val sessionId = ev[1].toInt()
|
||||||
Log.d(TAG, "got recorder sessionid $recorderSessionId")
|
if (sessionId > 0 && sessionId != recorderSessionId) {
|
||||||
if (recorderSessionId != 0) {
|
Log.d(TAG, "got new recorder sessionid $sessionId (was $recorderSessionId)")
|
||||||
|
recorderSessionId = sessionId
|
||||||
|
aec?.release()
|
||||||
|
aec = null
|
||||||
|
agc?.release()
|
||||||
|
agc = null
|
||||||
|
ns?.release()
|
||||||
|
ns = null
|
||||||
if (aecAvailable) {
|
if (aecAvailable) {
|
||||||
aec = AcousticEchoCanceler.create(recorderSessionId)
|
try {
|
||||||
if (aec != null) {
|
aec = AcousticEchoCanceler.create(sessionId)
|
||||||
if (!aec!!.enabled) {
|
if (aec != null) {
|
||||||
aec!!.enabled = true
|
aec!!.enabled = true
|
||||||
if (aec!!.enabled)
|
Log.d(TAG, "AEC is ${if (aec!!.enabled) "enabled" else "not enabled"}")
|
||||||
Log.d(TAG, "AEC is enabled")
|
|
||||||
else
|
|
||||||
Log.w(TAG, "Failed to enable AEC")
|
|
||||||
}
|
}
|
||||||
else
|
} catch (e: Exception) {
|
||||||
Log.d(TAG, "AEC is already enabled")
|
Log.e(TAG, "Exception creating AEC: $e")
|
||||||
} else
|
}
|
||||||
Log.w(TAG, "Failed to create AEC for session $recorderSessionId")
|
|
||||||
}
|
}
|
||||||
if (agcAvailable) {
|
if (agcAvailable) {
|
||||||
agc = AutomaticGainControl.create(recorderSessionId)
|
try {
|
||||||
if (agc != null) {
|
agc = AutomaticGainControl.create(sessionId)
|
||||||
if (!agc!!.enabled) {
|
if (agc != null) {
|
||||||
agc!!.enabled = true
|
agc!!.enabled = true
|
||||||
if (agc!!.enabled)
|
Log.d(TAG, "AGC is ${if (agc!!.enabled) "enabled" else "not enabled"}")
|
||||||
Log.d(TAG, "AGC is enabled")
|
|
||||||
}
|
}
|
||||||
} else
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Failed to create AGC")
|
Log.e(TAG, "Exception creating AGC: $e")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nsAvailable) {
|
if (nsAvailable) {
|
||||||
ns = NoiseSuppressor.create(recorderSessionId)
|
try {
|
||||||
if (ns != null) {
|
ns = NoiseSuppressor.create(sessionId)
|
||||||
if (!ns!!.enabled) {
|
if (ns != null) {
|
||||||
ns!!.enabled = true
|
ns!!.enabled = true
|
||||||
if (ns!!.enabled)
|
Log.d(TAG, "NS is ${if (ns!!.enabled) "enabled" else "failed to enable"}")
|
||||||
Log.d(TAG, "NS is enabled")
|
|
||||||
}
|
}
|
||||||
} else
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Failed to create NS")
|
Log.e(TAG, "Exception creating NS: $e")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
recorderSessionId = 0
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -996,6 +999,10 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
"call closed" -> {
|
"call closed" -> {
|
||||||
Log.d(TAG, "AoR $aor call $callp is closed prm: ${ev[1]}")
|
Log.d(TAG, "AoR $aor call $callp is closed prm: ${ev[1]}")
|
||||||
|
if (call != null) {
|
||||||
|
call.terminated.value = true
|
||||||
|
call.remove()
|
||||||
|
}
|
||||||
ConnectionService.lastDisconnectTime = System.currentTimeMillis()
|
ConnectionService.lastDisconnectTime = System.currentTimeMillis()
|
||||||
val connection = ConnectionService.connections[callp]
|
val connection = ConnectionService.connections[callp]
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
@ -1016,12 +1023,6 @@ class BaresipService: Service() {
|
|||||||
if (call != null) {
|
if (call != null) {
|
||||||
stopRinging()
|
stopRinging()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
aec?.release()
|
|
||||||
aec = null
|
|
||||||
agc?.release()
|
|
||||||
agc = null
|
|
||||||
ns?.release()
|
|
||||||
ns = null
|
|
||||||
val newCall = call.newCall
|
val newCall = call.newCall
|
||||||
if (newCall != null) {
|
if (newCall != null) {
|
||||||
newCall.onHoldCall = null
|
newCall.onHoldCall = null
|
||||||
@ -1034,10 +1035,26 @@ class BaresipService: Service() {
|
|||||||
call.onHoldCall = null
|
call.onHoldCall = null
|
||||||
}
|
}
|
||||||
val isConference = call.conferenceCall
|
val isConference = call.conferenceCall
|
||||||
call.remove()
|
val hasOtherCalls = calls.any { it.ua == ua }
|
||||||
|
if (calls.isEmpty()) {
|
||||||
|
aec?.release()
|
||||||
|
aec = null
|
||||||
|
agc?.release()
|
||||||
|
agc = null
|
||||||
|
ns?.release()
|
||||||
|
ns = null
|
||||||
|
recorderSessionId = 0
|
||||||
|
}
|
||||||
updateStatusNotification()
|
updateStatusNotification()
|
||||||
if (isConference && ua.calls().isEmpty())
|
if (isConference && !hasOtherCalls) {
|
||||||
Api.module_unload("mixminus")
|
Log.d(TAG, "Last conference call closed, scheduling mixminus unload")
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
if (calls.none { it.conferenceCall }) {
|
||||||
|
Log.d(TAG, "Unloading mixminus module")
|
||||||
|
Api.module_unload("mixminus")
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
val reason = ev[1]
|
val reason = ev[1]
|
||||||
val tone = ev[2]
|
val tone = ev[2]
|
||||||
if (tone == "busy")
|
if (tone == "busy")
|
||||||
@ -1049,6 +1066,7 @@ class BaresipService: Service() {
|
|||||||
!reason.startsWith("408") &&
|
!reason.startsWith("408") &&
|
||||||
!reason.startsWith("480") &&
|
!reason.startsWith("480") &&
|
||||||
!reason.startsWith("Connection reset by")
|
!reason.startsWith("Connection reset by")
|
||||||
|
|
||||||
val missed = call.dir == "in" && call.startTime == null && !call.rejected
|
val missed = call.dir == "in" && call.startTime == null && !call.rejected
|
||||||
val completedElsewhere = missed && ev[2].startsWith("SIP") &&
|
val completedElsewhere = missed && ev[2].startsWith("SIP") &&
|
||||||
ev[2].contains(";cause=200")
|
ev[2].contains(";cause=200")
|
||||||
@ -1900,28 +1918,55 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ensureCommunicationMode() {
|
private fun ensureCommunicationMode() {
|
||||||
if (Call.inCall()) {
|
val targetMode = if (Call.inCall()) MODE_IN_COMMUNICATION else MODE_NORMAL
|
||||||
if (am.mode != MODE_IN_COMMUNICATION) {
|
val currentMode = am.mode
|
||||||
am.mode = MODE_IN_COMMUNICATION
|
val isSpeakerphoneOn = if (VERSION.SDK_INT >= 31)
|
||||||
Log.d(TAG, "Manual Mode Guard (SDK ${VERSION.SDK_INT}): Setting MODE_IN_COMMUNICATION")
|
am.communicationDevice?.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
|
||||||
}
|
else {
|
||||||
} else {
|
@Suppress("DEPRECATION")
|
||||||
if (am.mode != MODE_NORMAL) {
|
am.isSpeakerphoneOn
|
||||||
am.mode = MODE_NORMAL
|
|
||||||
Log.d(TAG, "Manual Mode Guard (SDK ${VERSION.SDK_INT}): Resetting to MODE_NORMAL")
|
|
||||||
}
|
|
||||||
Utils.clearCommunicationDevice(am)
|
|
||||||
if (speakerPhone) {
|
|
||||||
speakerPhone = false
|
|
||||||
postServiceEvent(ServiceEvent("speaker update,false", arrayListOf(0L, 0L), System.nanoTime()))
|
|
||||||
}
|
|
||||||
if (isMicMuted) {
|
|
||||||
isMicMuted = false
|
|
||||||
postServiceEvent(ServiceEvent("mic muted,false", arrayListOf(0L, 0L), System.nanoTime()))
|
|
||||||
}
|
|
||||||
resetCallVolume()
|
|
||||||
proximitySensing(false)
|
|
||||||
}
|
}
|
||||||
|
if (targetMode == currentMode && (targetMode == MODE_NORMAL || isSpeakerphoneOn == speakerPhone)) {
|
||||||
|
Log.d(TAG, "ensureCommunicationMode: Already in $targetMode with correct speaker state, skipping.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log.d(TAG, "Scheduling ensureCommunicationMode ($targetMode) in 500ms")
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
if (Call.inCall()) {
|
||||||
|
if (am.mode != MODE_IN_COMMUNICATION) {
|
||||||
|
am.mode = MODE_IN_COMMUNICATION
|
||||||
|
Log.d(TAG, "Manual Mode Guard (SDK ${VERSION.SDK_INT}): Setting MODE_IN_COMMUNICATON")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (am.mode != MODE_NORMAL) {
|
||||||
|
am.mode = MODE_NORMAL
|
||||||
|
Log.d(TAG, "Manual Mode Guard (SDK ${VERSION.SDK_INT}): Resetting to MODE_NORMAL")
|
||||||
|
Utils.clearCommunicationDevice(am)
|
||||||
|
if (speakerPhone) {
|
||||||
|
speakerPhone = false
|
||||||
|
postServiceEvent(
|
||||||
|
ServiceEvent(
|
||||||
|
"speaker update,false",
|
||||||
|
arrayListOf(0L, 0L),
|
||||||
|
System.nanoTime()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (isMicMuted) {
|
||||||
|
isMicMuted = false
|
||||||
|
postServiceEvent(
|
||||||
|
ServiceEvent(
|
||||||
|
"mic muted,false",
|
||||||
|
arrayListOf(0L, 0L),
|
||||||
|
System.nanoTime()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
resetCallVolume()
|
||||||
|
proximitySensing(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("WakelockTimeout", "Wakelock")
|
@SuppressLint("WakelockTimeout", "Wakelock")
|
||||||
@ -2194,8 +2239,13 @@ 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 aecAvailable = false
|
var aecAvailable = false
|
||||||
private var aec: AcousticEchoCanceler? = null
|
|
||||||
var agcAvailable = false
|
var agcAvailable = false
|
||||||
|
var nsAvailable = false
|
||||||
|
private var aec: AcousticEchoCanceler? = null
|
||||||
|
private var agc: AutomaticGainControl? = null
|
||||||
|
private var ns: NoiseSuppressor? = null
|
||||||
|
private var recorderSessionId = 0
|
||||||
|
|
||||||
var rt: Ringtone? = null
|
var rt: Ringtone? = null
|
||||||
|
|
||||||
var colorblind = false
|
var colorblind = false
|
||||||
@ -2206,11 +2256,6 @@ class BaresipService: Service() {
|
|||||||
val circleRed = mapOf(true to R.drawable.circle_red_blind,
|
val circleRed = mapOf(true to R.drawable.circle_red_blind,
|
||||||
false to R.drawable.circle_red)
|
false to R.drawable.circle_red)
|
||||||
|
|
||||||
private var agc: AutomaticGainControl? = null
|
|
||||||
private val nsAvailable = NoiseSuppressor.isAvailable()
|
|
||||||
private var ns: NoiseSuppressor? = null
|
|
||||||
private var recorderSessionId = 0
|
|
||||||
|
|
||||||
internal const val KEY_TEXT_REPLY = "key_text_reply_baresip"
|
internal const val KEY_TEXT_REPLY = "key_text_reply_baresip"
|
||||||
private const val PHONE_ACCOUNT_ID = "baresip_phone_account"
|
private const val PHONE_ACCOUNT_ID = "baresip_phone_account"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user