[Android Software Development] bjrmd:
Project Purposes: Optimize sound quality of snapdragon audio codec devices when played through the headset port at moderate to low volumes, especially using low impedance, high sensitivity in ear monitors. The optimization will mainly affect signal to noise ratio, noise floor, perhaps THD. In addition, real time Spl monitoring on any device has been added for hearing protection, curiosity and viewing the dynamic range of music tracks. Integration of the Biquad equalization/filter mod by [MENTION=2760454]chdloc[/MENTION] as a parametric equalizer. The equalizer is capable of 5 bands, different left and right parameters and clipping protection.

Potential Users: Listen to music with high efficiency headphones/IEM and music volume generally below 2/3 max. Low distortion, noise important. Will also provide a finer granularity to the volume heard, about 1 dB increment change vs 3 dB through android volume control. Ability to make custom equalization filters for anything that plays through the headset jack.

Requirements:

For Gain Control:

Rooted, snapdragon based sound codec device (tested on galaxy S3, Note 4, Sony Tablet Z, Nexus 5). Totally stock ROM and kernel is fine. AOSP and custom kernels should work, even Faux audio kernels.

For Spl measurement only:

Non rooted, stock android 4.4 and beyond.

Usb DAC-you need to be rooted but any brand codec, Usb audio must work already, Not compatible with 3rd party Usb sound apps/drivers. You will also need ALSAmixer and thanks to the developer for making this tool. Use version 251.

This app supports Neutron, Poweramp, Spotify and Google play music. Other music play apps should work using a “polling” method to detect if they are playing

Background

You may have heard various reviewers say that the codec/DAC of a device is of high quality but the software has not been designed to take advantage of said hardware. Well, that seems to be unfortunately true. The situation is that most if not all headphone audio is not designed to maximize signal to noise ratio, distortion and noise floor. The volume output of the device is dependant on "gain" from both analog and digital controls. Unless you are playing back at max levels, volume attenuation using the digital control results in data truncation and potentially loss of information. Therefore the use of analog gain to control the volume(with digital gain near 0) should provide the most optimal signal. Measurements done by myself show about a 10 dB noise floor improvement at low gain levels using an analog method of gain level optimization . But at near max output this difference should disappear.

Reference is zipped below from a presentation from ESS, a company that makes high quality DAC chips.

Is there a way to do this? Yes, by keeping the digital gains near or at 0 dB and using analog gain control. There are 3 different gains that we can adjust, RX digital gain(in /system/etc/mixer_paths.xml with value 84 generally zero dB), Android volume(0-15---15 being 0 dB) and analog control(HPHL and HPHR-also in mixer_paths). The problem is that each time you adjust mixer_paths you need to restart your phone--not a very good solution unless you listen at one fixed volume. There is a utility called tinymix that will adjust these as well but in my experience(Note 4) it's not very reliable/fast.

In the process of working on some other sound mods with my friend [MENTION=2760454]chdloc[/MENTION]) we stumbled on a specific file that is a codec debug tool. It shows the codec register values(the ones above as well as a plethora of other data) but more importantly--it can be written to! So we have a way to smoothly and quickly read and adjust digital and analog gains. There is a catch though. If the audio path changes (listening to music then a text notification comes in, or alarm goes off, or you get a phone call) the audio gain will revert to whatever was default in the mixerpaths.xml file(kind of a master control file for audio). We have been able to compensate somewhat for this as will be seen below and is a main feature of this mod.

The Spl monitoring is covered below in more detail. Although it was not my initial goal for this project, I believe the Spl monitoring offers a unique glimpse into the actual sound pressure level coming out of the headset as well as the dynamic range of your music. As far as I have seen, there is not another mod that does this and it was something I have always wanted to do. My hearing has already been degraded by rock concerts, noisy subways, loud weddings etc and I wanted a way to protect against any further damage (but at the same time I do like to listen at a relatively high volume). This feature is helpful in that compromise.

