I’ve had this phone for a while and thought I’d share some interesting findings for anyone interested in getting one or for whoever already has one.
As many know, the LG G7 Thinq (and the other LG V series phones) have exemplary audio due to their unique hardware. (The LG G7 has a Quad DAC and dedicated headphone amp).
@Amir has done a wonderful indepth review on this phone already: https://www.audiosciencereview.com/...o-measurement-of-lg-g7-thinq-smartphone.4468/
The thing is, it’s aged, and support for it has essentially been minimal. The last officially supported stock Android OS released for it was Android 10.
If you still use this phone, especially as a daily driver with the stock OS, it can be a little problematic (app support, security updates).
A way to fix this and continue receiving updates on the no longer supported LG G7 Thinq, is to switch to a different OS, something like LineageOS.
-------
I’m going to talk about LineageOS (because that’s what I just happened to install at the time and have been using it for a while).
LOS (LineageOS) offers a different philosophy of support towards the onboard DAC, specifically in terms of user interface and options as opposed to the stock os.
The options on LOS are as follows:
1. HiFi Quad DAC = On/Off
2. HiFi Mode = Normal, High Impedance, AUX High Impedance
3. AVC Volume (Amplifies Volume) = Default set to -11 (Sliding scale)
4. Digital Filter = Short, Sharp, Slow, Custom
5. Left Right Channel Balance
The options on the stock OS are as follows:
1. Volume = Sliding scale
2. Normalize Volume = On/Off
3. Equalizer
4. DTS:X 3D Surround = Wide, Side and Front
5. HiFi Quad DAC = On/Off
6. Sound Preset = Normal, Enhanced, Detailed, Live and Bass
7. Digital Filter = Short, Sharp, Slow
8. Left Right Channel Balance
The main difference here is that LOS is focusing on better hardware control (High Impedance and AUX High Impedance modes and fine tuning gain (AVC Volume option), while the stock os provided better a better software suite (DTS:X 3D and some interesting sound presets), which I miss as they were fun to play around with.
----
Now to the interesting part, testing:
I found out through some trial and error that LOS is not actually outputting advertised sound quality. (Well, that depends…)
Also, the stock music app that comes with LOS (called “Twelve”), doesn’t provide the user any information regarding sound quality of the music being played aside from the file type (.mp3, .wav, .flac, etc.) So, I went down a long rabbit hole looking for apps that provide this. I eventually settled on Neutron and USB Audio Player Pro. Both apps provided more information about the file being played but did they actually output it ?
I used a dumpsys command to help me analyze / investigate.
Stock Music Player (Twelve) on LOS:
Running the command shows the details of currently playing music on Android and reveals some interesting things.
The file I used for testing is a 96KHz, 24bit FLAC file (“Bee Moved” by Blue Monday FM) provided by Sony: https://helpguide.sony.net/high-res/sample1/v1/en/index.html
Doing a data dump when playing the track in the stock app (Twelve) that comes with LOS and running the command “adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread" shows us something interesting:
user@fedora:~$ adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread"
* daemon not running; starting now at tcp:5037
* daemon started successfully
Output thread 0x72b5f83600, name AudioOut_15, tid 7611, type 0 (MIXER):
I/O handle: 21
Standby: no
Sample rate: 48000 Hz
HAL frame count: 1920
HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
HAL buffer size: 7680 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Processing format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
Processing frame size: 4 bytes
Pending config events: none
Output devices: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
Input device: 0 (AUDIO_DEVICE_NONE)
Audio source: 0 (AUDIO_SOURCE_DEFAULT)
Timestamp stats: n=596213 disc=1291 cold=0 nRdy=0 err=353 rate=1 jitterMs(ave=0.000102997 std=0.0791189 min=-5.25656 max=5.0425) localSR(47999.9, 4.22452e-11) correctedJitterMs(ave=
0.000386946 std=0.0104202 min=-0.735569 max=4.99563)
Timestamp corrected: no
Last write occurred (msecs): 51
Process time ms stats: ave=2.32424 std=0.938775 min=0.943594 max=15.2033
Hal write jitter ms stats: ave=0.000176594 std=0.240499 min=-2.0676 max=2.02183
Threadloop write latency stats: ave=-208.922 std=7874.36 min=-174701 max=147.66
Note the Thread Type, instead of type 0 (MIXER), it should show a thread type like DIRECT or OFFLOAD. The Sample Rate should show 96000 Hz and the HAL Format should show 0x6 (AUDIO_FORMAT_PCM_24_BIT_PACKED) or similar, rather than 0x1 (16-bit).
Neutron:
Now lets run the command again, this time using the Neutron music player, same music file:
user@fedora:~$ adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread"
Output thread 0x72b5f83600, name AudioOut_15, tid 7611, type 0 (MIXER):
I/O handle: 21
Standby: no
Sample rate: 48000 Hz
HAL frame count: 1920
HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
HAL buffer size: 7680 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Processing format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
Processing frame size: 4 bytes
Pending config events: none
Output devices: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
Input device: 0 (AUDIO_DEVICE_NONE)
Audio source: 0 (AUDIO_SOURCE_DEFAULT)
Timestamp stats: n=596843 disc=1295 cold=0 nRdy=0 err=355 rate=0.999999 jitterMs(ave=0.000215702 std=0.0764984 min=-5.25656 max=5.0425) localSR(47999.8, 3.65766e-10) correctedJitter
Ms(ave=0.000387268 std=0.0104228 min=-0.735569 max=4.99563)
Timestamp corrected: no
Last write occurred (msecs): 69
Process time ms stats: ave=3.07741 std=0.987747 min=1.58396 max=12.5697
Hal write jitter ms stats: ave=-0.00289149 std=0.393875 min=-1.89661 max=1.90917
Threadloop write latency stats: ave=145.152 std=1.29484 min=132.038 max=147.048
Same results. Thread type, Sample rate and HAL format haven’t changed.
I did try and force the player to play the file at its correct sample rate by modifying some settings found in Neutrons settings page. Some things I tried were ensuring the Hi-Res Codec option was enabled, Enabling the “Follow Source Frequency” option and enabling “Exclusive Mode”
USB Audio Player Pro:
One more time with a different app, same file:
user@fedora:~$ adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread"
Output thread 0x72a98dfbc0, name AudioOut_245, tid 25805, type 1 (DIRECT):
I/O handle: 581
Standby: no
Sample rate: 96000 Hz
HAL frame count: 7680
HAL format: 0x6 (AUDIO_FORMAT_PCM_24_BIT_PACKED)
HAL buffer size: 46080 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Processing format: 0x6 (AUDIO_FORMAT_PCM_24_BIT_PACKED)
Processing frame size: 6 bytes
Pending config events: none
Output devices: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
Input device: 0 (AUDIO_DEVICE_NONE)
Audio source: 0 (AUDIO_SOURCE_DEFAULT)
Timestamp stats: n=115 disc=3 cold=3 nRdy=0 err=0 rate=0.999212 jitterMs(ave=0.0566463 std=0.586422 min=-0.949784 max=4.5986) localSR(95991, 9.74399e-08) correctedJitterMs(ave=0.067
7337 std=0.481601 min=-0.249887 max=4.5986)
Timestamp corrected: no
Last write occurred (msecs): 148
Process time ms stats: ave=0.500326 std=0.162315 min=0.2625 max=1.18135
Hal write jitter ms stats: ave=-1.24755 std=9.02093 min=-78.7238 max=0.698133
Threadloop write latency stats: ave=3546.04 std=19.2848 min=3409.18 max=3550.01
Note how the Thread type, Sample rate and HAL format are now different. The Thread type has changed now to “type 1 (DIRECT)”, the Sample rate is now showing 96000 Hz and the HAL format is showing “24_BIT_PACKED” , all in line and matching with the file quality being tested.
So why did the default music app provided by LineageOS and even an alternative app known for bypassing system resampling fail to output the actual quality of the FLAC file ?
A few things, but to put it simply, its primarily the way the apps interact with LineageOS’ security requirements, specifically its API. UAPP (USB Audio Player Pro) has a custom audio driver that bypasses the default android audio stack entirely. It essentially its own mini operating system and ignores LOS policy. On the other hand, even though Neutron has its own custom audio engine, it operates at an upper level and asks for permission to run its code, when LineageOS says “no” , it defaults to using the generic audio driver and android audio stack.
----
A few other music players were tested as well, like HiBy and Poweramp but both failed to play the file at it’s correct sample rate/quality.
----
A few ending notes.
There are a lot more moving parts to all of this than just a few data dumps and app testing. It made me realize how complex and intricately connected audio and security really is. Due to all this, I’m now left wondering how much more I don’t know/understand. The complex interaction between software and hardware, especially once you begin to deviate from stock is fascinating and can be overwhelming. I don’t exactly have a formal background in tech and so I’m now also wondering what are the next steps. Although I trust the data during the “dumpsys” printout, I don’t exactly understand the deeper and broader interaction “happenings” in this phone/DAC. With regards to audio quality output Is there something else I’m missing? Something else I’m not seeing ? Most likely, but for now I just thought I’d share my findings.
As many know, the LG G7 Thinq (and the other LG V series phones) have exemplary audio due to their unique hardware. (The LG G7 has a Quad DAC and dedicated headphone amp).
@Amir has done a wonderful indepth review on this phone already: https://www.audiosciencereview.com/...o-measurement-of-lg-g7-thinq-smartphone.4468/
The thing is, it’s aged, and support for it has essentially been minimal. The last officially supported stock Android OS released for it was Android 10.
If you still use this phone, especially as a daily driver with the stock OS, it can be a little problematic (app support, security updates).
A way to fix this and continue receiving updates on the no longer supported LG G7 Thinq, is to switch to a different OS, something like LineageOS.
-------
I’m going to talk about LineageOS (because that’s what I just happened to install at the time and have been using it for a while).
LOS (LineageOS) offers a different philosophy of support towards the onboard DAC, specifically in terms of user interface and options as opposed to the stock os.
The options on LOS are as follows:
1. HiFi Quad DAC = On/Off
2. HiFi Mode = Normal, High Impedance, AUX High Impedance
3. AVC Volume (Amplifies Volume) = Default set to -11 (Sliding scale)
4. Digital Filter = Short, Sharp, Slow, Custom
5. Left Right Channel Balance
The options on the stock OS are as follows:
1. Volume = Sliding scale
2. Normalize Volume = On/Off
3. Equalizer
4. DTS:X 3D Surround = Wide, Side and Front
5. HiFi Quad DAC = On/Off
6. Sound Preset = Normal, Enhanced, Detailed, Live and Bass
7. Digital Filter = Short, Sharp, Slow
8. Left Right Channel Balance
The main difference here is that LOS is focusing on better hardware control (High Impedance and AUX High Impedance modes and fine tuning gain (AVC Volume option), while the stock os provided better a better software suite (DTS:X 3D and some interesting sound presets), which I miss as they were fun to play around with.
----
Now to the interesting part, testing:
I found out through some trial and error that LOS is not actually outputting advertised sound quality. (Well, that depends…)
Also, the stock music app that comes with LOS (called “Twelve”), doesn’t provide the user any information regarding sound quality of the music being played aside from the file type (.mp3, .wav, .flac, etc.) So, I went down a long rabbit hole looking for apps that provide this. I eventually settled on Neutron and USB Audio Player Pro. Both apps provided more information about the file being played but did they actually output it ?
I used a dumpsys command to help me analyze / investigate.
Stock Music Player (Twelve) on LOS:
Running the command shows the details of currently playing music on Android and reveals some interesting things.
The file I used for testing is a 96KHz, 24bit FLAC file (“Bee Moved” by Blue Monday FM) provided by Sony: https://helpguide.sony.net/high-res/sample1/v1/en/index.html
Doing a data dump when playing the track in the stock app (Twelve) that comes with LOS and running the command “adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread" shows us something interesting:
user@fedora:~$ adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread"
* daemon not running; starting now at tcp:5037
* daemon started successfully
Output thread 0x72b5f83600, name AudioOut_15, tid 7611, type 0 (MIXER):
I/O handle: 21
Standby: no
Sample rate: 48000 Hz
HAL frame count: 1920
HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
HAL buffer size: 7680 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Processing format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
Processing frame size: 4 bytes
Pending config events: none
Output devices: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
Input device: 0 (AUDIO_DEVICE_NONE)
Audio source: 0 (AUDIO_SOURCE_DEFAULT)
Timestamp stats: n=596213 disc=1291 cold=0 nRdy=0 err=353 rate=1 jitterMs(ave=0.000102997 std=0.0791189 min=-5.25656 max=5.0425) localSR(47999.9, 4.22452e-11) correctedJitterMs(ave=
0.000386946 std=0.0104202 min=-0.735569 max=4.99563)
Timestamp corrected: no
Last write occurred (msecs): 51
Process time ms stats: ave=2.32424 std=0.938775 min=0.943594 max=15.2033
Hal write jitter ms stats: ave=0.000176594 std=0.240499 min=-2.0676 max=2.02183
Threadloop write latency stats: ave=-208.922 std=7874.36 min=-174701 max=147.66
Note the Thread Type, instead of type 0 (MIXER), it should show a thread type like DIRECT or OFFLOAD. The Sample Rate should show 96000 Hz and the HAL Format should show 0x6 (AUDIO_FORMAT_PCM_24_BIT_PACKED) or similar, rather than 0x1 (16-bit).
Neutron:
Now lets run the command again, this time using the Neutron music player, same music file:
user@fedora:~$ adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread"
Output thread 0x72b5f83600, name AudioOut_15, tid 7611, type 0 (MIXER):
I/O handle: 21
Standby: no
Sample rate: 48000 Hz
HAL frame count: 1920
HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
HAL buffer size: 7680 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Processing format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
Processing frame size: 4 bytes
Pending config events: none
Output devices: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
Input device: 0 (AUDIO_DEVICE_NONE)
Audio source: 0 (AUDIO_SOURCE_DEFAULT)
Timestamp stats: n=596843 disc=1295 cold=0 nRdy=0 err=355 rate=0.999999 jitterMs(ave=0.000215702 std=0.0764984 min=-5.25656 max=5.0425) localSR(47999.8, 3.65766e-10) correctedJitter
Ms(ave=0.000387268 std=0.0104228 min=-0.735569 max=4.99563)
Timestamp corrected: no
Last write occurred (msecs): 69
Process time ms stats: ave=3.07741 std=0.987747 min=1.58396 max=12.5697
Hal write jitter ms stats: ave=-0.00289149 std=0.393875 min=-1.89661 max=1.90917
Threadloop write latency stats: ave=145.152 std=1.29484 min=132.038 max=147.048
Same results. Thread type, Sample rate and HAL format haven’t changed.
I did try and force the player to play the file at its correct sample rate by modifying some settings found in Neutrons settings page. Some things I tried were ensuring the Hi-Res Codec option was enabled, Enabling the “Follow Source Frequency” option and enabling “Exclusive Mode”
USB Audio Player Pro:
One more time with a different app, same file:
user@fedora:~$ adb shell dumpsys media.audio_flinger | grep -A 20 "Output thread"
Output thread 0x72a98dfbc0, name AudioOut_245, tid 25805, type 1 (DIRECT):
I/O handle: 581
Standby: no
Sample rate: 96000 Hz
HAL frame count: 7680
HAL format: 0x6 (AUDIO_FORMAT_PCM_24_BIT_PACKED)
HAL buffer size: 46080 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Processing format: 0x6 (AUDIO_FORMAT_PCM_24_BIT_PACKED)
Processing frame size: 6 bytes
Pending config events: none
Output devices: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
Input device: 0 (AUDIO_DEVICE_NONE)
Audio source: 0 (AUDIO_SOURCE_DEFAULT)
Timestamp stats: n=115 disc=3 cold=3 nRdy=0 err=0 rate=0.999212 jitterMs(ave=0.0566463 std=0.586422 min=-0.949784 max=4.5986) localSR(95991, 9.74399e-08) correctedJitterMs(ave=0.067
7337 std=0.481601 min=-0.249887 max=4.5986)
Timestamp corrected: no
Last write occurred (msecs): 148
Process time ms stats: ave=0.500326 std=0.162315 min=0.2625 max=1.18135
Hal write jitter ms stats: ave=-1.24755 std=9.02093 min=-78.7238 max=0.698133
Threadloop write latency stats: ave=3546.04 std=19.2848 min=3409.18 max=3550.01
Note how the Thread type, Sample rate and HAL format are now different. The Thread type has changed now to “type 1 (DIRECT)”, the Sample rate is now showing 96000 Hz and the HAL format is showing “24_BIT_PACKED” , all in line and matching with the file quality being tested.
So why did the default music app provided by LineageOS and even an alternative app known for bypassing system resampling fail to output the actual quality of the FLAC file ?
A few things, but to put it simply, its primarily the way the apps interact with LineageOS’ security requirements, specifically its API. UAPP (USB Audio Player Pro) has a custom audio driver that bypasses the default android audio stack entirely. It essentially its own mini operating system and ignores LOS policy. On the other hand, even though Neutron has its own custom audio engine, it operates at an upper level and asks for permission to run its code, when LineageOS says “no” , it defaults to using the generic audio driver and android audio stack.
----
A few other music players were tested as well, like HiBy and Poweramp but both failed to play the file at it’s correct sample rate/quality.
----
A few ending notes.
There are a lot more moving parts to all of this than just a few data dumps and app testing. It made me realize how complex and intricately connected audio and security really is. Due to all this, I’m now left wondering how much more I don’t know/understand. The complex interaction between software and hardware, especially once you begin to deviate from stock is fascinating and can be overwhelming. I don’t exactly have a formal background in tech and so I’m now also wondering what are the next steps. Although I trust the data during the “dumpsys” printout, I don’t exactly understand the deeper and broader interaction “happenings” in this phone/DAC. With regards to audio quality output Is there something else I’m missing? Something else I’m not seeing ? Most likely, but for now I just thought I’d share my findings.
Last edited: