dolby: Add intelligent equalizer setting

Move preference-related classes to a new package while we're at it,
to reduce code clutter.

Change-Id: I2430e8ab9b6758503ce1777ec985a3e400b55b8e
This commit is contained in:
Adithya R 2024-08-05 10:09:08 +05:30 committed by basamaryan
parent b10f3eefc6
commit daec8b0c5b
No known key found for this signature in database
GPG Key ID: 707BA6C82329E8F9
14 changed files with 275 additions and 19 deletions

View File

@ -0,0 +1,24 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000000"
android:pathData="M 69.584 66.547 L 63.792 70.797 L 38.646 71.697 L 13.5 72.597 L 13.5 89.723 C 13.5 99.143 13.865 111.999 14.313 118.292 L 15.124 129.734 L 178.5 129.734 L 178.5 102.234 L 121.248 102.234 L 99.203 82.234 C 87.078 71.234 76.756 62.248 76.266 62.266 C 75.776 62.282 72.769 64.209 69.584 66.547"
android:strokeWidth="1.25"/>
<path
android:fillColor="#000000"
android:pathData="M 69.125 67.065 L 62.875 71.921 L 38.188 71.99 L 13.5 72.06 L 13.504 81.122 C 13.506 86.106 13.876 99.044 14.325 109.872 L 15.141 129.56 L 178.5 129.56 L 178.5 103.31 L 122.126 103.31 L 99.675 82.997 C 87.326 71.826 76.808 62.577 76.299 62.446 C 75.791 62.315 72.563 64.394 69.125 67.065"
android:strokeWidth="1.25"/>
<path
android:fillColor="#000000"
android:pathData="M 69.854 67.249 L 63.237 72.187 L 13.311 72.187 L 14.119 84.374 C 14.562 91.077 14.929 104.016 14.932 113.124 L 14.939 129.687 L 178.689 129.687 L 178.689 103.437 L 150.251 103.428 L 121.814 103.418 L 99.143 82.865 L 76.471 62.313 L 69.854 67.249"
android:strokeWidth="1.25"/>
<path
android:fillColor="#000000"
android:pathData="M 69.141 67.266 L 63.221 71.609 L 45.888 71.609 C 36.354 71.609 25.238 71.956 21.184 72.378 L 13.813 73.147 L 14.115 93.316 C 14.281 104.408 14.748 117.001 15.151 121.297 L 15.886 129.109 L 178.188 129.109 L 178.188 102.859 L 120.703 102.859 L 98.696 82.859 C 86.594 71.859 76.324 62.873 75.876 62.891 C 75.429 62.907 72.399 64.876 69.141 67.266"
android:strokeWidth="1.25"/>
</vector>

View File

@ -0,0 +1,24 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000000"
android:pathData="M 126.625 63.749 C 120.886 65.812 115.12 69.774 103.5 79.643 C 85.566 94.873 77.207 98.716 62.179 98.637 C 51.344 98.582 42.841 96.091 34.946 90.659 C 29.282 86.763 22.25 77.097 22.25 73.209 C 22.25 71.466 21.259 70.954 17.875 70.954 L 13.5 70.954 L 13.5 129.704 L 178.5 129.704 L 178.5 86.329 L 174.915 81.381 C 169.567 73.999 161.404 67.534 153.865 64.714 C 146.447 61.939 132.988 61.463 126.625 63.749"
android:strokeWidth="1.25"/>
<path
android:fillColor="#000000"
android:pathData="M 128.493 63.479 C 122.229 65.384 117.026 68.819 104.59 79.26 C 89.19 92.189 83.945 95.359 73.54 98.024 C 60.438 101.381 44.281 98.268 33.966 90.4 C 28.19 85.994 22.25 77.679 22.25 73.999 C 22.25 71.475 21.634 71.061 17.875 71.061 L 13.5 71.061 L 13.5 129.811 L 178.5 129.811 L 178.494 108.249 L 178.488 86.686 L 173.807 80.541 C 163.119 66.51 143.193 59.008 128.493 63.479"
android:strokeWidth="1.25"/>
<path
android:fillColor="#000000"
android:pathData="M 129.75 63.348 C 122.865 65.451 115.829 70.014 103.442 80.413 C 96.136 86.547 86.969 92.947 82.48 95.048 C 60.304 105.426 32.044 97.046 23.267 77.492 C 21.242 72.979 20.328 72.179 17.191 72.179 L 13.5 72.179 L 13.5 129.679 L 178.5 129.679 L 178.456 108.742 C 178.41 86.981 178.329 86.587 172.313 78.669 C 163.463 67.022 142.469 59.466 129.75 63.348"
android:strokeWidth="1.25"/>
<path
android:fillColor="#000000"
android:pathData="M 131.184 63.546 C 123.825 64.992 117.559 68.919 103.5 80.894 C 96.969 86.458 87.98 92.824 83.526 95.043 C 75.941 98.821 74.591 99.077 62.25 99.077 C 49.875 99.077 48.564 98.827 40.714 94.962 C 31.655 90.503 24.469 83.298 22.19 76.396 C 21.04 72.909 20.19 72.202 17.152 72.202 L 13.5 72.202 L 13.5 129.702 L 178.5 129.702 L 178.5 87.577 L 174.965 82.702 C 170.49 76.532 163.525 70.403 157.488 67.323 C 153.545 65.312 139.684 61.884 137.333 62.339 C 136.944 62.414 134.176 62.957 131.184 63.546"
android:strokeWidth="1.25"/>
</vector>