The Biquad integration provides a way to both design custom filters (equalization) that will work for all music apps playing through the headset jack. The filters can be asymmetric--left different from right.

Setup--

0- Backup/Nandroid everything.

1- place "tinymix" in system/bin, permission to execute. Tinymix is used in the initial codec query/calibration. Make the appropriate changes to mixer_paths.xml (see below).

2- make sure you have busybox installed(most custom Roms already have this, if you are stock rooted get it from playstore)

3- Install the Gainctrl apk. This is the main app to control gains, logically raise and lower the gain to achieve the desired listening volume. The app will ask for permissions dealing with starting on boot, root functions, reading sms since it can read back messages.

4- Put a set of headphones in the jack

5- Open the app Gainctrl----

You will presented with three choices. If you want the usual install press the top button.

(The second button will install Spl monitoring software only for non root.

The third option is for codec tools which will be used for future debugging and I will skip it.)

For Usb Dac control just press the choice and the screen will close.

When you plug in a Usb Dac, the program will detect this and will be discussed below.

Then a setup screen will open

There is an auto calibration step that needs to be done once-press the button on the lower part of the screen that says calibrate.

The app will find the range and location of the analog gains that your codec supports. This is where tinymix is used to determine the HPH levels your codec supports. The app will use Google play music to play a track(whatever you were last listening to, so make sure that app is installed), go through some measuring and then let you know when it’s done. It will then quit.

Quick start usage--just start playing Google music again and the notification controls will appear up top. Press the up/down buttons to raise /lower volume or use the 3rd triple line icon to open the gain slider screen.

Here are sliders for Android volume (each tick is 3 dB), Digital gain and Analog gain. Analog goes from 0 to 20 (usually, sometimes 12). Digital is the RX1 and RX2 (L,R side and each tick is 1 dB) from mixerpaths and incidentally also corresponds to what Faux sound modifies. We should initially keep Analog at zero, Android at max 15 and then use the Digital to get a comfortable level. If you have maxed out digital to 84 (0 dB) then start raising Analog (each tick is 1.5 dB).

6- Setup Screen Usage---Choosing which music app you will use(Poweramp and Google are the same button). Each music app will fire "broadcast intents" when playing or not-these are used to rerun the codec scripts for gain changes on music play-so choose carefully. The calibration above uses Google music so that is what is chosen as default. As mentioned above the gain settings/biquads usually don't stick after the music stops so the app needs to know when tracks play/pause/change.. “Say text” on or off to verbally read text messages or not. In addition I have added a switch to enable automatic reapplication of the "Biquad" mod on each pause/play. This is a brilliant piece of work done by my friend [MENTION=2760454]chdloc[/MENTION] that creates a 5 band parametric equalizer on the qualcomm platform. His post has the details of how to implement the feature and further instructions are below.

Music polling-certain music apps don’t broadcast play pause info that this app can catch(Pandora). By choosing the polling method a loop will be set up on headset insertion that “listens” for music playing every 4 secs. It should not be used with the defined player options above it and if it is chosen the others become inactive, and visa versa.

Summary:

- The notification bar is where you increase or decrease the volume. The far right icon next to the arrows goes to the gain slider screen as an alternate adjustment.

- If you restart the phone/tablet you will not need to restart the app--it should auto start.

- If you get a call, the music will stop and on resume the volume will go back to the last chosen levels.

- If you get a text, music will pause and it will be "read" over the music channel so no volume shifting occurs. However, the text reading can be disabled by the button in the settings screen.

From any of the screens there is a master menu, 3 dots on the top left, it will go to all relevant screens. It can be activated by pressing the notification icon of the app, the Home button on the "Biquad" bar, opening the app from the app drawer if no notifications are present.

Help- will bring you to this post:

