Added echo canceller calibration & adaptive rate control settings

This commit is contained in:
Sylvain Berfini 2024-09-05 10:00:11 +02:00
parent ce4fed2197
commit 9fc9574369
4 changed files with 148 additions and 6 deletions

View file

@ -30,6 +30,7 @@ import org.linphone.core.AudioDevice
import org.linphone.core.Conference
import org.linphone.core.Core
import org.linphone.core.CoreListenerStub
import org.linphone.core.EcCalibratorStatus
import org.linphone.core.Factory
import org.linphone.core.FriendList
import org.linphone.core.Tunnel
@ -67,6 +68,10 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
// Calls settings
val echoCancellerEnabled = MutableLiveData<Boolean>()
val calibratedEchoCancellerValue = MutableLiveData<String>()
val adaptiveRateControlEnabled = MutableLiveData<Boolean>()
val videoEnabled = MutableLiveData<Boolean>()
val videoFecEnabled = MutableLiveData<Boolean>()
@ -187,12 +192,19 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
val videoCodecs = MutableLiveData<List<CodecModel>>()
private val coreListener = object : CoreListenerStub() {
@WorkerThread
override fun onAudioDevicesListUpdated(core: Core) {
Log.i(
"$TAG Audio devices list has changed, update available input/output audio devices list"
)
setupAudioDevices()
}
@WorkerThread
override fun onEcCalibrationResult(core: Core, status: EcCalibratorStatus, delayMs: Int) {
if (status == EcCalibratorStatus.InProgress) return
echoCancellerCalibrationFinished(status, delayMs)
}
}
init {
@ -232,6 +244,24 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
isUiSecureModeEnabled.postValue(corePreferences.enableSecureMode)
echoCancellerEnabled.postValue(core.isEchoCancellationEnabled)
val delay = core.echoCancellationCalibration
if (delay > 0) {
val label = AppUtils.getString(
R.string.settings_calls_calibrate_echo_canceller_done
).format(
delay
)
calibratedEchoCancellerValue.postValue(label)
} else if (delay == 0) {
calibratedEchoCancellerValue.postValue(
AppUtils.getString(
R.string.settings_calls_calibrate_echo_canceller_done_no_echo
)
)
}
adaptiveRateControlEnabled.postValue(core.isAdaptiveRateControlEnabled)
videoEnabled.postValue(core.isVideoEnabled)
videoFecEnabled.postValue(core.isFecEnabled)
vibrateDuringIncomingCall.postValue(core.isVibrationOnIncomingCallEnabled)
@ -312,6 +342,26 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
}
}
@UiThread
fun calibrateEchoCanceller() {
coreContext.postOnCoreThread { core ->
Log.i("$TAG Starting echo canceller calibration")
core.startEchoCancellerCalibration()
calibratedEchoCancellerValue.postValue(
AppUtils.getString(R.string.settings_calls_calibrate_echo_canceller_in_progress)
)
}
}
@UiThread
fun toggleAdaptiveRateControl() {
val newValue = adaptiveRateControlEnabled.value == false
coreContext.postOnCoreThread { core ->
core.isAdaptiveRateControlEnabled = newValue
adaptiveRateControlEnabled.postValue(newValue)
}
}
@UiThread
fun toggleEnableVideo() {
val newValue = videoEnabled.value == false
@ -697,4 +747,25 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
}
videoCodecs.postValue(videoCodecsList)
}
@WorkerThread
private fun echoCancellerCalibrationFinished(status: EcCalibratorStatus, delay: Int) {
val value = when (status) {
EcCalibratorStatus.DoneNoEcho -> {
echoCancellerEnabled.postValue(false)
AppUtils.getString(R.string.settings_calls_calibrate_echo_canceller_done_no_echo)
}
EcCalibratorStatus.Done -> {
echoCancellerEnabled.postValue(true)
AppUtils.getString(R.string.settings_calls_calibrate_echo_canceller_done).format(
delay
)
}
EcCalibratorStatus.Failed -> {
AppUtils.getString(R.string.settings_calls_calibrate_echo_canceller_failed)
}
else -> ""
}
calibratedEchoCancellerValue.postValue(value)
}
}

View file