View File

@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000000"
android:pathData="M 13.5 96 L 13.5 103.5 L 178.5 103.5 L 178.5 88.5 L 13.5 88.5 L 13.5 96"
android:strokeWidth="1.25"
android:fillType="evenOdd"/>
</vector>

View File

@ -0,0 +1,28 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000000"
android:pathData="M 48.789 64.919 C 45.865 66.366 40.885 70.429 37.721 73.948 C 28.465 84.243 13.479 116.446 13.479 126.041 L 13.479 129.786 L 95.979 129.786 C 141.354 129.786 178.479 129.486 178.479 129.12 C 178.479 128.753 177.131 125.8 175.483 122.558 C 170.413 112.579 162.723 104.006 155.705 100.509 C 149.673 97.503 148.053 97.286 131.582 97.286 C 105.944 97.286 102.89 95.881 86.335 76.454 C 74.977 63.124 61.056 58.848 48.789 64.919"
android:strokeWidth="1.25"
android:fillType="evenOdd"/>
<path
android:fillColor="#000000"
android:pathData="M 49.712 64.871 C 40.942 68.842 33.167 78.157 25.45 93.941 C 18.063 109.047 13.462 121.585 13.462 126.604 L 13.462 129.769 L 178.496 129.769 L 176.673 125.407 C 171.895 113.971 159.81 101.317 151.203 98.739 C 148.476 97.921 138.591 97.264 128.942 97.256 C 107.671 97.241 102.106 95.265 93.347 84.617 C 76.128 63.684 64.227 58.297 49.712 64.871"
android:strokeWidth="1.25"
android:fillType="evenOdd"/>
<path
android:fillColor="#000000"
android:pathData="M 52.781 63.452 C 47.321 65.482 40.256 70.907 35.792 76.496 C 27.971 86.29 13.406 119.09 13.406 126.91 L 13.406 129.502 L 178.552 129.502 L 174.586 122.06 C 169.31 112.162 163.213 105.23 156.113 101.056 C 150.453 97.729 149.705 97.625 130.807 97.53 C 107.81 97.414 103.646 96.04 94.012 85.387 C 80.912 70.9 77.898 68.045 73.171 65.632 C 67.157 62.565 57.846 61.569 52.781 63.452"
android:strokeWidth="1.25"
android:fillType="evenOdd"/>
<path
android:fillColor="#000000"
android:pathData="M 56.078 63.069 C 44.607 65.852 35.711 75.314 26.246 94.802 C 19.707 108.263 16.537 116.731 14.817 125.334 L 14.005 129.397 L 95.98 129.397 C 165.857 129.397 177.953 129.136 177.953 127.627 C 177.953 124.146 165.22 106.857 160.048 103.314 C 152.515 98.156 150.572 97.791 129.828 97.641 C 111.478 97.507 110.935 97.424 104.33 93.776 C 99.905 91.331 95.316 87.208 91 81.798 C 80.578 68.737 74.351 64.324 64.203 62.812 C 61.797 62.453 58.141 62.568 56.078 63.069"
android:strokeWidth="1.25"
android:fillType="evenOdd"/>
</vector>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 The Android Open Source Project
(C) 2024 Paranoid Android
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="56dp"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:paddingLeft="8dp"
android:paddingStart="8dp"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:paddingTop="4dp"
android:paddingBottom="4dp">
<androidx.preference.internal.PreferenceImageView
android:id="@+id/ieq_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:maxWidth="56dp"
app:maxHeight="56dp"/>
</LinearLayout>