There are also 2 mini apps--"Up" and "Down". These can serve in place as up or down clicks on the notification bar. They are good as "shortcuts" to put on the home screen, or even mapping the volume up/down keys using "xposed additions". A single launch/click of the Up/Down app will change the gains by 1 dB according to the logical algorithm (keeping android vol/digital at or near 0 dB and analog gain as low as possible).

Spl control-

Preface-One of my fears in many long years of listening, is what damage is being done in regards to permanent hearing loss. There are studies and recommendations as to time and volume levels that are safe. The SPL calc is an attempt to provide a rough estimate of the Spl(sound pressure level) coming out of the headphone using the following assumptions.

The full output of the codec is 1 V, the published headphone stats(sensitivity and impedance) and measured/published phone amplifier impedance are correct. The software will compute the Spl using the above and the gains selected. So you need the headphone’s published sensitivity( my Shure SE846 is 114 dB SPL/mW), some are published in dB/V so be careful with the entry box. The Spl window uses these units so be reasonably certain. The headphone out impedance is usually about 1 to10 Ohm (Note 4 is 1.4) but you should be able to find the value on the net or measure it yourself(here). The headphones impedance at 1 Khz is usually published but can be also taken from Goldenears.net reviews( again my SE846 is about 9 Ohm)

You should be able to raise/lower gain by 1 dB, monitor the Spl from the notification bar. If you are curious and have the right gear you can also use this in bench testing to easily compare different settings(high analog vs digital attenuation) but at the same Spl(gain). I have measured the actual Spl using a handheld meter, using a full-scale 1 kHz sine wave and the matching is very close. Actual music will be less but varies depending on what you are listening to. Informal observations show average music to be 5-6 dB down from the 1 kHz sine. Please consult published guidelines for safe listening.

Spl and Visualizer

As noted above, one of the purposes of this app/mod is to try to inform the listener about excess sound levels which will cause hearing loss. It does not limit or change the sound in any way but based on the gains(voltage put out by the phone), the headphone/amplifier output impedance and headphone sensitivity, calculates what a 1 kHz sine wave Spl would be. Depending on what you are listening to (silence, over compressed rock music, everything in between) the sound coming out of the headphone will be quite different. There is a class available in android that measures the peak and RMS audio levels on a real time basis. By using this measurement we can then compensate for whatever the played signal is for a much more accurate determination of Spl. Unfortunately there is a bug in the measurement process that makes levels only accurate at maximum android volume levels. With this app, we keep them there anyway so it is not an issue. However, if you do not do so the numbers put out will not be accurate.

Additional Feature:

Spl Monitoring Mode Only- Any device, any onboard DAC- No root needed, the volume keys will provide the gain parameters. Of course, you still need to input the amplifier, headphone specs. In addition, the maximum output voltage will need to be measured(to figure out the maximum volume possible). A male to male headset connector, voltmeter and a 1 kHz full scale sine wave is needed(below). Play the sine wave at max volume(do not attach headphone), measure the voltage and that is used in the input screen. My Galaxy S6 only puts out .525 V so it's max Spl will be quite a bit different than the Note 4 (1 V).

The new Spl measurement process gets peak and RMS levels every 1.5 seconds and put these values in an array of 8 values. At the end of the 8th measurement, the array is averaged and saved to a text file on your root storage(about every 15 sec). The two files contain the peak values and RMS in dB. So let's say the track has a peak value at 1 minute into the song of 0 dB, and an RMS level of -7 dB. The dynamic range would be 7 and if the calculated Spl was 90 by the original OP formula, the new net Spl would be 83 dB. A very quiet track may have a peak of -3 dB and RMS -16 resulting in a dynamic range of 13 and corrected Spl (90-16) of 74. More info on dynamic range calculations

The “visualizer” is enabled in the Spl Ctrl screen.

Be extra careful which headphone sensitivity units are used--either dB/V or dB/mw. Enter either one but not both. The website of the manufacturer should have the specs. Note: Shure is in dB/mw and Sennheiser is dB/V.

The visualizer engine does take considerable CPU resources and battery use. If you don’t want/need it, keep it disabled. On my Note 4, there is no lag and minimal battery compromise but devices may vary. The following screenshot shows the effect on my Note 4, about an extra 5-7%.

[/IMG]

The values are in a separate notification bar, with the last 8 array members over the previous 15 seconds.

The graph icon will show a graph of the Spl and dynamic range over time. It uses google graph api, so an internet connection is needed. The graph is scrollable by dragging it. Every time the headphone is pulled a separate “session” begins and the graph zeros out. But the last session can still be seen by pressing the button noted. Very long sessions won’t function with the google graph api that is used so the data gets automatically resized to every other value. Pause/play stays in the same session.

The left side of the graph has units for Spl in dB, the right(which may need to be scrolled since it is off screen) has the legend for dynamic range. Most tracks will have a dynamic range of between 8-15 (corresponds to the DR album database of 5-12 values). Parts of a track may have more range than others and certainly will have different Spl values. I have placed a yellow caution line at about 78 dB and a red at 85.

I have enclosed a couple of papers from recent literature regarding safe/prolonged listening levels and hearing loss. This software does not “A” weight the Spl, which is what is seen in the literature, but it is not far off, based on my A vs C weighted Spl meter comparing the levels.

Additional information

Neutron users must enable generic driver in settings.

Poweramp working with gains and Spl, use the google music toggle in setup, make sure direct volume control off and MusicFx is on in settings

Biquad Control:

One of the most significant accomplishments in regards to the qualcomm codec platform was the development of the Biquad filter/equalization system by [MENTION=2760454]chdloc[/MENTION]. This give us either a hard coded fixed equalizer(see his post for the mixerpath mods) or (with a bit of work) an on demand custom 5 band parametric equalizer that you can totally control. What my app will do is capture the numeric band codes from the Biquad app scripts, and take a screenshot of the frequency curve.

Step 1 is to install Biquads app, make the required mixerpath mods and probably make an extreme filter(bad sounding) to make sure it actually works when we test it out.

Step 2- From this apps main menu open Biquad Bar.

Another notification bar will appear up top, back arrow or close the main menu for now.

Step 3- Open [MENTION=2760454]chdloc[/MENTION]’s Biquad app, design your filter and press “Design Biquad”.

It will calculate the filter and put up a nice graphic--do not close this! Go to the notification bar opened above and press the “Capture” button. A screenshot is taken and you are presented with a screen to name the filter. Call it something descriptive, ie +2 dB 4 Khz Q 2 lets say, then hit save. You can now go back to chdloc Biquad app, hit ok to put away the graphic and then design another. Note--all captures are done on biquad #1--so do not design on the others.

Step 4- Design “Multi filter”- from the main menu, choose that entry and a screen opens showing left, right channels and the previously added individual biquads are in the drop down positions in a grid form. By default, they are all disabled. Just pick one at a time. A few comments. After measuring my Shure 846 freq response I noted a bit of a channel imbalance. So I made a 2 dB boost at 4K in the R and 4 dB boost in the L. So each band does not need to have the same gaines L or R. Each line can also have just a unilateral change. So if you need a boost or cut in just one side, leave the other disabled.

To prevent clipping it is very important to cut the “preamp” (INP1) by whatever the max boost was in your filters. So if you are boosting low bass by 8 dB, INP1 reduction needs to be 8. The net Spl calculation will reflect this as well.

Step 5- Go back to Setup from the main menu and enable Biquads.

Step 6- From the Main menu click “Active Filter” or the “Biquads bar” in notifications(click on the icon-not the Home) will open the same window. You will see a list of all the filter composites you have made, including a disabled choice. Just click on the entry you want to be active and it will run some tinymix commands to implement it. The details of the “mix” will show below the choice list in case you forgot what you picked. Long clicking will delete any entry.

Step 7-optional-Biquad library- from the main menu again, this lists all the single filters we took from the Biquad app, with screenshots(not scaled) to get an idea of what each looks like. Long clicking will delete.

