dolby: Restore all settings upon bootup

Dolby often messes up restoring profile-specific settings after a reboot.
"Fine. I'll do it myself."

Change-Id: Ic255c6922eabae0b522c05110f87e2c10a97fb6c
This commit is contained in:
Adithya R 2024-07-09 18:39:18 +05:30 committed by basamaryan
parent d5620a07ee
commit 5b0e5a2afc
No known key found for this signature in database
GPG Key ID: 707BA6C82329E8F9
7 changed files with 271 additions and 136 deletions

View File

@ -21,7 +21,8 @@
<string name="dolby_category_settings">Settings</string>
<string name="dolby_bass_enhancer">Bass enhancer</string>
<string name="dolby_dialogue_enhancer">Dialogue enhancer</string>
<string name="dolby_virtualizer">Surround virtualizer</string>
<string name="dolby_spk_virtualizer">Speaker virtualization</string>
<string name="dolby_hp_virtualizer">Headphone virtualization</string>
<string name="dolby_stereo_widening">Stereo widening</string>
<string name="dolby_volume_leveler">Volume leveler</string>
<string name="dolby_connect_headphones">Connect headphones</string>

View File

@ -30,15 +30,18 @@
android:entryValues="@array/dolby_preset_values"
android:title="@string/dolby_preset" />
<SwitchPreference
android:key="dolby_spk_virtualizer"
android:title="@string/dolby_spk_virtualizer" />
<SwitchPreference
android:key="dolby_virtualizer"
android:title="@string/dolby_virtualizer" />
android:title="@string/dolby_hp_virtualizer" />
<ListPreference
android:key="dolby_stereo"
android:entries="@array/dolby_stereo_entries"
android:entryValues="@array/dolby_stereo_values"
android:defaultValue="4"
android:title="@string/dolby_stereo_widening"
android:dependency="dolby_virtualizer" />

View File