@ -58,6 +58,65 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
android:id="@+id/calibrate_echo_canceller"
android:onClick="@{() -> viewModel.calibrateEchoCanceller()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="@dimen/screen_bottom_margin"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="@string/settings_calls_calibrate_echo_canceller_title"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/calibrated_echo_canceller"
app:layout_constraintTop_toBottomOf="@id/echo_canceller_subtitle"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_subtitle_style"
android:id="@+id/calibrated_echo_canceller"
android:onClick="@{() -> viewModel.calibrateEchoCanceller()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{viewModel.calibratedEchoCancellerValue, default=`0ms`}"
app:layout_constraintStart_toStartOf="@id/echo_canceller_switch"
app:layout_constraintEnd_toEndOf="@id/echo_canceller_switch"
app:layout_constraintTop_toTopOf="@id/calibrate_echo_canceller"
app:layout_constraintBottom_toBottomOf="@id/calibrate_echo_canceller"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
android:onClick="@{() -> viewModel.toggleAdaptiveRateControl()}"
android:id="@+id/adaptive_rate_control_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/settings_calls_adaptive_rate_control_title"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/adaptive_rate_control_switch"
app:layout_constraintBottom_toBottomOf="@id/adaptive_rate_control_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/adaptive_rate_control_switch"/>
<com.google.android.material.materialswitch.MaterialSwitch
style="@style/material_switch_style"
android:id="@+id/adaptive_rate_control_switch"
android:onClick="@{() -> viewModel.toggleAdaptiveRateControl()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.adaptiveRateControlEnabled}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/calibrate_echo_canceller" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
android:onClick="@{() -> viewModel.toggleEnableVideo()}"
@ -84,7 +143,7 @@
android:layout_marginEnd="16dp"
android:checked="@{viewModel.videoEnabled}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/echo_canceller_switch" />
app:layout_constraintTop_toBottomOf="@id/adaptive_rate_control_switch" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
@ -151,7 +210,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_marginStart="10dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="@dimen/screen_bottom_margin"

View file

@ -179,8 +179,14 @@
<string name="settings_security_enable_vfs_subtitle">Attention, vous ne pourrez pas revenir en arrière !</string>
<string name="settings_security_prevent_screenshots_title">Empêcher l\'interface d\'être enregistrée</string>
<string name="settings_calls_title">Appels</string>
<string name="settings_calls_echo_canceller_title">Utiliser l\'annulateur d\'écho</string>
<string name="settings_calls_echo_canceller_subtitle">Évite que de l\'écho soit entendu par votre correspondant</string>
<string name="settings_calls_echo_canceller_title">Utiliser l\'annulateur d\'écho logiciel</string>
<string name="settings_calls_echo_canceller_subtitle">Évite que de l\'écho soit entendu par votre correspondant si un annulateur matériel n\'est pas disponible</string>
<string name="settings_calls_calibrate_echo_canceller_title">Calibrer l\'annulateur d\'écho</string>
<string name="settings_calls_calibrate_echo_canceller_in_progress">en cours</string>
<string name="settings_calls_calibrate_echo_canceller_done_no_echo">pas d\'écho</string>
<string name="settings_calls_calibrate_echo_canceller_done">%s ms</string>
<string name="settings_calls_calibrate_echo_canceller_failed">échec</string>
<string name="settings_calls_adaptive_rate_control_title">Contrôle qualité adaptatif</string>
<string name="settings_calls_enable_video_title">Activer la vidéo</string>
<string name="settings_calls_enable_fec_title">Activer la FEC vidéo</string>
<string name="settings_calls_vibrate_while_ringing_title">Vibrer lors de la réception d\'un appel</string>

View file

@ -216,8 +216,14 @@
<string name="settings_security_enable_vfs_subtitle">Warning: once enabled it can\'t be disabled!</string>
<string name="settings_security_prevent_screenshots_title">Prevent interface from being recorded</string>
<string name="settings_calls_title">Calls</string>
<string name="settings_calls_echo_canceller_title">Use echo canceller</string>
<string name="settings_calls_echo_canceller_subtitle">Prevents echo from being heard by remote end</string>
<string name="settings_calls_echo_canceller_title">Use software echo canceller</string>
<string name="settings_calls_echo_canceller_subtitle">Prevents echo from being heard by remote end if no hardware echo canceller is available</string>
<string name="settings_calls_calibrate_echo_canceller_title">Calibrate echo canceller</string>
<string name="settings_calls_calibrate_echo_canceller_in_progress">in progress</string>
<string name="settings_calls_calibrate_echo_canceller_done_no_echo">no echo</string>
<string name="settings_calls_calibrate_echo_canceller_done">%s ms</string>
<string name="settings_calls_calibrate_echo_canceller_failed">failed</string>
<string name="settings_calls_adaptive_rate_control_title">Adaptive rate control</string>
<string name="settings_calls_enable_video_title">Enable video</string>
<string name="settings_calls_enable_fec_title">Enable video FEC</string>
<string name="settings_calls_vibrate_while_ringing_title">Vibrate while incoming call is ringing</string>