You may have noticed that I like to measure things. I just added another example program to the GitHub repo, this time for measuring the impulse response of audio adapters. The results are pretty interesting. You can clone the repo and test your soundcard, too.
The impulse_response example program generates a single-sample impulse at the specified sampling rate. In this case, 500 samples of 0, followed by a single sample of 1, then 500 more 0's, and repeats this forever. The output from the card is then a representation of the system's impulse response. This first waveform, taken from one of those tiny $8 SYBA USB audio adapters, is funny for several reasons. This dongle uses a CM119 chip from C-Media, as a brief hammer and chisel session revealed:
The output from this card is slightly bizarre. From the output shown above, it looks like there's no analog filtering whatsoever on the output - you get discrete steps right from the DAC, but digital filtering has been applied before the DAC. The card only supports 44.1 or 48kHz, and the output above was set to 48kHz. However, the output is sampled at 96kHz (see cursor measurement), and has been digitally filtered with an approximation of the sinc function. This is just plain weird (not the sinc part, which is the correct reconstruction filter for frequency domain accuracy).
It's this upsampling that causes the stray dots in the vector display - in between desired dots and as ringing artifacts. On the plus side, this card does draw discrete points on the display, even if it adds a few extra.
One of the challenges of this project is that soundcards/audio adapters are designed to sound good by reproducing the signal accurately in the frequency domain. This is a different goal from reproducing the signal accurately in the time domain. The sinc function is the ideal reconstruction filter for the frequency domain, but what we'd really like is a Gaussian filter, which shows minimum step times with no overshoot or ringing.
I think I know what's going on here. I had read about oversampling interpolating DACs before, but didn't recognize this one when I saw it. Analog Devices has a nice whitepaper on the concept here. The idea is to reduce the requirements on the post-DAC analog anti-aliasing filter, so that a lower-order filter can be used. In this case, they've taken it to an extreme, and used *no* anti-aliasing filter at all. I guess the assumption is that your headphones will act as the filter. I also remembered that I can look at the frequency response implied by the impulse response using the FFT on the scope:
It's tough to read from the image, and the cursor view obscured the trace, but I measured the response as -3dB down at 18.7 kHz. The deep trough is about 50dB down, and extends from 37 to 61kHz. If you followed this DAC with an analog filter that dropped substantially before 61KHz, it wouldn't look that bad (as it is, the harmonics extend pretty high). @Thomas mentioned that you might use an adapter like this as a MW transmitter, and now I believe it!
I am tempted to dig out my bag of 5532 amps, whip up a decent lowpass, and see how nice I could make this cheap adapter look.
Here's a similar test using the output of the audio adapter built into my desktop motherboard, reported as:
00:14.2 Audio device: Advanced Micro Devices, Inc. [AMD/ATI] SBx00 Azalia (Intel HDA) (rev 40)
It's an Azalia audio chipset.
This is more like what I expected to see, a nice representation of a sinc waveform, the ideal reconstruction filter. Again, perfect for audio, but if you try to draw a single dot on the vector display, you get this ringing.
Raspberry Pi 1 Model B
Here's the same thing from the audio output of the RPi.
This thing is a fucking train wreck.
The response jumps between three different shapes, none of which resemble a good sinc. This isn't too surprising, since the RPi "audio" output is actually just an RC-filtered PWM. It appears that the response you get depends on how the PWM phase hits, maybe? You can also see the RC filter at work turning steps into exponentials. I'll have to think about this one a little more, but it looks like there is some digital filtering, the PWM, then the RC analog filtering going on.
In any case, this output probably isn't the best for vector display output, and should be relegated to sound effects, making coarse bleeps and bloops to accompany your retro vector game creations.
SYBA 24 Bit 96KHz USB DAC
In the middle of writing this log, the UPS person dropped one of these on my doorstep. The 24-bit isn't really interesting and I haven't had much chance to play with it yet, but here's what I found so far using 96kHz sampling rate.
First, the output is inverted! This is sheer apostacy for audiophiles who insist on absolute phase. There is also a ridiculous amount of noise. I've only used this adapter for a few minutes, and haven't even tried music through it, so it's entirely possible I've screwed something up. I'll play with it a bit more, and report back later.
Anyway, this has been very interesting. I had no idea soundcards would be so different...