From 4e85c77d53bce6da3dc094e334d7f5004245edd1 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 15 Dec 2024 19:08:31 +0900 Subject: [PATCH] feat(YouTube Music): Add `Disable DRC audio` patch https://github.com/inotia00/ReVanced_Extended/issues/2552 --- .../music/patches/misc/DrcAudioPatch.java | 14 ++++ .../extension/music/settings/Settings.java | 1 + .../patches/music/misc/drc/DrcAudioPatch.kt | 64 +++++++++++++++++++ .../patches/music/misc/drc/Fingerprints.kt | 47 ++++++++++++++ .../patches/music/utils/patch/PatchList.kt | 4 ++ .../utils/playservice/VersionCheckPatch.kt | 3 + .../music/settings/host/values/strings.xml | 2 + 7 files changed, 135 insertions(+) create mode 100644 extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/DrcAudioPatch.java create mode 100644 patches/src/main/kotlin/app/revanced/patches/music/misc/drc/DrcAudioPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/music/misc/drc/Fingerprints.kt diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/DrcAudioPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/DrcAudioPatch.java new file mode 100644 index 000000000..94e1e5335 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/DrcAudioPatch.java @@ -0,0 +1,14 @@ +package app.revanced.extension.music.patches.misc; + +import app.revanced.extension.music.settings.Settings; + +@SuppressWarnings("unused") +public class DrcAudioPatch { + + public static float disableDrcAudio(float original) { + if (!Settings.DISABLE_DRC_AUDIO.get()) { + return original; + } + return 0f; + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java index fe78f7d7f..19d940bd0 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java @@ -173,6 +173,7 @@ public class Settings extends BaseSettings { // PreferenceScreen: Miscellaneous public static final BooleanSetting CHANGE_SHARE_SHEET = new BooleanSetting("revanced_change_share_sheet", FALSE, true); public static final BooleanSetting DISABLE_CAIRO_SPLASH_ANIMATION = new BooleanSetting("revanced_disable_cairo_splash_animation", FALSE, true); + public static final BooleanSetting DISABLE_DRC_AUDIO = new BooleanSetting("revanced_disable_drc_audio", FALSE, true); public static final BooleanSetting ENABLE_OPUS_CODEC = new BooleanSetting("revanced_enable_opus_codec", FALSE, true); public static final BooleanSetting SPOOF_CLIENT = new BooleanSetting("revanced_spoof_client", FALSE, true); public static final BooleanSetting SETTINGS_IMPORT_EXPORT = new BooleanSetting("revanced_extended_settings_import_export", FALSE, false); diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/drc/DrcAudioPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/drc/DrcAudioPatch.kt new file mode 100644 index 000000000..1ba486ee1 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/drc/DrcAudioPatch.kt @@ -0,0 +1,64 @@ +package app.revanced.patches.music.misc.drc + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.extension.Constants.MISC_PATH +import app.revanced.patches.music.utils.patch.PatchList.DISABLE_DRC_AUDIO +import app.revanced.patches.music.utils.playservice.is_7_13_or_greater +import app.revanced.patches.music.utils.playservice.versionCheckPatch +import app.revanced.patches.music.utils.settings.CategoryType +import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus +import app.revanced.patches.music.utils.settings.addSwitchPreference +import app.revanced.patches.music.utils.settings.settingsPatch +import app.revanced.util.fingerprint.matchOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction + +private const val EXTENSION_CLASS_DESCRIPTOR = + "$MISC_PATH/DrcAudioPatch;" + +@Suppress("unused") +val DrcAudioPatch = bytecodePatch( + DISABLE_DRC_AUDIO.title, + DISABLE_DRC_AUDIO.summary, +) { + compatibleWith(COMPATIBLE_PACKAGE) + + dependsOn( + settingsPatch, + versionCheckPatch, + ) + + execute { + val fingerprint = if (is_7_13_or_greater) { + compressionRatioFingerprint + } else { + compressionRatioLegacyFingerprint + } + + fingerprint.matchOrThrow(formatStreamModelConstructorFingerprint).let { + it.method.apply { + val insertIndex = it.patternMatch!!.endIndex + val insertRegister = getInstruction(insertIndex - 1).registerA + + addInstructions( + insertIndex, + """ + invoke-static {v$insertRegister}, $EXTENSION_CLASS_DESCRIPTOR->disableDrcAudio(F)F + move-result v$insertRegister + """ + ) + } + } + + addSwitchPreference( + CategoryType.MISC, + "revanced_disable_drc_audio", + "false" + ) + + updatePatchStatus(DISABLE_DRC_AUDIO) + + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/drc/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/drc/Fingerprints.kt new file mode 100644 index 000000000..27aa6fc0b --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/drc/Fingerprints.kt @@ -0,0 +1,47 @@ +package app.revanced.patches.music.misc.drc + +import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +/** + * On YouTube, this class is 'Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;' + * On YouTube Music, class names are obfuscated. + */ +internal val formatStreamModelConstructorFingerprint = legacyFingerprint( + name = "formatStreamModelConstructorFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + literals = listOf(45374643L), +) + +/** + * YouTube Music 7.13.52 ~ + */ +internal val compressionRatioFingerprint = legacyFingerprint( + name = "compressionRatioFingerprint", + returnType = "Lj${'$'}/util/Optional;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + opcodes = listOf( + Opcode.IF_EQZ, + Opcode.IGET, + Opcode.NEG_FLOAT, + ) +) + +/** + * ~ YouTube Music 7.12.52 + */ +internal val compressionRatioLegacyFingerprint = legacyFingerprint( + name = "compressionRatioLegacyFingerprint", + returnType = "F", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.IGET, + Opcode.RETURN, + ) +) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt index c589f2660..c814a7d97 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/patch/PatchList.kt @@ -45,6 +45,10 @@ internal enum class PatchList( "Disable Cairo splash animation", "Adds an option to disable Cairo splash animation." ), + DISABLE_DRC_AUDIO( + "Disable DRC audio", + "Adds an option to disable DRC (Dynamic Range Compression) audio." + ), DISABLE_AUTO_CAPTIONS( "Disable auto captions", "Adds an option to disable captions from being automatically enabled." diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt index 27115309c..dfb6de9f8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/playservice/VersionCheckPatch.kt @@ -13,6 +13,8 @@ var is_6_42_or_greater = false private set var is_7_06_or_greater = false private set +var is_7_13_or_greater = false + private set var is_7_18_or_greater = false private set var is_7_20_or_greater = false @@ -38,6 +40,7 @@ val versionCheckPatch = resourcePatch( is_6_36_or_greater = 240399000 <= playStoreServicesVersion is_6_42_or_greater = 240999000 <= playStoreServicesVersion is_7_06_or_greater = 242499000 <= playStoreServicesVersion + is_7_13_or_greater = 243199000 <= playStoreServicesVersion is_7_18_or_greater = 243699000 <= playStoreServicesVersion is_7_20_or_greater = 243899000 <= playStoreServicesVersion is_7_23_or_greater = 244199000 <= playStoreServicesVersion diff --git a/patches/src/main/resources/music/settings/host/values/strings.xml b/patches/src/main/resources/music/settings/host/values/strings.xml index 3bc78a2c0..311b6504d 100644 --- a/patches/src/main/resources/music/settings/host/values/strings.xml +++ b/patches/src/main/resources/music/settings/host/values/strings.xml @@ -418,6 +418,8 @@ Click to see how to issue a API key." Change from in-app share sheet to system share sheet. Disable Cairo splash animation Disables Cairo splash animation when the app starts up. + Disable DRC audio + Disables DRC (Dynamic Range Compression) applied to audio. Enable debug logging Prints the debug log. Enable debug buffer logging