• WANTED: Happy members who like to discuss audio and other topics related to our interest. Desire to learn and share knowledge of science required. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

Measurements of Google Pixel 3 + bundled dongle + AIMP app

edechamps

Addicted to Fun and Learning
Forum Donor
Joined
Nov 21, 2018
Messages
910
Likes
3,620
Location
London, United Kingdom
So here we go, my first set of measurements using my shiny new QA401. The measurement protocol is a first iteration; comments and feedback are welcome.

For another take on Pixel dongles, see these measurements and these ones, both by amirm. One thing that is worth noting is that amirm's measurements were done with the dongle plugged into a Windows computer. I decided not to do that, for multiple reasons. First, it would just be a repeat of measurements that have already been done. Second, for some reason none of my USB-C headphone dongles work with any of my Windows PCs (no idea why - the dongle is not recognized as an audio output, even though it appears in Device Manager). Third, some concerns were voiced that dongles might not behave consistently depending on what they're plugged into. Fourth, I'm interested in measuring the end-to-end performance of a real-world playback chain that I would use on a day-to-day basis, including Android itself and the music player app. For this reason, this review is about measuring an entire Android audio playback chain, not just the dongle.

The dongle I'm using here is the dongle that shipped with the Google Pixel 3 smartphone. I did not buy it separately. It is not clear if the dongle I'm reviewing here is the same as what amirm calls the "Google Pixel adapter V2". As we'll see in this review, some results are similar, some aren't.

Equipment under test (EUT): Google Pixel 3 running Android 9; analog output through the USB-C to 3.5mm adapter that shipped with the phone; test signals played using the AIMP Android App (v2.85 build 720); device volume at maximum unless otherwise noted
Test equipment: QuantAsylum QA401 Audio Analyzer (using L-/R- inputs; L+/R+ properly terminated; attenuator disabled; baseline results); ASIO401 1.1; REW V5.20 Beta 5

I decided to use AIMP to play the test signals because that's the app I'm using nowadays to play my music, and because it looks like a pretty minimalistic app that seems unlikely to do much processing of the audio that would mess up the measurements.

All the raw data and measurements, including REW mdat files, can be downloaded here.

setup.jpg


LOAD SENSING BEHAVIOUR

Before we begin, I should mention an important peculiarity of the EUT that will affect the measurements. I noticed this peculiar behaviour when I started measuring with various loads. At first I was deeply confused at the results I was getting: depending on how I set up the measurements, I would sometimes see the output level drop by 8 dB with some loads. But sometimes, that wouldn't happen. After much head-scratching, I discovered something quite intriguing: the EUT seems to change its behaviour depending on the impedance it sees on the right channel. This is true even if the right channel is not playing any signal - it looks like the EUT is actively sensing what impedance is connected to the right channel, and adjusting its output characteristics in kind. What's connected to the left channel doesn't seem to matter.

One thing that is worth noting is that the EUT does this "load sensing" thing only at the time the dongle is plugged into the phone's USB-C port, or at the time it detects a 3.5mm jack is being physically inserted into the dongle. It does not seem to sense the load continuously, and it's doesn't seem to do that at the beginning or end of playback, either. This means that it is possible to "trick" the EUT into a specific behaviour by changing the load characteristics after the dongle and the jack are plugged in.

As far as I can tell, this mechanism seems to be an "all or nothing" proposition: either it's enabled (-8 dB gain), or it's not (0 dB). I couldn't observe any in-between or progressive response behaviour. The load impedance threshold at which it kicks in seems to be somewhere between 100 Ω and 10 kΩ. Sadly, I cannot provide a better estimate because I don't have a programmable load and the resistors I have on hand are of limited variety at the moment. As far as I can tell, the mechanism seems to be designed to kick in when a pair of headphones is plugged in, as opposed to a line-level input.

So, basically, we need two sets of measurements: one for "High Impedance Mode" (HIM), to characterize the behaviour of the EUT when it didn't sense a load, and one for "Low Impedance Mode" (LIM), to characterize the behaivour of the EUT when it did sense a load (such as a pair of headphones). For some measurements I didn't deem the distinction to be worth the effort (e.g. sample rate, bit depth), and those were only done in High Impedance Mode.

Important note: for the avoidance of doubt, in this review, when I use the term "High Impedance Mode" and "Low Impedance Mode", this only means that I forced the "load senser" of the EUT into a particular mode. It is unrelated to the load I'm actually applying to the EUT outputs when making the measurement.

PRELIMINARY MEASUREMENTS: SAMPLE RATE (HIM)

The first order of business is to determine what sample rate the playback chain is running at, and if that can be changed. Ideally I want to do that by measuring, so as to not be blind sided by software indicators that are not necessarily trustworthy (they might not be telling me about hidden sample rate conversions, for example). So I came up with a set of test signals:

Code:
sox --channels 2 --bits 16 --rate 192000 --null 20000-192000.wav synth 30 sine 20000 gain -3
sox --channels 2 --bits 16 --rate 192000 --null 22050-192000.wav synth 30 sine 22050 gain -3
sox --channels 2 --bits 16 --rate 192000 --null 24000-192000.wav synth 30 sine 24000 gain -3
sox --channels 2 --bits 16 --rate 192000 --null 44100-192000.wav synth 30 sine 44100 gain -3
sox --channels 2 --bits 16 --rate 192000 --null 48000-192000.wav synth 30 sine 48000 gain -3
sox --channels 2 --bits 16 --rate 192000 --null 65000-192000.wav synth 30 sine 65000 gain -3

The point is to "probe" for the Nyquist frequencies of various sample rates. Running the QA401 at 192 kHz, we can see which ones of these test signals make it through, and which ones don't because they go through the stopband of a resampler. From there, we can deduce what the signal is being resampled to.

The 20 kHz and 22.05 kHz signals made it through. The 24 kHz signal, however, didn't, pointing to the signal being resampled to 48 kHz. Note that all the tests are done with the AIMP "Sample Rate" and "Output Method" options set to "Auto". These options don't seem to make any difference whatsoever; the results are the same no matter what they're set to. In fact, I can still get a 22.05 kHz even if the "sample rate" option is set to 44.1 kHz, which makes no sense and suggests the option does absolutely nothing.

Just to make sure, I also tried testing using a 96 kHz file:

Code:
sox --channels 2 --bits 16 --rate 96000 --null 24000-96000.wav synth 30 sine 24000 gain -3

But even then, the 24 kHz signal did not make it to the other end.

From there we can deduce that the maximum sample rate of the playback chain is 48 kHz.

PRELIMINARY MEASUREMENTS: INTERSAMPLE PEAKS (HIM)

Doing an intersample peak test as one of the first measurements might seem a bit odd, but it's actually quite useful because it can provide interesting information about the behaviour of the playback chain which can inform the rest of the measurements.

My intersample test signals are generated using the following:

Code:
sox --channels 2 --bits 16 --rate 48000 --null intersample-peaks-48000-16-0.wav synth 30 sine 12000 0 12.5 gain -1
sox --channels 2 --bits 16 --rate 48000 --null intersample-peaks-48000-16-1.wav synth 30 sine 12000 0 12.5 gain 0
sox --channels 2 --bits 16 --rate 48000 --null intersample-peaks-48000-16-2.wav synth 30 sine 12000 0 12.5 gain 1
sox --channels 2 --bits 16 --rate 48000 --null intersample-peaks-48000-16-3.wav synth 30 sine 12000 0 12.5 gain 2
sox --channels 2 --bits 16 --rate 48000 --null intersample-peaks-48000-16-4.wav synth 30 sine 12000 0 12.5 gain 3

In the end they look like this:

intersample-peaks-test-signal.png


And this is what bs1770gain has to say about them:

Code:
  [1/5] "intersample-peaks-48000-16-0.wav":
       true peak:  -0.58 TPFS / 0.935585
  [2/5] "intersample-peaks-48000-16-1.wav":
       true peak:  0.42 TPFS / 1.049707
  [3/5] "intersample-peaks-48000-16-2.wav":
       true peak:  1.42 TPFS / 1.177829
  [4/5] "intersample-peaks-48000-16-3.wav":
       true peak:  2.42 TPFS / 1.321535
  [5/5] "intersample-peaks-48000-16-4.wav":
       true peak:  3.42 TPFS / 1.482774

Now, while measuring the response of the system under test to these signals, I noticed that the system does distort heavily when confronted with intersample peaks, which is not really surprising. I also noticed that the distortion only happens when the device volume is set to maximum, which is pretty good evidence that the volume control is digital, not analog.

Another interesting discovery is the fact that the distortion at 48 kHz looks very different from the distortion at 44.1 kHz, as measured on a high-speed oscilloscope:

intersample-peaks-result.png


The 48 kHz case is the most logical: every cycle gets distorted. At 44.1 kHz however, the distortion seems to occur at a period that is different from the signal itself. What I suspect we're seeing here is evidence of the 44.1 kHz being implicitly resampled to 48 kHz: indeed, any sample rate conversion done on the original intersample peak test signal would (by definition) interpolate samples that are above full scale and clip them, and since the resampling ratio is not integer, the resulting distortion would follow a cycle that seems unrelated to the cycle of the original signal, which is exactly what we've observing. (Addendum: after further experiments, I came to the conclusion that this phenomenon is likely caused by AIMP; it's probably not the dongle's fault.)

PRELIMINARY MEASUREMENTS: BIT DEPTH (HIM)

Now let's try to find out what we can about how the EUT behaves under various bit depths. We use a 997 Hz sine wave signal at various levels, encoded at 16-bit and 24-bit. I also threw in pure silence (undithered, i.e. pure zeroes) files for completeness.

Note: the "Force 16-bit output" option in AIMP was disabled for all tests. That said, I've observed that this option doesn't seem to change anything to the test results.

Code:
sox --channels 2 --bits 16 --rate 48000 --null --no-dither 997-1-48000-16.wav synth 30 sine 997 gain -1 dither -p 16
sox --channels 2 --bits 24 --rate 48000 --null --no-dither 997-1-48000-24.wav synth 30 sine 997 gain -1 dither -p 24
sox --channels 2 --bits 16 --rate 48000 --null --no-dither 997-30-48000-16.wav synth 30 sine 997 gain -30 dither -p 16
sox --channels 2 --bits 24 --rate 48000 --null --no-dither 997-30-48000-24.wav synth 30 sine 997 gain -30 dither -p 24
sox --channels 2 --bits 16 --rate 48000 --null --no-dither 997-60-48000-16.wav synth 30 sine 997 gain -60 dither -p 16
sox --channels 2 --bits 24 --rate 48000 --null --no-dither 997-60-48000-24.wav synth 30 sine 997 gain -60 dither -p 24
sox --channels 2 --bits 16 --rate 48000 --null --no-dither 997-90-48000-16.wav synth 30 sine 997 gain -90 dither -p 16
sox --channels 2 --bits 24 --rate 48000 --null --no-dither 997-90-48000-24.wav synth 30 sine 997 gain -90 dither -p 24
sox --channels 2 --bits 16 --rate 48000 --null --no-dither 997-120-48000-16.wav synth 30 sine 997 gain -120 dither -p 16
sox --channels 2 --bits 24 --rate 48000 --null --no-dither 997-120-48000-24.wav synth 30 sine 997 gain -120 dither -p 24
sox --channels 2 --bits 16 --rate 48000 --null --no-dither 997-140-48000-16.wav synth 30 sine 997 gain -140 dither -p 16
sox --channels 2 --bits 24 --rate 48000 --null --no-dither 997-140-48000-24.wav synth 30 sine 997 gain -140 dither -p 24
sox --channels 2 --bits 16 --rate 48000 --null --no-dither silence-48000-16.wav trim 0 30
sox --channels 2 --bits 24 --rate 48000 --null --no-dither silence-48000-24.wav trim 0 30

16-bit results look perfectly normal. Here are various measurements at 16-bit:

16bit.png


When nothing is playing, we're bottoming out to the noise floor of the test equipment itself, which suggests the output literally shuts down when it's not being used, and when it does, it shorts the output instead of leaving it hanging. This is a good thing, because it means EMI interference (such as mains hum) won't show up when the output is unused.

The difference in level between the -1 dB 997 Hz signal and -140 dB signal (drowned in the 16-bit dither, as expected) is 93 dB, which confirms we have access to the full 16-bit dynamic range.

The 16-bit and 24-bit "silence" measurements are identical, which suggests the EUT is not applying additional dithering on top of the source file.