@ -46,7 +46,7 @@ class DolbyAudioEffect(priority: Int, audioSession: Int) : AudioEffect(
}
}
fun resetProfileSpecificSettings() {
fun resetProfileSpecificSettings(profile: Int = this.profile) {
dlog(TAG, "resetProfileSpecificSettings: profile=$profile")
setIntParam(EFFECT_PARAM_RESET_PROFILE_SETTINGS, profile)
}

View File

@ -31,13 +31,24 @@ class DolbyConstants {
const val PREF_ENABLE = "dolby_enable"
const val PREF_PROFILE = "dolby_profile"
const val PREF_PRESET = "dolby_preset"
const val PREF_VIRTUALIZER = "dolby_virtualizer"
const val PREF_HP_VIRTUALIZER = "dolby_virtualizer"
const val PREF_SPK_VIRTUALIZER = "dolby_spk_virtualizer"
const val PREF_STEREO = "dolby_stereo"
const val PREF_DIALOGUE = "dolby_dialogue"
const val PREF_BASS = "dolby_bass"
const val PREF_VOLUME = "dolby_volume"
const val PREF_RESET = "dolby_reset"
val PROFILE_SPECIFIC_PREFS = setOf(
PREF_PRESET,
PREF_HP_VIRTUALIZER,
PREF_SPK_VIRTUALIZER,
PREF_STEREO,
PREF_DIALOGUE,
PREF_BASS,
PREF_VOLUME
)
fun dlog(tag: String, msg: String) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(tag, msg)

View File

@ -90,99 +90,6 @@ internal class DolbyController private constructor(
dolbyEffect.profile = value
}
var preset: String
get() {
val gains = dolbyEffect.getDapParameter(DsParam.GEQ_BAND_GAINS)
return gains.joinToString(separator = ",").also {
dlog(TAG, "getPreset: $it")
}
}
set(value) {
dlog(TAG, "setPreset: $value")
checkEffect()
val gains = value.split(",")
.map { it.toInt() }
.toIntArray()
dolbyEffect.setDapParameter(DsParam.GEQ_BAND_GAINS, gains)
}
var headphoneVirtEnabled: Boolean
get() =
dolbyEffect.getDapParameterBool(DsParam.HEADPHONE_VIRTUALIZER).also {
dlog(TAG, "getHeadphoneVirtEnabled: $it")
}
set(value) {
dlog(TAG, "setHeadphoneVirtEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.HEADPHONE_VIRTUALIZER, value)
}
var speakerVirtEnabled: Boolean
get() =
dolbyEffect.getDapParameterBool(DsParam.SPEAKER_VIRTUALIZER).also {
dlog(TAG, "getSpeakerVirtEnabled: $it")
}
set(value) {
dlog(TAG, "setSpeakerVirtEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.SPEAKER_VIRTUALIZER, value)
}
var bassEnhancerEnabled: Boolean
get() =
dolbyEffect.getDapParameterBool(DsParam.BASS_ENHANCER_ENABLE).also {
dlog(TAG, "getBassEnhancerEnabled: $it")
}
set(value) {
dlog(TAG, "setBassEnhancerEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.BASS_ENHANCER_ENABLE, value)
}
var volumeLevelerEnabled: Boolean
get() {
val enabled = dolbyEffect.getDapParameterBool(DsParam.VOLUME_LEVELER_ENABLE)
val amount = dolbyEffect.getDapParameterInt(DsParam.VOLUME_LEVELER_AMOUNT)
dlog(TAG, "getVolumeLevelerEnabled: enabled=$enabled amount=$amount")
return enabled && amount > 0
}
set(value) {
dlog(TAG, "setVolumeLevelerEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.VOLUME_LEVELER_ENABLE, value)
dolbyEffect.setDapParameter(
DsParam.VOLUME_LEVELER_AMOUNT,
if (value) VOLUME_LEVELER_AMOUNT else 0
)
}
var stereoWideningAmount: Int
get() =
dolbyEffect.getDapParameterInt(DsParam.STEREO_WIDENING_AMOUNT).also {
dlog(TAG, "getStereoWideningAmount: $it")
}
set(value) {
dlog(TAG, "setStereoWideningAmount: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.STEREO_WIDENING_AMOUNT, value)
}
var dialogueEnhancerAmount: Int
get() {
val enabled = dolbyEffect.getDapParameterBool(DsParam.DIALOGUE_ENHANCER_ENABLE)
val amount = if (enabled) {
dolbyEffect.getDapParameterInt(DsParam.DIALOGUE_ENHANCER_AMOUNT)
} else 0
dlog(TAG, "getDialogueEnhancerAmount: enabled=$enabled amount=$amount")
return amount
}
set(value) {
dlog(TAG, "setDialogueEnhancerAmount: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.DIALOGUE_ENHANCER_ENABLE, (value > 0))
dolbyEffect.setDapParameter(DsParam.DIALOGUE_ENHANCER_AMOUNT, value)
}
init {
dlog(TAG, "initialized")
}
@ -190,12 +97,58 @@ internal class DolbyController private constructor(
fun onBootCompleted() {
dlog(TAG, "onBootCompleted")
// Restore current profile now and on certain audio changes.
val on = dsOn
dolbyEffect.enabled = on
registerCallbacks = on
if (on)
setCurrentProfile()
// Restore our main settings
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
dsOn = prefs.getBoolean(DolbyConstants.PREF_ENABLE, true)
setCurrentProfile()
context.resources.getStringArray(R.array.dolby_profile_values)
.map { it.toInt() }
.forEach { profile ->
// Reset dolby first to prevent it from loading bad settings
dolbyEffect.resetProfileSpecificSettings(profile)
// Now restore our profile-specific settings
restoreSettings(profile)
}
}
private fun restoreSettings(profile: Int) {
dlog(TAG, "restoreSettings(profile=$profile)")
val prefs = context.getSharedPreferences("profile_$profile", Context.MODE_PRIVATE)
setPreset(
prefs.getString(DolbyConstants.PREF_PRESET, getPreset(profile)),
profile
)
setHeadphoneVirtEnabled(
prefs.getBoolean(DolbyConstants.PREF_HP_VIRTUALIZER, getHeadphoneVirtEnabled(profile)),
profile
)
setSpeakerVirtEnabled(
prefs.getBoolean(DolbyConstants.PREF_SPK_VIRTUALIZER, getSpeakerVirtEnabled(profile)),
profile
)
setStereoWideningAmount(
prefs.getString(
DolbyConstants.PREF_STEREO,
getStereoWideningAmount(profile).toString()
).toInt(),
profile
)
setDialogueEnhancerAmount(
prefs.getString(
DolbyConstants.PREF_DIALOGUE,
getDialogueEnhancerAmount(profile).toString()
).toInt(),
profile
)
setBassEnhancerEnabled(
prefs.getBoolean(DolbyConstants.PREF_BASS, getBassEnhancerEnabled(profile)),
profile
)
setVolumeLevelerEnabled(
prefs.getBoolean(DolbyConstants.PREF_VOLUME, getVolumeLevelerEnabled(profile)),
profile
)
}
private fun checkEffect() {
@ -207,10 +160,6 @@ internal class DolbyController private constructor(
}
private fun setCurrentProfile() {
if (!dsOn) {
dlog(TAG, "setCurrentProfile: skip, dolby is off")
return
}
dlog(TAG, "setCurrentProfile")
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
profile = prefs.getString(DolbyConstants.PREF_PROFILE, "0" /*dynamic*/).toInt()
@ -227,8 +176,104 @@ internal class DolbyController private constructor(
}
fun resetProfileSpecificSettings() {
dlog(TAG, "resetProfileSpecificSettings")
checkEffect()
dolbyEffect.resetProfileSpecificSettings()
context.deleteSharedPreferences("profile_$profile")
}
fun getPreset(profile: Int = this.profile): String {
val gains = dolbyEffect.getDapParameter(DsParam.GEQ_BAND_GAINS, profile)
return gains.joinToString(separator = ",").also {
dlog(TAG, "getPreset: $it")
}
}
fun setPreset(value: String, profile: Int = this.profile) {
dlog(TAG, "setPreset: $value")
checkEffect()
val gains = value.split(",")
.map { it.toInt() }
.toIntArray()
dolbyEffect.setDapParameter(DsParam.GEQ_BAND_GAINS, gains, profile)
}
fun getHeadphoneVirtEnabled(profile: Int = this.profile) =
dolbyEffect.getDapParameterBool(DsParam.HEADPHONE_VIRTUALIZER, profile).also {
dlog(TAG, "getHeadphoneVirtEnabled: $it")
}
fun setHeadphoneVirtEnabled(value: Boolean, profile: Int = this.profile) {
dlog(TAG, "setHeadphoneVirtEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.HEADPHONE_VIRTUALIZER, value, profile)
}
fun getSpeakerVirtEnabled(profile: Int = this.profile) =
dolbyEffect.getDapParameterBool(DsParam.SPEAKER_VIRTUALIZER, profile).also {
dlog(TAG, "getSpeakerVirtEnabled: $it")
}
fun setSpeakerVirtEnabled(value: Boolean, profile: Int = this.profile) {
dlog(TAG, "setSpeakerVirtEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.SPEAKER_VIRTUALIZER, value, profile)
}
fun getBassEnhancerEnabled(profile: Int = this.profile) =
dolbyEffect.getDapParameterBool(DsParam.BASS_ENHANCER_ENABLE, profile).also {
dlog(TAG, "getBassEnhancerEnabled: $it")
}
fun setBassEnhancerEnabled(value: Boolean, profile: Int = this.profile) {
dlog(TAG, "setBassEnhancerEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.BASS_ENHANCER_ENABLE, value, profile)
}
fun getVolumeLevelerEnabled(profile: Int = this.profile): Boolean {
val enabled = dolbyEffect.getDapParameterBool(DsParam.VOLUME_LEVELER_ENABLE, profile)
val amount = dolbyEffect.getDapParameterInt(DsParam.VOLUME_LEVELER_AMOUNT, profile)
dlog(TAG, "getVolumeLevelerEnabled: enabled=$enabled amount=$amount")
return enabled && amount > 0
}
fun setVolumeLevelerEnabled(value: Boolean, profile: Int = this.profile) {
dlog(TAG, "setVolumeLevelerEnabled: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.VOLUME_LEVELER_ENABLE, value, profile)
dolbyEffect.setDapParameter(
DsParam.VOLUME_LEVELER_AMOUNT,
if (value) VOLUME_LEVELER_AMOUNT else 0,
profile
)
}
fun getStereoWideningAmount(profile: Int = this.profile) =
dolbyEffect.getDapParameterInt(DsParam.STEREO_WIDENING_AMOUNT, profile).also {
dlog(TAG, "getStereoWideningAmount: $it")
}
fun setStereoWideningAmount(value: Int, profile: Int = this.profile) {
dlog(TAG, "setStereoWideningAmount: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.STEREO_WIDENING_AMOUNT, value, profile)
}
fun getDialogueEnhancerAmount(profile: Int = this.profile): Int {
val enabled = dolbyEffect.getDapParameterBool(DsParam.DIALOGUE_ENHANCER_ENABLE, profile)
val amount = if (enabled) {
dolbyEffect.getDapParameterInt(DsParam.DIALOGUE_ENHANCER_AMOUNT, profile)
} else 0
dlog(TAG, "getDialogueEnhancerAmount: enabled=$enabled amount=$amount")
return amount
}
fun setDialogueEnhancerAmount(value: Int, profile: Int = this.profile) {
dlog(TAG, "setDialogueEnhancerAmount: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.DIALOGUE_ENHANCER_ENABLE, (value > 0), profile)
dolbyEffect.setDapParameter(DsParam.DIALOGUE_ENHANCER_AMOUNT, value, profile)
}
companion object {

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2024 Paranoid Android
*
* SPDX-License-Identifier: Apache-2.0
*/
package co.aospa.dolby.xiaomi
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceDataStore
import androidx.preference.PreferenceManager
class DolbyPreferenceStore(
private val context: Context
) : PreferenceDataStore() {
private val defaultSharedPrefs by lazy {
PreferenceManager.getDefaultSharedPreferences(context)
}
private lateinit var profileSharedPrefs: SharedPreferences
var profile = 0
set(value) {
field = value
profileSharedPrefs = context.getSharedPreferences(
"profile_$value",
Context.MODE_PRIVATE
)
}
private fun getSharedPreferences(key: String) =
if (DolbyConstants.PROFILE_SPECIFIC_PREFS.contains(key)) {
profileSharedPrefs
} else {
defaultSharedPrefs
}
override fun putBoolean(key: String, value: Boolean) =
getSharedPreferences(key).edit()
.putBoolean(key, value)
.apply()
override fun getBoolean(key: String, defValue: Boolean) =
getSharedPreferences(key).getBoolean(key, defValue)
override fun putInt(key: String, value: Int) =
getSharedPreferences(key).edit()
.putInt(key, value)
.apply()
override fun getInt(key: String, defValue: Int) =
getSharedPreferences(key).getInt(key, defValue)
override fun putString(key: String, value: String?) =
getSharedPreferences(key).edit()
.putString(key, value)
.apply()
override fun getString(key: String, defValue: String?) =
getSharedPreferences(key).getString(key, defValue)
}

View File

@ -45,8 +45,11 @@ class DolbySettingsFragment : PreferenceFragment(),
private val bassPref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_BASS)!!
}
private val virtPref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_VIRTUALIZER)!!
private val hpVirtPref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_HP_VIRTUALIZER)!!
}
private val spkVirtPref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_SPK_VIRTUALIZER)!!
}
private val volumePref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_VOLUME)!!
@ -83,14 +86,17 @@ class DolbySettingsFragment : PreferenceFragment(),
dlog(TAG, "onCreatePreferences")
addPreferencesFromResource(R.xml.dolby_settings)
val profile = dolbyController.profile
preferenceManager.preferenceDataStore = DolbyPreferenceStore(context).also {
it.profile = profile
}
val dsOn = dolbyController.dsOn
switchBar.addOnSwitchChangeListener(this)
switchBar.setChecked(dsOn)
profilePref.onPreferenceChangeListener = this
profilePref.setEnabled(dsOn)
val profile = dolbyController.profile
profilePref.apply {
if (entryValues.contains(profile.toString())) {
summary = "%s"
@ -101,7 +107,8 @@ class DolbySettingsFragment : PreferenceFragment(),
}
presetPref.onPreferenceChangeListener = this
virtPref.onPreferenceChangeListener = this
hpVirtPref.onPreferenceChangeListener = this
spkVirtPref.onPreferenceChangeListener = this
stereoPref.onPreferenceChangeListener = this
dialoguePref.onPreferenceChangeListener = this
bassPref.onPreferenceChangeListener = this
@ -133,35 +140,38 @@ class DolbySettingsFragment : PreferenceFragment(),
dlog(TAG, "onPreferenceChange: key=${preference.key} value=$newValue")
when (preference.key) {
DolbyConstants.PREF_PROFILE -> {
dolbyController.profile = newValue.toString().toInt()
val profile = newValue.toString().toInt()
dolbyController.profile = profile
(preferenceManager.preferenceDataStore as DolbyPreferenceStore).profile = profile
updateProfileSpecificPrefs()
}
DolbyConstants.PREF_PRESET -> {
dolbyController.preset = newValue.toString()
dolbyController.setPreset(newValue.toString())
}
DolbyConstants.PREF_VIRTUALIZER -> {
if (isOnSpeaker)
dolbyController.speakerVirtEnabled = newValue as Boolean
else
dolbyController.headphoneVirtEnabled = newValue as Boolean
DolbyConstants.PREF_SPK_VIRTUALIZER -> {
dolbyController.setSpeakerVirtEnabled(newValue as Boolean)
}
DolbyConstants.PREF_HP_VIRTUALIZER -> {
dolbyController.setHeadphoneVirtEnabled(newValue as Boolean)
}
DolbyConstants.PREF_STEREO -> {
dolbyController.stereoWideningAmount = newValue.toString().toInt()
dolbyController.setStereoWideningAmount(newValue.toString().toInt())
}
DolbyConstants.PREF_DIALOGUE -> {
dolbyController.dialogueEnhancerAmount = newValue.toString().toInt()
dolbyController.setDialogueEnhancerAmount(newValue.toString().toInt())
}
DolbyConstants.PREF_BASS -> {
dolbyController.bassEnhancerEnabled = newValue as Boolean
dolbyController.setBassEnhancerEnabled(newValue as Boolean)
}
DolbyConstants.PREF_VOLUME -> {
dolbyController.volumeLevelerEnabled = newValue as Boolean
dolbyController.setVolumeLevelerEnabled(newValue as Boolean)
}
else -> return false
@ -194,16 +204,17 @@ class DolbySettingsFragment : PreferenceFragment(),
val enable = dsOn && (currentProfile != -1)
presetPref.setEnabled(enable)
virtPref.setEnabled(enable)
spkVirtPref.setEnabled(enable)
dialoguePref.setEnabled(enable)
volumePref.setEnabled(enable)
resetPref.setEnabled(enable)
hpVirtPref.setEnabled(enable && !isOnSpeaker)
stereoPref.setEnabled(enable && !isOnSpeaker)
bassPref.setEnabled(enable && !isOnSpeaker)
if (!enable) return
val preset = dolbyController.preset
val preset = dolbyController.getPreset(currentProfile)
presetPref.apply {
if (entryValues.contains(preset)) {
summary = "%s"
@ -213,7 +224,7 @@ class DolbySettingsFragment : PreferenceFragment(),
}
}
val deValue = dolbyController.dialogueEnhancerAmount.toString()
val deValue = dolbyController.getDialogueEnhancerAmount(currentProfile).toString()
dialoguePref.apply {
if (entryValues.contains(deValue)) {
summary = "%s"
@ -223,22 +234,18 @@ class DolbySettingsFragment : PreferenceFragment(),
}
}
virtPref.setChecked(if (isOnSpeaker) {
dolbyController.speakerVirtEnabled
} else {
dolbyController.headphoneVirtEnabled
})
volumePref.setChecked(dolbyController.volumeLevelerEnabled)
spkVirtPref.setChecked(dolbyController.getSpeakerVirtEnabled(currentProfile))
volumePref.setChecked(dolbyController.getVolumeLevelerEnabled(currentProfile))
// below prefs are not enabled on loudspeaker
if (isOnSpeaker) {
stereoPref.summary = headphoneRes
bassPref.summary = headphoneRes
hpVirtPref.summary = headphoneRes
return
}
val swValue = dolbyController.stereoWideningAmount.toString()
val swValue = dolbyController.getStereoWideningAmount(currentProfile).toString()
stereoPref.apply {
if (entryValues.contains(swValue)) {
summary = "%s"
@ -249,7 +256,12 @@ class DolbySettingsFragment : PreferenceFragment(),
}
bassPref.apply {
setChecked(dolbyController.bassEnhancerEnabled)
setChecked(dolbyController.getBassEnhancerEnabled(currentProfile))
summary = null
}
hpVirtPref.apply {
setChecked(dolbyController.getHeadphoneVirtEnabled(currentProfile))
summary = null
}
}