A few years back, I needed a quick, low-frequency, yet very low distortion source to test an onboard micro-controller ADC to see if it had anywhere near the effective number of bits (ENOB) and linearity that the datasheet said.
I knew about the very low distortion, but somewhat complicated design from Linear Technology , but that seemed like overkill for my immediate need. So I ended up building a classical, three op amp, state variable oscillator with a little grain-of-wheat light bulb as the amplitude stabilizing circuit based on a circuit by Hein van den Heuvel .
After a day of fiddling with the loading of various stages of the op amps in the circuit, I managed to get the harmonic distortion products down below -95 dBc level, which was fine for my immediate need.
While a discrete oscillator circuit can be built, it is fiddly. There are temperature issues, like amplitude drift, frequency drift, startup and stabilization time, etc. Likewise, I thought that in the future it would be nice to have a fast setup oscillator with multiple outputs from 2.5 to +/-10 volts so that I could quickly measure any ADC with 16-bit accuracy.
The analog approach is anything but a fast setup, and this got me thinking about how the professional audio analyzers implement their sources. They must either build a precision, discrete DDS or use one of the high-resolution I2S audio DACs, I thought.
I then ran across the TI Application note for their take on the super-low-distortion test oscillator and sure enough, it uses one of their Burr-Brown I2S, audio DACs followed by some high-performance low pass filters .
I bought a few I2S DACs and hooked them up to one of my microcontroller demo boards and in about a day had the I2S running and had some decent signals running out of the setup. The wonderful thing about I2S is that it can be hooked up to the processor’s DMA to make 99% of the data transfer transparent to the processor. All the processor has to do is to keep the DMA pipe filled up every once in a while.
This was a learning experience and not economically advantageous because TI sells their circuit for less than $300, however, there is no published API for controlling their solution from your own test programs.
I then thought, “What about a USB sound card dongle? They must be pretty decent and cheap.”
A quick search revealed that Creative Labs does indeed make a very low cost but high performance 16/24-bit USB dongle, the impressively named “Creative Labs Sound Blaster Play! 3.” This less than $20.00 device even has a 24-bit/96-kHz data rate . I trust Creative Labs to not make junk, so I bought one to try out.
Initial tests with my 18-bit FFT analyzer  showed that not only did the laptop “sound” better to my ear, but that the performance was indeed at the 16-bit level of distortion with a nice clean noise floor.
This approach would indeed be a “Quick Setup” solution for my universal ADC test bench as all the software could be run on my laboratory PCs; now I would have a ‘controllable’ source, frequency and amplitude wise, and it was being run on my PC so I could have standalone applications and even build API’s for inclusion into automated test suites if needed later.
That is a lot of work solved right there, and by using an external sound card the exact amplitude and known quality would be transferable between any test bench, as my test laptops internal sound cards vary all over the place on output amplitude and real sound quality.
Another good thing about using a Laptop for the test controller is that you can pull the power adapter and run on batteries thereby eliminating a lot of ground loop issues that always crop up when you are trying to move quickly and just get the job done.
Enter the BlasterAmp
All the project required now was an analog interface board for the Sound Blaster dongle to get the desired outputs for my “universal” test setup.
I measured the Sound Blaster audio output into the specified headphone load of 300 ohms and with some test tones, and full-scale outputs I measured a consistent 0.37 volts peak, independent of what PC or operating system I used.
A list was made of the usual ADC input ranges (Table 1). I figured that If I cover the common ADC input ranges, anything in between could be measured by using the volume control to adjust the amplitude, this would ultimately lower the achievable signal to noise ratio (SNR) but the Sound Blaster has more than enough SNR for the applications I am looking to measure.
Table 1: These ranges cover almost all of the ADC inputs that I have come across in the last 10 years. This table was used as the basis for figuring out what gains and offsets would be needed for an amplifier at the output of the Sound Blaster dongle.
The 3.3 volt peak range is an oddball, but still comes up in lower resolution, basic designs, that are mostly 10- or 12-bit ADCs anyway, so the decision was made to just use the volume control and 0-5 volt range for these applications, with only a small loss of signal to noise ratio.
I then designed what I call the “BlasterAmp” with the needed gains and offsets to be able to convert the 0.37 volts peak, the full-scale output of the Sound Blaster Dongle to match Table 2.
Table 2: The BlasterAmp was designed to cover the common voltages of table 1 with only 4 gain steps and 3 offset settings. The unipolar ranges require three offset voltages to be used.
One thing to note about the unipolar ranges: these are always “rail to rail” now, and while we say “rail to rail” there is almost always some offset from the “rail.” This will play havoc with any ADC/buffer testing because if the “rail” isn’t exactly at zero or full scale, then the ADC will clip and this will lead to severe distortion that will prevent any meaningful measurements from being made. Also, there are times when the ADC reference voltage is 2.048 or 4.096 volts instead of 2.5 and 5 volts. To account for these situations I used precision, 25-turn trimpots to allow for slight tweaks to the gain and offset to be made when needed. The trimpots also allow for any slight differences in Sound Blaster dongles, resistor tolerances, and op amp offset voltages.
Figure 1 shows one channel of the finished BlasterAmp. Shorting jumpers were used to allow the offset and gain changes as needed to accommodate the various needed output ranges.
Figure 1: One channel of the stereo BlasterAmp. The gain and offset range are set with movable jumpers, and then fine tuned with the aid of precision, 25 turn trimpots. The resistor network around U101 is a 1 k-ohm, matched network from Vishay (OSOPTC1001AT0). All the other resistors are 0.1%, 0805 sized to minimize resistor heating and subsequent distortion. C100 and C101 must be film or COG ceramic types to eliminate distortion.
For the amplifiers, I used the tried and true Burr-Brown OPA1611, an ultra-low-distortion audio op amp and they performed as per the datasheet, which is to say excellently.
For the offset reference voltage, I used the TI REF5050, which is a precision 5-volt reference.
Since the circuit is expected to be used on my bench in a test setup arrangement, I designed it to be powered by +/-15-volt rails, and used another tried and true component, namely the HP6234A dual linear power supply that I keep on my bench for such occasions. The use of a linear power supply like the HP6234A is really useful because of its low noise, low IO capacitance design, and the fact that it isn’t spewing common-mode currents from a switching power supply everywhere. If I had to use a switcher to power the design I would have used some linear, low-dropout regulators and hefty common-mode choking in the circuit to keep the switching noise off the board as best I could. The trusty HP6234A eliminates all those issues.
I laid the final, two-channel BlasterAmp PCB out to fit in a small-sized Hammond Enclosure  that I didn’t put the cover on, as this would allow for easy changing of the various jumpers and trimpot adjustment (Figure 2).
Figure 2: The completed BlasterAmp. I mounted the PCB in an extruded enclosure for protection. The audio from the sound card is the black cable at the top right of the PCB. Power is supplied from my HP6234A linear bench supply via the wire connector at the middle right of the PCB. The complete design is available, see reference 10.
Universal maxim: Hardware needs software
Using the Sound Blaster dongle certainly simplified the design greatly and saved development time, but I still needed a way to play high dynamic range test signals into the Sound Blaster. I tried probably a dozen audio test tone software solutions and most of them were only at the 60-dBc distortion level or less, which is fine for listening tests, but not OK for my application, I needed to get the distortion down to the 16-bit level.
There are several audiophile sites on the internet that provide very low distortion files for testing . For playback you need a WAV or MP3 file player that has zero dead time when looping. I have found that the stupidly named program “foobar2000” is an excellent choice . I originally used the program to play white noise on my laptop when I am traveling to drown out extraneous sounds when trying to sleep, and you can’t have any clicks or pops when looping a white noise file either, or you will immediately wake up. The foobar2000 program works wonderfully for the BlasterAmp and for sleeping.
These canned test files have a fixed frequency, but the amplitude can be fine-tuned as needed by the BlasterAmp trimpots or the PC’s volume control.
As for being able to programmatically set the frequency and volume, I found a Python library called PyAudio  that allows me to generate a precision sine wave signal of a given amplitude and then be able to play this directly from the Python script . This has proven to produce very low distortion signals as can be seen in Figure 3.
Figure 3: Results of the BlasterAmp when set to the +/-10V range as measured on my DMT9000 FFT analyzer . The full scale distortion products can be seen to be at the 16 bit level of -96 dBc below full scale.
Care must be taken in generating any test tone, however. You will either have to make a file that is continuous and long enough for your test, or you will have to continuously loop. When looping just make sure that the start and the endpoints of your waveform line up exactly or there will be a discontinuity that will add distortion at the loop point.
As a final note on using the Sound Blaster dongle for precision tone generation, be sure to turn off any audio equalizers or control programs on the PC that the sound generation is being played on just to make sure that there are no unforeseen issues.
In the next article, I will show techniques for using the BlasterAmp to measure some actual ADCs and test components for distortion.
The complete source code for the Python scripts and the full schematic for the BlasterAmp can be found on Github .
 Jim Williams, Guy Hoover, “Fidelity Testing for A→D Converters”, Linear Technology AN132:
 Hein van den Heuvel, “Reference Sine Wave Generator”, Elektor Post, Project No. 53 – https://www.elektormagazine.com/index.php/files/attachment/326
 Precision Signal Injector (PSI) Evaluation Module for Testing ADC Performance, Texas Instruments – https://www.ti.com/tool/PSIEVM
 Creative Labs Sound Blaster Play! 3 – https://us.creative.com/p/sound-blaster/sound-blaster-play-3
 A future design article will detail my DMT9000 18 Bit FFT Analyzer Instrument.
 Hammond Manufacturing, Extruded Enclosures – https://www.hammfg.com/electronics/small-case/extruded/1455
 “foobar2000” looping audio playback program – https://www.foobar2000.org/download
 The PyAudio installer is broken as of May 2022, a fixed version can be downloaded from – https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio
 The complete BlasterAmp design and the Python Scripts can be found at – https://github.com/Hagtronics/BlasterAmp
—Steve Hageman has been a confirmed “Analog-Crazy” since about the fifth grade. He has had the pleasure of designing op-amps, switched-mode power supplies, gigahertz-sampling oscilloscopes, Lock In Amplifiers, Radio Receivers, RF Circuits to 50 GHz and test equipment for digital wireless products. Steve knows that all modern designs can’t be done with Rs, Ls, and Cs, so he dabbles with programming PCs and embedded systems just enough to get the job done.
>> This article was originally published on our sister site, EDN.
- Accounting for sampling clock jitter in data acquisition applications
- Bringing analog circuit design into the digital age
- Using Python to simplify noise analysis of mixed-mode signal chains
- Eliminating level shifters in microcontroller applications: Design considerations
For more Embedded, subscribe to Embedded’s weekly email newsletter.