The rest of the 24-bit measurements, however, are, to put it mildly, all over the place, especially at low levels. Look at this garbage:

24bit.png


I don't know if this is laughably poor linearity, noise modulation, quantization issues, or what, but that looks bad. Really bad. To give you an idea, 997-120-48000-24 is supposted to be a -120 dBFS pure tone. It's measured at -94 dBFS with 40% THD. Something is deeply wrong here.

I had a suspicion that the reason why the 16-bit results look okay was solely because of the 16-bit dithering in the source files. So I had the idea of re-running 997-120-48000-16 with the device volume reduced halfway on the volume slider. Well that was quite informative - reducing the volume reduces the original source dithering along with it, and distortion rears its ugly head again:

16bit-halfvolume.png


Just by lowering the volume slider we went from virtually zero THD (harmonics drown in the noise) to a whooping 22% THD.

Well isn't that fucked up. Basically, the only way to get proper low level behavior out of that EUT is to play 16-bit files properly dithered at maximum volume. Do anything differently, and you'll get pretty nasty distortion at low levels. Someone definitely screwed up here - I get the impression that the DAC is pretending to run at 24-bit but is unable to, and will basically fall over as soon as one dips below the 16-bit noise floor. Combine that with the digital volume control, and you get a distortion fest. Sad.

UNLOADED MEASUREMENTS: MAXIMUM OUTPUT VOLTAGE

In HIM the 997-1-48000-48 test signal registers at -0.4 dBV, which means the maximum output level, unloaded, in High impedance Mode, is +0.6 dBV, or 1.07 Vrms, or 1.5 Vp, or 3.03 Vpp. In LIM things look quite different: the same signal registers at -8.4 dBV (exactly 8 dB lower than HIM), which means the maximum output level, unloaded, in Low Impedance Mode, is -7.4 dBV, or 0.43 Vrms, or 0.60 Vp, or 1.21 Vpp. That's mediocre, but typical of that kind of hardware. Obviously I wouldn't expect that to work well with low sensitivity headphones.

The difference in output voltage between LIM and HIM can cause quite a bit of user confusion if the user is not plugging in the headphones directly into the dongle, but is instead going through more adapters. Because of the way load sensing works (see above), if the user plugs in the headphone after whatever adapter was plugged into the dongle, the EUT will sound louder, which can be surprising.

amirm measured the Google V1 and V2 dongles at 1.88 Vrms and 0.44 Vrms, respectively. This leaves open the possibility that amirm measured the same dongle in LIM.

UNLOADED MEASUREMENTS: NOISE FLOOR AND DYNAMIC RANGE

In High Impedance Mode the silence-24 test signal (see above) registers 100.1 dB below 997-1-48000-16, leading us to believe we have access to 101.1 dB of dynamic range, or about 17 bits, and a noise floor of -100.5 dBV. In Low Impedance Mode the noise floor is 2.7 dB below, but the signal is 8.0 dB below, leading to a 5.3 dB loss in dynamic range.

But of course that would be too generous, because our bit depth measurements show that the EUT is not actually capable of delivering that noise floor with any kind of real signal other than pure silence. In practice, if we use the 997-140-48000-24 measurement which is more indicative of actual performance, we get 94 dB of dynamic range in High Impedance Mode, which is basically 16 bits, and a noise floor of -93.4 dBV. The Low Impedance Mode results are about 2.4 dB worse.

That's at maximum device volume, by the way. As already mentioned in the bit depth section, the device volume control is digital, or in other words, if you lower the volume slider, the noise floor stays the same and therefore the dynamic range is reduced.

UNLOADED MEASUREMENTS: THD AND THD+N/SINAD (997 Hz)

Unloaded, 997-1-48000-24 shows a THD of -91.9 dB (0.0025%) and a SINAD of 77.6 dB (0.013% THD+N) in High Impedance Mode; and a THD of -88.3 dB (0.0038%) and a SINAD of 78.8 dB (0.011% THD+N) in Low Impedance Mode.. This is well above the limits of the test equipment, so the results are valid.