View File

@ -85,4 +85,18 @@
<item>64</item>
</string-array>
<string-array name="dolby_ieq_entries">
<item>@string/dolby_off</item>
<item>@string/dolby_balanced</item>
<item>@string/dolby_warm</item>
<item>@string/dolby_detailed</item>
</string-array>
<string-array name="dolby_ieq_values">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
</resources>

View File

@ -61,4 +61,10 @@
<string name="dolby_geq_preset_name_exists">Preset name already exists!</string>
<string name="dolby_geq_preset_name_too_long">Preset name is too long!</string>
<!-- Dolby intelligent EQ -->
<string name="dolby_ieq">Intelligent equalizer</string>
<string name="dolby_balanced">Balanced</string>
<string name="dolby_warm">Warm</string>
<string name="dolby_detailed">Detailed</string>
</resources>

View File

@ -33,6 +33,12 @@
android:targetClass="co.aospa.dolby.xiaomi.geq.EqualizerActivity" />
</Preference>
<co.aospa.dolby.xiaomi.preference.DolbyIeqPreference
android:key="dolby_ieq"
android:entries="@array/dolby_ieq_entries"
android:entryValues="@array/dolby_ieq_values"
android:title="@string/dolby_ieq" />
<SwitchPreference
android:key="dolby_spk_virtualizer"
android:title="@string/dolby_spk_virtualizer" />

View File

@ -7,6 +7,7 @@
package co.aospa.dolby.xiaomi
import android.os.Bundle
import co.aospa.dolby.xiaomi.preference.DolbySettingsFragment
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity
import com.android.settingslib.widget.R

View File

@ -14,6 +14,7 @@ class DolbyConstants {
HEADPHONE_VIRTUALIZER(101),
SPEAKER_VIRTUALIZER(102),
VOLUME_LEVELER_ENABLE(103),
IEQ_PRESET(104),
DIALOGUE_ENHANCER_ENABLE(105),
DIALOGUE_ENHANCER_AMOUNT(108),
GEQ_BAND_GAINS(110, 20),
@ -30,6 +31,7 @@ class DolbyConstants {
const val PREF_ENABLE = "dolby_enable"
const val PREF_PROFILE = "dolby_profile"
const val PREF_PRESET = "dolby_preset"
const val PREF_IEQ = "dolby_ieq"
const val PREF_HP_VIRTUALIZER = "dolby_virtualizer"
const val PREF_SPK_VIRTUALIZER = "dolby_spk_virtualizer"
const val PREF_STEREO = "dolby_stereo"
@ -40,6 +42,7 @@ class DolbyConstants {
val PROFILE_SPECIFIC_PREFS = setOf(
PREF_PRESET,
PREF_IEQ,
PREF_HP_VIRTUALIZER,
PREF_SPK_VIRTUALIZER,
PREF_STEREO,

View File

@ -121,6 +121,13 @@ internal class DolbyController private constructor(
prefs.getString(DolbyConstants.PREF_PRESET, getPreset(profile)),
profile
)
setIeqPreset(
prefs.getString(
DolbyConstants.PREF_IEQ,
getIeqPreset(profile).toString()
).toInt(),
profile
)
setHeadphoneVirtEnabled(
prefs.getBoolean(DolbyConstants.PREF_HP_VIRTUALIZER, getHeadphoneVirtEnabled(profile)),
profile
@ -283,6 +290,17 @@ internal class DolbyController private constructor(
dolbyEffect.setDapParameter(DsParam.DIALOGUE_ENHANCER_AMOUNT, value, profile)
}
fun getIeqPreset(profile: Int = this.profile) =
dolbyEffect.getDapParameterInt(DsParam.IEQ_PRESET, profile).also {
dlog(TAG, "getIeqPreset: $it")
}
fun setIeqPreset(value: Int, profile: Int = this.profile) {
dlog(TAG, "setIeqPreset: $value")
checkEffect()
dolbyEffect.setDapParameter(DsParam.IEQ_PRESET, value, profile)
}
companion object {
private const val TAG = "DolbyController"
private const val EFFECT_PRIORITY = 100

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2024 Paranoid Android
*
* SPDX-License-Identifier: Apache-2.0
*/
package co.aospa.dolby.xiaomi.preference
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.ImageView
import androidx.appcompat.content.res.AppCompatResources
import androidx.preference.ListPreference
import androidx.preference.PreferenceViewHolder
import co.aospa.dolby.xiaomi.R
// Preference with icon on the right side
class DolbyIeqPreference(
context: Context,
attrs: AttributeSet?,
) : ListPreference(context, attrs) {
init {
widgetLayoutResource = R.layout.ieq_icon_layout
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val iconView = holder.findViewById(R.id.ieq_icon)!! as ImageView
val icon = AppCompatResources.getDrawable(context, getIeqIconResId())
iconView.setImageDrawable(icon)
}
private fun getIeqIconResId(): Int {
val ieqValue = value?.toIntOrNull() ?: 0
return when (ieqValue) {
0 -> R.drawable.ic_ieq_off
1 -> R.drawable.ic_ieq_balanced
2 -> R.drawable.ic_ieq_warm
3 -> R.drawable.ic_ieq_detailed
else -> 0 // should never hit this!
}
}
}

View File

@ -4,12 +4,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
package co.aospa.dolby.xiaomi
package co.aospa.dolby.xiaomi.preference
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceDataStore
import androidx.preference.PreferenceManager
import co.aospa.dolby.xiaomi.DolbyConstants
class DolbyPreferenceStore(
private val context: Context

View File

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package co.aospa.dolby.xiaomi
package co.aospa.dolby.xiaomi.preference
import android.media.AudioAttributes
import android.media.AudioDeviceCallback
@ -19,7 +19,20 @@ import androidx.preference.Preference
import androidx.preference.Preference.OnPreferenceChangeListener
import androidx.preference.PreferenceFragment
import androidx.preference.SwitchPreference
import co.aospa.dolby.xiaomi.DolbyConstants
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_BASS
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_DIALOGUE
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_ENABLE
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_HP_VIRTUALIZER
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_IEQ
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_PRESET
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_PROFILE
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_RESET
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_SPK_VIRTUALIZER
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_STEREO
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.PREF_VOLUME
import co.aospa.dolby.xiaomi.DolbyConstants.Companion.dlog
import co.aospa.dolby.xiaomi.DolbyController
import co.aospa.dolby.xiaomi.R
import com.android.settingslib.widget.MainSwitchPreference
import com.android.settingslib.widget.OnMainSwitchChangeListener
@ -28,34 +41,37 @@ class DolbySettingsFragment : PreferenceFragment(),
OnPreferenceChangeListener, OnMainSwitchChangeListener {
private val switchBar by lazy {
findPreference<MainSwitchPreference>(DolbyConstants.PREF_ENABLE)!!
findPreference<MainSwitchPreference>(PREF_ENABLE)!!
}
private val profilePref by lazy {
findPreference<ListPreference>(DolbyConstants.PREF_PROFILE)!!
findPreference<ListPreference>(PREF_PROFILE)!!
}
private val presetPref by lazy {
findPreference<Preference>(DolbyConstants.PREF_PRESET)!!
findPreference<Preference>(PREF_PRESET)!!
}
private val ieqPref by lazy {
findPreference<DolbyIeqPreference>(PREF_IEQ)!!
}
private val stereoPref by lazy {
findPreference<ListPreference>(DolbyConstants.PREF_STEREO)!!
findPreference<ListPreference>(PREF_STEREO)!!
}
private val dialoguePref by lazy {
findPreference<ListPreference>(DolbyConstants.PREF_DIALOGUE)!!
findPreference<ListPreference>(PREF_DIALOGUE)!!
}
private val bassPref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_BASS)!!
findPreference<SwitchPreference>(PREF_BASS)!!
}
private val hpVirtPref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_HP_VIRTUALIZER)!!
findPreference<SwitchPreference>(PREF_HP_VIRTUALIZER)!!
}
private val spkVirtPref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_SPK_VIRTUALIZER)!!
findPreference<SwitchPreference>(PREF_SPK_VIRTUALIZER)!!
}
private val volumePref by lazy {
findPreference<SwitchPreference>(DolbyConstants.PREF_VOLUME)!!
findPreference<SwitchPreference>(PREF_VOLUME)!!
}
private val resetPref by lazy {
findPreference<Preference>(DolbyConstants.PREF_RESET)!!
findPreference<Preference>(PREF_RESET)!!
}
private val dolbyController by lazy { DolbyController.getInstance(context) }
@ -112,6 +128,7 @@ class DolbySettingsFragment : PreferenceFragment(),
dialoguePref.onPreferenceChangeListener = this
bassPref.onPreferenceChangeListener = this
volumePref.onPreferenceChangeListener = this
ieqPref.onPreferenceChangeListener = this
resetPref.setOnPreferenceClickListener {
dolbyController.resetProfileSpecificSettings()
@ -143,37 +160,41 @@ class DolbySettingsFragment : PreferenceFragment(),
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
dlog(TAG, "onPreferenceChange: key=${preference.key} value=$newValue")
when (preference.key) {
DolbyConstants.PREF_PROFILE -> {
PREF_PROFILE -> {
val profile = newValue.toString().toInt()
dolbyController.profile = profile
(preferenceManager.preferenceDataStore as DolbyPreferenceStore).profile = profile
updateProfileSpecificPrefs()
}
DolbyConstants.PREF_SPK_VIRTUALIZER -> {
PREF_SPK_VIRTUALIZER -> {
dolbyController.setSpeakerVirtEnabled(newValue as Boolean)
}
DolbyConstants.PREF_HP_VIRTUALIZER -> {
PREF_HP_VIRTUALIZER -> {
dolbyController.setHeadphoneVirtEnabled(newValue as Boolean)
}
DolbyConstants.PREF_STEREO -> {
PREF_STEREO -> {
dolbyController.setStereoWideningAmount(newValue.toString().toInt())
}
DolbyConstants.PREF_DIALOGUE -> {
PREF_DIALOGUE -> {
dolbyController.setDialogueEnhancerAmount(newValue.toString().toInt())
}
DolbyConstants.PREF_BASS -> {
PREF_BASS -> {
dolbyController.setBassEnhancerEnabled(newValue as Boolean)
}
DolbyConstants.PREF_VOLUME -> {
PREF_VOLUME -> {
dolbyController.setVolumeLevelerEnabled(newValue as Boolean)
}
PREF_IEQ -> {
dolbyController.setIeqPreset(newValue.toString().toInt())
}
else -> return false
}
return true
@ -205,6 +226,7 @@ class DolbySettingsFragment : PreferenceFragment(),
val enable = dsOn && (currentProfile != -1)
presetPref.setEnabled(enable)
spkVirtPref.setEnabled(enable)
ieqPref.setEnabled(enable)
dialoguePref.setEnabled(enable)
volumePref.setEnabled(enable)
resetPref.setEnabled(enable)
@ -216,6 +238,16 @@ class DolbySettingsFragment : PreferenceFragment(),
presetPref.summary = dolbyController.getPresetName()
val ieqValue = dolbyController.getIeqPreset(currentProfile)
ieqPref.apply {
if (entryValues.contains(ieqValue.toString())) {
summary = "%s"
value = ieqValue.toString()
} else {
summary = unknownRes
}
}
val deValue = dolbyController.getDialogueEnhancerAmount(currentProfile).toString()
dialoguePref.apply {
if (entryValues.contains(deValue)) {