Things have gotten a little easier: A native Android app that replaces the below script mess along with the Tasker-generated app is now available here. Unfortunately, you will still need to manually update your mixer_paths.xml file.
Newer devices and/or kernels now utilize a codec feature that is incompatible with biQuads. If after appropriate modification of your phone's mixer file you only hear audio coming out of your right headphone channel, then I suggest you read this post for a fix.
This mod is not just another collection of black-box sound "enhancement" libraries. There are plenty of those in this forum. The uniqueness of this mod is its ability to offer highly flexible and truly personalized headphone compensation filters. The potential of this proposition becomes clear when you realize that audio "quality" is experienced on a very subjective/individual level. The final compensation filters as obtained by the attached app simply require a modification of a single text file (mixer_paths.xml) that control the IIR filter as offered by the audio codec (Qualcomm only!). The audio mod itself is independent of kernel, ROM, and audio playback software used.
The aim of this mod is to offer the user of a rooted Qualcomm-based Android device running Lollipop or later the ability to take full advantage of the IIR filter implementation offered by Qualcomm audio codecs (WCD93xx). The IIR filters are implemented in hardware as a cascade of five biquads that can be designed independently. Before diving into your own filter designs, you may want to visit this website to play with an interactive visualization of biquad filters. The mod and associated app aims to provide a similar design experience right on your device.
The advantages of using Qualcomm's hardware filter as opposed to other equalization filters offered by software implementations, such as Viper and friends are:
- the filters are implemented in hardware and independent of the ROM, kernel, and media playback software used
- the additional impact on battery usage is virtually non-existent
- no black box: the user has full control over the design; the filters can be designed to avoid any distortions to the audio signal
- install the attached app
- make sure you have busybox installed
- flash the attached zip using a custom recovery (tested with TWRP) Update: For devices using the Qualcomm WCD9335 and newer you will need to install an updated version, which is available here
- prepare your mixer (/system/etc/mixer_paths.xml) to accept the hardware filter. This is the most complex part of this mod. Unfortunately, this needs to be done manually as each device is (potentially) different. This post hosts the relevant sections of various devices, which will hopefully be updated regularly with new devices.
- Newer devices and/or kernels now utilize a codec feature that is incompatible with biQuads. If after appropriate modification of your phone's mixer file you only hear audio coming out of your right headphone channel, then I suggest you read this post for a fix.
Operation of the software
This software is very useful to (within reason) design compensation filters for your headphone's frequency response. For example, many in-ear-monitors (IEMs) suffer from some level of high-frequency boost due to ear canal resonances. These resonances can be effectively "eliminated" by attenuating the offending frequencies. Each offending frequency (or frequency range) is then taken care of by designing its own biquad. You can find measured frequency responses (that you can use as a reference) of a large number of headphones either on GoldenEars, Inner Fidelity, or in forums like Head-Fi.
Open the biQuads app and you will see the main screen that allows you to enter the parameters of each of the five available biquads, see the example section below. Enter the parameters and tap "Design Biquad". You can repeat this process for up to five biquads, but you can also leave any number of biquads at their default, which is a simple bypass (does not change the frequency response at all). A biquad that is kept at its default values is marked with a white IIR X (X=1,2,...,5) text label. Once a biquad has been designed the text turns green. A designed biquad filter can be reset to its default value by tapping the corresponding green text label. Note that your most recent filter design will remain in memory and will even survive a reboot.
Once you are happy with your biquad design you can tap the "Review Filter" button. This action will combine all previously designed biquads (green text labels) to the final filter which can then be applied to the audio codec ("Listen" button) while you are listening to music. Once you are completely satisfied with your filter you can hit the "Save" button which will allow you to save the filter coefficients along with a screenshot of the final frequency response along with all design parameters. You will then need to manually copy the contents of the saved filter coefficients file to your (modified) mixer_paths.xml file. The format of the coefficients file is such you can simply copy and paste into your mixer_path.xml file.
Please keep an eye on the maximum gain applied by the overall filter. In order to avoid distortions introduced by that gain, I highly recommend to appropriately lower the playback volume; each volume "tick" in the upper playback range corresponds to 3 dB. For example if your overall filter adds a maximum of 3 dB of gain, the playback level should be kept below the highest Volume setting to avoid non-linear distortions.
Limitations of this software
this app has been created with the incredible Tasker software. While Tasker is extremely powerful, exported apps are not exactly pretty and they do not show up in the "Recent Apps" view. (At least not this app) may not scale well on certain screen resolutions.
- unfortunately, mixer_path edits are close to impossible to automate and some manual edits are necessary
- when listening to the effect of the designed filters, keep in mind that the filters will reset to whatever (if any) filter has been hardcoded in your mixer_path.xml file with any audio stream change (fast forward, skip, etc.). You will have to tap the "Listen" button to, again, apply the designed filters.
- not necessarily a limitation of this app, but a limitation of using the Qualcomm-provided IIR filter for headphone compensation: any other reference to IIR filtering in your mixer_paths.xml file should be removed. The original use-case for the IIR filter is sidetone compensation for telephony.
due to the nature of this implementation (Tasker executing shell scripts and writing files that don't sit in /system), root privileges are frequently requested. I have seen instances where SuperSU runs out of memory to spawn new "root shells". At this point, no app will work that relies on root privileges and yo have to reboot your device. I'm not sure whether this is a Tasker or SuperSU problem.
A design example with screenshots
Below is a screenshot of the parameter entry screen for a peak filter (IIR/biquad 1) at 7 kHz with a gain of -6.0 dB (attenuation) and Q=1.0:
Below is a screenshot of the frequency response screen (after tapping the "Design Biquad" button) for a peak filter (IIR/biquad 1) at 7 kHz with a gain of -6.0 dB (attenuation) and Q=1.0:
Below is a screenshot of the parameter entry screen for a lowpass (LP) shelf filter (IIR/biquad 2) at 200 Hz with a gain of 3.0 dB and Q=1.0:
Below is a screenshot of the frequency response screen (after tapping the "Design Biquad" button) for a lowpass (LP) shelf filter (IIR/biquad 2) at 200 Hz with a gain of 3.0 dB and Q=1.0:
Below is a screenshot of the overall designed filter (after tapping the "Review Filter" button) of the two biquads designed above:
Useful posts in this thread
- required mixer_paths.xml modifications
- simple channel crossfeed scheme
- theory and practice of personalized IIR filter design
- asymmetric filter design
- Nexus 5 (my own and only device)
- Samsung Note 4 (Qualcomm)
- HTC M9
Many thanks to my good friends @bjrmd and @avs333 whose comments and time spent on debugging have been incredibly valuable to the project.
- Version 1.0 (December 12, 2015): Initial revision
- Version 1.0.1 (December 14, 2015): added tinymix binary required to apply filters to the codec from within the app
- Version 1.1 (December 20, 2015): added feature: the gain introduced by the IIR filter can now be compensated for. This is particularly important when playing back audio at high levels and designing biquads that introduce overall gain, particularly at low frequencies. Now you can long-tap the "Listen" button to force gain compensation. This update also includes a few bugfixes. Please reflash the attached zip.
- Version 1.1.1 (December 21, 2015): for as of yet unknown reasons, the tinymix binary that I've packaged with the last two releases does not seem to work with Android version prior to Marshmallow. This release packages the tinymix attached to the second post, which has been built from Lollipop sources and still works on Marshmallow. Thanks @bjrmd for reporting the issue!
- Version 1.2 (December 29, 2015): app now allows for applying any of the designed biquads to either the left channel or right channel only, which paths the way for compensation of asymmetric hearing and/or physically different transducers (loudspeakers on the phone). This mode can be enabled by tapping the filter parameter text box on the "Review Filter" screen. The filters are still applied to both channels simultaneously by default. Note that, at this stage, the filters are still saved for both channels, regardless of what playback mode has been selected. Some manual labor is required to transfer the final filters to your mixer_paths.xml file. Note that you will need additional edits to your mixer_paths file to support built-in speaker compensation. See this post for an example pertaining to the Nexus 5.
- Version 1.2.1 (March 9, 2016): small update to address a potential problem writing data (filter coefficients) to external storage. Thanks @bjrmd for reporting the issue!
- Version 1.2.2 (April 4, 2016): update that fixes filter coefficient overflow inside the codec that may occur with a limited number of design parameter combinations. Yet again, I'm indebted to @bjrmd for pointing out the issue.
- (New) Version 1.0 (November 17, 2017): First release of a native Android app doing the same as the previous version 1.2.2. This app now self-contained and root-method-agnostic, so there is no need to flash anything anymore.