Once this is done, the overall filter/equalization will occur automatically on playing.

Mixerpath mods:

As noted above, if the music stops or something interrupts the music stream, the default gain settings kick back in, potentially leading to a loud music blast as the track resumes, before the scripts have a chance to fire. To prevent this I highly recommend changing a few values in the mixer_paths.xml file that control HPH, which are the headphone analog gains and RX1, RX2 which are digital gains. Important: as above, the setup screen choice of what music app you are using is key for the scripts to run on playing, if they are not chosen the app will not know when to run the scripts.

In system/etc resides mixer_paths.xml. Use an appropriate file explorer and text editor to make the changes. There is one mixer_path change that is needed (at least on my device). That change involves turning off the "compander". The purpose of the compander is to reduce noise but I have seen no such improvement in testing. Unfortunately, having this on will prevent the analog gains from reliably changing so it needs to be off. So open mixer_paths.xml and under the "Headset" path change the "COMP1 Switch"=1 to "COMP1 Switch"=0.

Open and "find" occurrences of "HPHL" and "HPHR" in the path "Headset". Replace values with something low-- (2 to 4 range). That is to assure that analog gain does not get out of hand on audio stream type change(default is 20 on the Note 4 which is 30 dB higher than the 0 some people will use). Especially change the HPHL/R values of 0 in the beginning of the file, also to 2 to 4.

If your Digital gains are usually 65-75 in the control screen, I would also change the RX1 and RX2 values at the beginning of the file to whatever you generally use as well as the values under the "Headset" path(both usually 80-84). (NOTE- the path is under “headphones” on the Nexus 5 so again be careful). Save the file. If the formatting is not proper, audio may not work and/or the phone may not even boot.

Do not forget to change the COMP1 switch to 0.

Finally, if you use the “Up” and “Down” miniapps, they will trigger the above actions without pulling down the notification bar. They can also be mapped to the volume buttons using xposed additions(free version works fine). If you do this and media is not playing, the buttons should still control incall volume. However if no media is playing and not in a call, volume button (Up and Down miniapps) will trigger a volume screen below(since it does not know what you would like to adjust). Note--if tasker is running as a freestanding app, a broadcast error may flash-it is of no consequence.:

Usb Dac control;

On insertion you may see:

You must check the "always" box and hit OK.

First time use you will see:

The top box will populate with sound card devices and the Usb Dac will usually be device 1.

So enter 1 in "Device ID" field as shown.

Then the next scroll box will show the details of that sound card. We are interested in "PCM playback volume". Notice that the Numid is 3. That is entered in the next line as Numid.

Now, I have defaulted some boxes with my Dragonfly Red data but as shown, the Soundblaster E3 has markedly different values. The next part is critical. The "Range" must be put in (if not 64)--so in this case it's 12560. Then a Start Gain, this will trigger every time the Usb Dac is plugged--pick 5-10 percent of max, but this can be altered later. If you are interested in Spl levels, the voltage, impedance data etc must be put in. It is useful not only for ear protection but can help in loudness matching between headphone jack and Usb. The visualizer is explained above. The default player is Google music but the 3 dot menu can take you to "Setup" to change that.

When the Usb Dac is plugged, the notification bar will have a control similar to the qualcomm one. The up and down arrows will boost or decrease the Usb Dac gain by 1 dB (if the Range is 64) and the 3 lines on the right will take you to sliders that do the same.

If you do not want to have the Usb Dac control anymore, there is a Disable button on the control screen.

Finally, many thanks again to [MENTION=2760454]chdloc[/MENTION] for direction, knowledge, encouragement, friendship and the brilliant Biquad app. And for helping with the Usb Dac, Alsa particulars.

I would also like to thank the makers of Tasker, one of the most useful coding tools I have used in my many years of amateur programming. This app was created solely in Tasker including android java api usage.