That SINAD is quite bad, and significantly worse than the SINAD amirm measured for the Google V1 and V2 dongles, which were 89.6 and 85.9 dB, respectively. Not sure if that means I have yet another different dongle (and mine is worse than amirm's V2), or if the differences come from elsewhere in the EUT, or if I screwed up somewhere (this is my first review, after all).

UNLOADED MEASUREMENTS: FREQUENCY RESPONSE

For frequency response measurements, I use the measurement sweeps from REW, which are extremely precise and allow REW to compute all kinds of interesting information (phase response, THD vs frequency, etc.). I generated a -20 dBFS measurement sweep stimulus file from 10 Hz to Nyquist, at 44.1 and 48 kHz. I then play the stimulus on the EUT, record it (using ASIO401Test which I know is bit-perfect from QA401 to file since, well, I wrote it), and feed the result back to REW. The result is recorded with the QA401 running at 192 kHz to prevent the test equipment from affecting the response near Nyquist. The very slightly less-than-ideal response of the QA401 itself is compensated using a REW soundcard calibration file, which basically inverts the loopback response of the QA401.

The only thing that's slightly hairy with this protocol is that REW requires the measurement to be recorded at an integer multiple of the sample rate of the original stimulus file. That poses a problem when using a 44.1 kHz stimulus file, because the QA401 cannot operate at a multiple of 44.1 kHz. So, for the 44.1 kHz measurement, what I did was resample the 192 kHz recording to 176.4 kHz using sox rate -v before feeding it to REW. In theory this shouldn't affect the results at all, because the folding frequency of the resampling operation (88.2 kHz) is much higher than the highest frequency of the measurement (22.05 kHz) - we are very comfortably within the passband here.

With that in mind, let's look at the results:

frequency-response.png


At a sampling rate of 48 kHz the frequency response is beyond reproach - with +/- 0.01 dB over most of the frequency range, a <10 Hz low frequency limit, and a 22 kHz high frequency limit, there's not much to complain about here, it's just great.

At 44.1 kHz however, things take a dark turn. There's a pretty aggressive low pass filter somewhere in the chain that lowers the response by 1 dB at merely 12.5 kHz and by 3 dB at 16 kHz. I suspect that the DAC itself only operates at 48 kHz, and when a 44.1 kHz file is played, a resampling filter of questionable quality gets inserted into the chain, resulting in significant high frequency loss. This would certainly be consistent with the weird behavior we've observed at 44.1 kHz in the intersample peak tests (see above). Sad. (Addendum: after further experiments, I came to the conclusion that this is AIMP's fault, not the dongle's. See also the native results measured from Windows.)

MEASUREMENTS INTO 16 Ω: MAXIMUM OUTPUT VOLTAGE AND POWER

Note that all loaded measurements are done with both channels loaded and playing the same test signal, but only the left channel is measured.

In HIM the 997-1-48000-24 test signal registers at -3.6 dBV, which means the maximum output level, into 16.5 Ω, in High impedance Mode, is -2.6 dBV, or 0.74 Vrms, or 1.05 Vp, or 2.10 Vpp. In LIM (which is the mode headphone users are likely to land in), just like the unloaded measurements, the level is exatly 8 dB lower, and the same signal registers at -8.4 dBV, which means the maximum output level, into 16.5 Ω, in Low Impedance Mode, is -10.6 dBV, or 0.30 Vrms, or 0.42 Vp, or 0.84 Vpp.

The difference with the maximum unloaded output voltage is completely explained by the output impedance, as we'll see below. This means the EUT will always be voltage-limited for all realistic loads.

This translates to an output power of 33 mW (HIM) and 5.2 mW (LIM) into 16 Ω. Since the EUT is voltage-limited, as load impedance increases, I would expect output power to decrease accordingly.

MEASUREMENTS INTO 16 Ω: THD AND THD+N/SINAD (997 Hz)

Here's how things like at -1 dBFS into 16.5 Ω:

16ohm-distortion.png


Into 16.5 Ω, 997-1-48000-24 shows a THD of -58.5 dB (0.11%) and the same SINAD in High Impedance Mode; and a THD of -76.3 dB (0.015%) and a SINAD of 74.4 dB (0.019% THD+N) in Low Impedance Mode.. This is not great, though these numbers are arguably tolerable for a device operating at its absolute limits.

The difference between HIM and LIM can easily be explained by the lower output level; in fact, a -9 dBFS signal in HIM shows pretty similar results to -1 dBFS in LIM.

MEASUREMENTS INTO 16 Ω: OUTPUT IMPEDANCE AND FREQUENCY RESPONSE

To measure the output impedance, we can examine the level difference in the frequency responses between loaded and unloaded. I like this method because it also makes it obvious whether the output impedance is constant across the frequency range - in the past I measured a number of devices where it definitely wasn't, and I won't be fooled again.

16ohm-frequency-response.png


From these measurements we can see that connecting a 16.5 Ω load makes the output level drop by 3.1 dB compared to no load. There is no difference between HIM and LIM in that regard. From there we can directly deduce that the output impedance is a constant 7.0 Ω. That's bad and will compromise the otherwise excellent (at 48 kHz, at least) frequency response of the EUT when headphones are used.

The 7.0 Ω number is not far from the 7.6 Ω number that amirm obtained from the Google V2 dongle, making me once again wonder if this is the same hardware.

CONCLUSION

Overall this EUT is a pretty mediocre piece of hardware. It doesn't properly support any sample rate over than 48 kHz, making it a poor choice to play 44.1 kHz music. (Addendum: after some more experiments I determined this is AIMP's fault, not the dongle's.) Its SINAD is even worse than what amirm measured for the "V2" Google dongle. Its distortion profile at low signal levels is appalling, especially given that the volume control seems to be implemented in software. It attempts to detect when a load (such as headphones) is plugged in and automatically lowers its output level by 8 dB when that's the case, which is surprising and doesn't seem to serve any actual purpose (or at least not a measurable one). In that mode its unloaded maximum output level goes from bad (1.07 Vrms) to worse (0.43 Vrms), which makes it unsuitable for low-sensitivity headphones. But its output impedance of 7 Ω also makes it unsuitable for low-impedance headphones. So in the end it's not really that good at anything. Avoid.
 
Last edited:
OP
edechamps

edechamps

Addicted to Fun and Learning
Forum Donor
Joined
Nov 21, 2018
Messages
910
Likes
3,620
Location
London, United Kingdom
Addendum: while measuring other dongles I determined that the poor 44.1 kHz frequency response is caused by AIMP, not the dongle. If I play the test signal using the Google Play Music player, the frequency response looks equally good at 44.1 kHz as it does at 48 kHz. I will update the review to mention that, otherwise it could be misleading.

Another thing I noticed with another dongle is that AIMP is incapable of operating at a sample rate other than 48 kHz, period. With another dongle Google Play Music can properly play a 96 kHz file including a 24 kHz tone; AIMP can't. That was a really poor choice of app on my part. So, buyers beware: AIMP might not be a good choice for critical music listening.

However, Google Play Music was still unable to properly play at 96 kHz with the dongle in this particular review, so the statement that this particular dongle doesn't support >48 kHz sample rates still stands. I also double-checked the behaviour near noise floor at 24-bit, and there are no differences there.
 
Last edited:
OP
edechamps

edechamps

Addicted to Fun and Learning
Forum Donor
Joined
Nov 21, 2018
Messages
910
Likes
3,620
Location
London, United Kingdom
Thanks for the link. I seem to be getting good results with the standard Google Play Music player (in particular I have evidence it can run at 96 kHz just fine), so I think I'm gonna stick to that. I'd like to avoid too "specialized" apps if possible because I'd like my results to translate well to real-world use cases. I want to avoid broken apps, but not necessarily go as far as to use specialist ones.
 
OP
edechamps

edechamps

Addicted to Fun and Learning
Forum Donor
Joined
Nov 21, 2018
Messages
910
Likes
3,620
Location
London, United Kingdom
ADDENDUM

Okay, so I finally managed to make the dongle work with Windows. (It turns out that you need to actually plug something into the dongle for the audio device to show up… *facepalm*)

Windows shows that the device natively supports the 44.1 kHz and 48 kHz sample rates, but not 96 kHz.

Here's how the frequency response looks like with Windows (WASAPI Exclusive, max gain):

frequency-response-windows.png


A bit low in the high treble, but nothing to worry about, really. Spectrograms look good:

spectrograms-windows.PNG
 

restorer-john

Grand Contributor
Joined
Mar 1, 2018
Messages
12,579
Likes
38,280
Location
Gold Coast, Queensland, Australia
Top Bottom