Triangles are really easy: all equal value resistors! I didn't mention earlier, but all resistors should be 1% tolerance or better metal-film for low noise and distortion. In volume, these are only a fraction of a cent in surface-mount flavors. The cost of mounting is larger than the piece part cost!

I've never had a chance to verify with a scope (can't afford one), but some of those annoying sounds (sine, square, sawtooth) that your wife complains about can be easily generated with Audacity (http://audacity.sourceforge.net), an opensource project. They claim 0.001 Hz resolution, but I'm sure it's really a function of your soundcard quality, e.g. software vs. on-board vs. discrete card. The nice bit is there are additional community driven plug-ins for generating other tones like DTMF, etc.

The rig looks sweet, but figured you have a old PC sitting around and since this is an audio project, the response is probably good enough using a device designed for producing the same (think about MIDI files)...just in case you forget the new tasty at home or office one day.

Note that you can use another set of resistors and an op amp to genererate a triangle, square wave, or other approximate (symmetrical) wave form at the same time off the same register, since the output impedance of modern digital chips is very low compared to the R you'll use with the op amp.

See David's post above. My original application aws used in a couple of designs covering the full audio range. As David pointed out, the main distortion products are pretty high-order, thus the single pole of the small capacitor in parallel with the summing op amp does a pretty good job (depending on how many decades of range you want to support). For my designs, the range was a single decade (telecom range of 300Hz-3KHz) and distortion was well under a percent as I recall. This was back when i worked for Motorola Comm division in South Florida. My designs always had the highest gross margins in the company despite being considered the "razors" of the business, not the blades!

What an elegant idea! Long ago a test engineer designed a production test fixture for one of my products that required a low frequency sine wave signal. I suggested that he use a Wien-bridge oscillator, but he was of the digital persuasion and used a squave oscillator, a counter chain, a PROM with the sine conversion lookup table, and a D-to-A.

If only he (and me) had known about what you just described. Any idea of the distortion specs vs number of shift stages?

@mhrackin I also used this technique. It was the subject of an article in Elektor magazine. I recalculated the resistor values for a 10-bit shift register and used it for a synthesised frequency generator giving a precise 45 to 55 Hz output for testing frequency-sensitive relays (I worked for an electricity utility at the time). It worked really well. Because the primary harmonics (for an 8-bit register) are the 15th and 17th, you can just use RC filtering and it gives you an almost perfect sine wave. I amplified that with a fairly standard audio amp and transformer to 220V for the output. It was a great project. Sometime I'd like to take it further and design a wider range generator using a switched-cap filter chip fed by the Shift Register clocking signal to do the filtering. Oh for a bit more spare time.....

Back in the 1970s I created a little circuit that used a SINGLE digital chip to create a pretty good sine wave. Take an 8-stage shift register (CMOS preferably) and tie the last stage output (inverted; use a transistor if your design doesn't have a spare somewhere). Oh, and you do need to tie the reset line to a power-up reset (which any digital design should have)That makes what is called a "switch-tail shift register" that will start out with all 8 outputs zero. First clock pulse will fill the first stage with a "1" which will propagate through until all outputs are 1, at which point the next pulse will start filling with "0"s. That's a divide-by-16. Here's the neat part: connect each stage's output to a resistor of a value inversely proportional to sine (22.5 degrees*stage number) ignore the sign! Connect the other ends of all resistors together and to the summing junction (negative input) of an op-amp. Connect the output of the op amp back to the summing junction with a feedback resistor roughly equal to the parallel value of all the input resistors, and put a small capacitor in parallel with the feedback resistor (this filters the spikes from the sharp edges of the digital outputs). Use your favorite programmable counter design to create the clock at 16 times the desired output frequencies (by changing the programming), or if you have even the tiniest little microP handy, use its programmable timer (of course you could use an 8-bit output parallel port to even eliminate the shift register....). The rest I leave to the student as an exercise! You can probably build this today for less than a buck!