Here is another version of the DAC+Arduino signal generator. This version drops the idea of using interrupts, and instead sets the output values in a loop which invokes the builtin delay() and delayMicroseconds() functions. The delays are set from the period between samples of the waveform, minus a small amount to account for the time taken to execute the loop. We can make this time constant, or close to it, by precomputing all the output samples and storing them in an array.
The sine and triangle waves are quite clean, the square and sawtooth waves less so. I wonder if the MCP4921 doesn't like big voltage swings. Here are some sample outputs:
Square waves work to about 20kHz, the others to less, depending on how many samples you use.
And here is the code: