Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
* Adapted to run with my new module "Audio Samplerate Changer"
  • Loading branch information
yzyhk904 authored Oct 28, 2024
1 parent 64f53ce commit 4ac8857
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 15 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ This module,
<br/>
<br/>

* Don't forget to install ["Audio jitter silencer"](https://github.com/Magisk-Modules-Alt-Repo/audio-jitter-silencer) together and uninstall "Digital Wellbeing" app (for reducing very large jitters which this module cannot reduce as itself)! If you like much clearer replay (especially on Qcomm devices using an offloading USB driver with large jitter), use <a href="https://github.com/yzyhk904/USB_SampleRate_Changer">"USB_SampleRate_Changer"</a> for reducing the jitter (making foggy sound).
* Don't forget to install ["Audio jitter silencer"](https://github.com/Magisk-Modules-Alt-Repo/audio-jitter-silencer) together and uninstall "Digital Wellbeing" app (for reducing very large jitters which this module cannot reduce by itself)! If you like much clearer replay (especially on Qcomm devices using an offloading USB driver with large jitter), use <a href="https://github.com/yzyhk904/USB_SampleRate_Changer">"USB_SampleRate_Changer"</a> for reducing the jitter (making foggy sound).

* Don't use Am@zon music using a much worse internal re-sampler which bypasses the mastering quality re-sampling in the OS mixer (audioFlinger). Other music streaming services don't use such an internal re-sampler, as far as I know.

* This module has been tested on LineageOS and crDroid ROM's, and phh GSI's (Android 10 ~ 14, Qualcomm & MediaTek SoC, and Arm32 & Arm64 combinations).

* Note 1: This module raises the resampling quality from AOSP standard one (stop band attenuation 90dB & cut off 100% of the Nyquist frequency & half filter length 32) to a very mastering quality (179dB & 99% & 408 for Android 12 and later devices and 160db & 91% & 480 for Android 9 & 10 & 11 ones (except low performance ones), but 167dB & 106% & 368 (194dB & 100% & 520 exceptionally for Galaxy S4) for low performance Android 12 and later devices, 160dB & 91% & 320 for low performance Android 9 & 10 & 11 ones; because earlier than Android 12 has a bug relating to aliasing processing around the Nyquist frequency). However, this cannot raise the quality for Android 8.1 and earlier ones. Please keep in mind that those attenuation values are used for a resampler design as targeted ones and may not be accomplished in the AOSP implementation.
* Note 1: This module raises the resampling quality from AOSP standard one (stop band attenuation 90dB & cut off 100% of the Nyquist frequency & half filter length 32) to a very mastering quality (194dB & 98% & 520 for very high performance devices, 179dB & 99% & 408 for Android 12 and later ones and 160db & 91% & 480 for Android 9 & 10 & 11 ones (except low performance ones), but 167dB & 106% & 368 (194dB & 100% & 520 exceptionally for Galaxy S4) for low performance Android 12 and later devices, 160dB & 91% & 320 for low performance Android 9 & 10 & 11 ones; because earlier than Android 12 has a bug relating to aliasing processing around the Nyquist frequency). However, this cannot raise the quality for Android 8.1 and earlier ones. Please keep in mind that those attenuation values are used for a resampler design as targeted ones and may not be accomplished in the AOSP implementation.

* Note 2: Entry class USB DAC's usually adopt an interface chip communicating with the adaptive mode or the synchronous one defined in the USB audio standard. As in these modes an Android host controller sends audio sampling rate clock signals to the DAC, jitter generated at the host side affects the audio quality of the DAC tremendously. Higher class DAC's communicate with the asynchronous mode (also defined in the standard) to a host controller, but they actually use a PLL to reduce jitter from the host not to stutter even in heavy jitter situations. As this result, they behave as the adaptive mode with a feedback loop to dynamically adjust the host side sampling clock signals while referring a DAC side clock in a real sense, so even with the asynchronous mode they are more or less affected by host side jitter. You can see the mode of your USB DAC by opening "/proc/asound/card1/stream0" on your phone while playing music. Please see a word in parentheses at "Endpoint:" lines; "SYNC", "ADAPTIVE" or "ASYNC" means that your DAC uses "synchronous", "adaptive" or "asynchronous" mode to communicate to your phone, respectively. Moreover, almost all audio peripherals, e.g., bluetooth earphones, internal DAC's, network audio devices have a PLL in themselves and are affected by host side jitter for the same reason.

Expand All @@ -43,6 +43,7 @@ This module,
| 159 | 480 | 92 | | High Performance devices under A12 |
| 165 | 360 | | 104 | Low Performance devices for A12 and later |
| 179 | 408 | | 99 | High Performance devices for A12 and later, and Galaxy S4 |
| 194 | 520 | | 98 | Very High Performance devices |
| External examples: | - | - | - | - |
| 100 | 29 | (91) | 109 | AK4493 (Sharp roll-off N-fold over-sampling) |
| 150 | 42 | (91) | 109 | AK4191EQ (Sharp roll-off N-fold over-sampling) |
Expand Down
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
## Change logs

# v1.3.9
* Adapted to run with my new module "Audio Samplerate Changer"

# v1.3.8
* Added disabling Dolby control support for USB DAC's on HyperOS not to reboot
* Excluded "MotorolaSettingsProvider" on Motorala devices only for avoiding their bootloop
* Changed the USB period_us from 2250 usec to 2000 usec to optimize for 48 kHz Opus tracks (recent majority)
* Added new props "audio.safemedia.force=false" and "audio.safemedia.csd.force=false"
* Fixed above disabling Dolby control support (manufacturer mismatch)
* Added a support for Tensor G4 (zuma pro)
* Changed a mirroring warning for incompatible Magisk v28.0; Please use [Compatible magisk-mirroring](https://github.com/Magisk-Modules-Alt-Repo/compatible-magisk-mirroring) and Magisk v28.0 together
* Added better re-sampling parameters for very high performance devices

# v1.3.7
* Added "compatible Magisk-mirroring" message for incompatible Magisk variants
Expand Down
165 changes: 158 additions & 7 deletions customize-functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,29 @@ function getActualConfigXML()
fi
}

function toHexLE()
{
if [ $# -eq 1 -a $1 -gt 0 ]; then
printf "%2.2x%2.2x%2.2x%2.2x" $(( $1 % 256 )) $(( $1 / 256 % 256 )) $(( $1 / 256 / 256 % 256 )) $(( $1 / 256 / 256 / 256 % 256 ))
return 0
else
return 1
fi
}

function toHexLineLE()
{
if [ $# -eq 1 ]; then
local i
for i in $1; do
toHexLE $i
done
return 0
else
return 1
fi
}

function toHexString()
{
if [ $# -ge 1 ]; then
Expand All @@ -86,7 +109,7 @@ function toHexString()
fi
}

# Patch libalsautils.so to map a property string to another
# Patch libalsautils.so and audio_usb_aoc.so (Tensor's offload USB driver) to map a property string to another
# arg1: original libalsautils.so file; arg2: patched libalsautils.so file;
function patchMapProperty()
{
Expand Down Expand Up @@ -117,6 +140,101 @@ function patchMapProperty()
fi
}

# Patch libalsautils.so to clear the 96kHz lock of USB audio class drivers
# arg1: original libalsautils.so file; arg2: patched libalsautils.so file;
# optional arg3: "max" (clearing upto 768kHz), "full" (clearing upto 386kHz), "default" or others (clearing upto 192kHz)
function patchClearLock()
{
local orig_rates='96000 88200 192000 176400 48000 44100 32000 24000 22050 16000 12000 11025 8000'
local new_rates='192000 176400 96000 88200 48000 44100 32000 24000 22050 16000 12000 11025 8000'

if [ $# -ge 2 -a -r "$1" ]; then
if [ $# -gt 2 ]; then
case "$3" in
"max" )
new_rates='768000 705600 384000 352800 192000 176400 96000 88200 48000 44100 24000 16000 8000'
;;
"full" )
new_rates='384000 352800 192000 176400 96000 88200 48000 44100 32000 24000 16000 12000 8000'
;;
"default" | * )
;;
esac
fi

local pat1=`toHexLineLE "$orig_rates"`
local pat2=`toHexLineLE "$new_rates"`

# A workaroud for a SELinux permission bug on Android 12
local prop1=`toHexString "ro.audio.usb.period_us"`
local prop2=`toHexString "vendor.audio.usb.perio"`

xxd -p <"$1" | tr -d ' \n' | sed -e "s/$prop1/$prop2/" -e "s/$pat1/$pat2/" \
| awk 'BEGIN {
foldWidth=60
getline buf
len=length(buf)
for (i=1; i <= len; i+=foldWidth) {
if (i + foldWidth - 1 <= len)
print substr(buf, i, foldWidth)
else
print substr(buf, i, len)
}
exit
}' \
| xxd -r -p >"$2"

return $?

else

return 1
fi
}

# Patch audio_usb_aoc.so file to clear the 192kHz lock of USB audio class Tensor offload drivers
# arg1: original audio_usb_aoc.so file; arg2: patched audio_usb_aoc.so file;
function patchClearTensorOffloadLock()
{
local orig_rates='192000 96000 48000 44100 32000 24000 22050 16000 12000 11025 8000'
local new_rates='768000 705600 384000 352800 192000 176400 96000 88200 48000 44100 8000'

if [ $# -ge 2 -a -r "$1" ]; then
local pat1=`toHexLineLE "$orig_rates"`
local pat2=`toHexLineLE "$new_rates"`

# A workaroud for a SELinux permission bug on Android 12
local prop1=`toHexString "ro.audio.usb.period_us"`
local prop2=`toHexString "vendor.audio.usb.perio"`

# sample rate limiter at 192kHz
local ul1=`toHexLineLE "192000"`
local ul2=`toHexLineLE "768000"`

# Don't work yet. Need more inviestigations
# xxd -p <"$1" | tr -d ' \n' | sed -e "s/$prop1/$prop2/" -e "s/$ul1/$ul2/" -e "s/$pat1/$pat2/" \
xxd -p <"$1" | tr -d ' \n' | sed -e "s/$prop1/$prop2/" \
| awk 'BEGIN {
foldWidth=60
getline buf
len=length(buf)
for (i=1; i <= len; i+=foldWidth) {
if (i + foldWidth - 1 <= len)
print substr(buf, i, foldWidth)
else
print substr(buf, i, len)
}
exit
}' \
| xxd -r -p >"$2"

return $?

else
return 1
fi
}

function makeLibraries()
{
local MAGISKPATH="$(magisk --path)"
Expand All @@ -131,10 +249,10 @@ function makeLibraries()
chcon u:object_r:vendor_file:s0 "${MODPATH}/system/vendor/${d}/${lname}"
chown root:root "${MODPATH}/system/vendor/${d}/${lname}"
chmod -R a+rX "${MODPATH}/system/vendor/${d}"
if [ -z "${REPLACE}" ]; then
REPLACE="/system/vendor/${d}/${lname}"
if [ -z "${REPLACEFILES}" ]; then
REPLACEFILES="/system/vendor/${d}/${lname}"
else
REPLACE="${REPLACE} /system/vendor/${d}/${lname}"
REPLACEFILES="${REPLACEFILES} /system/vendor/${d}/${lname}"
fi
fi
done
Expand All @@ -159,6 +277,31 @@ function loosenedMessage()
ui_print ""
}

function replaceSystemProps_VHPerf()
{
sed -i \
-e 's/vendor\.audio\.usb\.perio=.*$/vendor\.audio\.usb\.perio=2000/' \
-e 's/vendor\.audio\.usb\.out\.period_us=.*$/vendor\.audio\.usb\.out\.period_us=2000/' \
"$MODPATH/system.prop"
sed -i \
-e 's/vendor\.audio\.usb\.perio=.*$/vendor\.audio\.usb\.perio=2000/' \
-e 's/vendor\.audio\.usb\.out\.period_us=.*$/vendor\.audio\.usb\.out\.period_us=2000/' \
"$MODPATH/system.prop-workaround"

sed -i \
-e 's/ro\.audio\.resampler\.psd\.enable_at_samplerate=.*$/ro\.audio\.resampler\.psd\.enable_at_samplerate=44100/' \
-e 's/ro\.audio\.resampler\.psd\.stopband=.*$/ro\.audio\.resampler\.psd\.stopband=194/' \
-e 's/ro\.audio\.resampler\.psd\.halflength=.*$/ro\.audio\.resampler\.psd\.halflength=520/' \
-e 's/ro\.audio\.resampler\.psd\.tbwcheat=.*$/ro\.audio\.resampler\.psd\.tbwcheat=98/' \
"$MODPATH/system.prop"
sed -i \
-e 's/ro\.audio\.resampler\.psd\.enable_at_samplerate=.*$/ro\.audio\.resampler\.psd\.enable_at_samplerate=44100/' \
-e 's/ro\.audio\.resampler\.psd\.stopband=.*$/ro\.audio\.resampler\.psd\.stopband=194/' \
-e 's/ro\.audio\.resampler\.psd\.halflength=.*$/ro\.audio\.resampler\.psd\.halflength=520/' \
-e 's/ro\.audio\.resampler\.psd\.tbwcheat=.*$/ro\.audio\.resampler\.psd\.tbwcheat=98/' \
"$MODPATH/system.prop-workaround"
}

function replaceSystemProps_Old()
{
if [ -e "${MODPATH%/*/*}/modules/usb-samplerate-unlocker" -o -e "${MODPATH%/*/*}/modules_update/usb-samplerate-unlocker" ]; then
Expand Down Expand Up @@ -357,10 +500,10 @@ function deSpatializeAudioPolicyConfig()
chcon u:object_r:vendor_configs_file:s0 "$modConfigXML"
chown root:root "$modConfigXML"
chmod -R a+rX "${modConfigXML%/*}"
if [ -z "$REPLACE" ]; then
REPLACE="/system${configXML}"
if [ -z "$REPLACEFILES" ]; then
REPLACEFILES="/system${configXML}"
else
REPLACE="$REPLACE /system${configXML}"
REPLACEFILES="$REPLACEFILES /system${configXML}"
fi
fi
fi
Expand Down Expand Up @@ -394,3 +537,11 @@ function disablePrivApps()
fi
done
}

function ui_print_replacelist()
{
local f
for f in $1; do
ui_print "- Replace target file: $f"
done
}
7 changes: 6 additions & 1 deletion customize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ if ! isMagiskMountCompatible; then
fi

REPLACE=""
REPLACEFILES=""

# Make patched ALSA utility and Tensor's offload libraries for "ro.audio.usb.period_us"
makeLibraries
Expand Down Expand Up @@ -53,13 +54,16 @@ fi
if "$IS64BIT"; then
board="`getprop ro.board.platform`"
case "$board" in
zuma* | "pineapple" )
replaceSystemProps_VHPerf
;;
"kona" | "kalama" | "shima" | "yupik" )
replaceSystemProps_Kona
;;
"sdm845" )
replaceSystemProps_SDM845
;;
gs* | zuma* )
gs* )
replaceSystemProps_Tensor
;;
"sdm660" | "bengal" | "holi" )
Expand Down Expand Up @@ -96,3 +100,4 @@ else
fi

rm -f "$MODPATH/customize-functions.sh" "$MODPATH/LICENSE" "$MODPATH/README.md" "$MODPATH/changelog.md"
ui_print_replacelist "$REPLACEFILES"
4 changes: 2 additions & 2 deletions module.prop
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
id=audio-misc-settings
name=Audio misc. settings
version=v1.3.8
versionCode=1308
version=v1.3.9
versionCode=1309
author=zyhk
description=Setting audio misc. configuration values (e.g. 100 volume steps, raising the resampling quality, disabling the effects framework, etc.)
9 changes: 6 additions & 3 deletions post-fs-data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ MODDIR=${0%/*}
# This script will be executed in post-fs-data mode

if [ \( -e "${MODDIR%/*/*}/modules/usb-samplerate-unlocker" -a ! -e "${MODDIR%/*/*}/modules/usb-samplerate-unlocker/disable" \) \
-o -e "${MODDIR%/*/*}/modules_update/usb-samplerate-unlocker" ]; then
-o -e "${MODDIR%/*/*}/modules_update/usb-samplerate-unlocker" ] || \
[ \( -e "${MODDIR%/*/*}/modules/audio-samplerate-changer" -a ! -e "${MODDIR%/*/*}/modules/audio-samplerate-changer/disable" \) \
-o -e "${MODDIR%/*/*}/modules_update/audio-samplerate-changer" ]; then

# If usb-samplerate-unlock exists, save related libraries elsewhere because the unlocker will do the same thing in itself.
# If usb-samplerate-unlock or audio-samplerate-changer exists, save related libraries and file(s) elsewhere
# because they will do the same thing in themselves.
for d in "lib" "lib64"; do
for lname in "libalsautils.so" "libalsautilsv2.so" "audio_usb_aoc.so"; do
if [ -r "${MODDIR}/system/vendor/${d}/${lname}" ]; then
Expand All @@ -22,7 +25,7 @@ if [ \( -e "${MODDIR%/*/*}/modules/usb-samplerate-unlocker" -a ! -e "${MODDIR%

else

# If usb-samplerate-unlock doesn't exist, restore related libraries from their saved folders.
# If usb-samplerate-unlock and audio-samplerate-changer don't exist, restore related libraries from their saved folders.
for d in "lib" "lib64"; do
for lname in "libalsautils.so" "libalsautilsv2.so" "audio_usb_aoc.so"; do
if [ -r "${MODDIR}/save/vendor/${d}/${lname}" -a -e "${MODDIR}/system/vendor/${d}" ]; then
Expand Down

0 comments on commit 4ac8857

Please sign in to comment.