I have the book:
Here's my DDS sim. A tiny ARM cpu generates a DDS sine wave in software, with a 50 KHz interrupt rate and its internal 10 bit DAC. The spice sim uses a sample+hold and quantizer to simulate that.
When V4 is around 400 Hz, the output looks really nice. At, say, 5377 Hz, you can zoom in on the voltage peaks and see them getting ragged. The FFT shows the corresponding sidebands around 50 KHz.
This stuff is fun, in a geeky sort of way. Better than working on the deck.
The filter was made from parts that were already on the pcb BOM; it's not bad.
Version 4 SHEET 1 2228 980 WIRE 176 -208 112 -208 WIRE 400 -208 176 -208 WIRE 112 -160 112 -208 WIRE 624 -160 576 -160 WIRE 688 -160 624 -160 WIRE 1024 -160 816 -160 WIRE 1168 -160 1104 -160 WIRE 400 -144 304 -144 WIRE 816 -96 816 -160 WIRE 304 -80 304 -144 WIRE 112 -48 112 -80 WIRE 816 16 816 -16 WIRE 304 48 304 0 WIRE 1760 96 1728 96 WIRE 1760 128 1760 96 WIRE 368 144 304 144 WIRE 400 144 368 144 WIRE 608 144 560 144 WIRE 640 144 608 144 WIRE 1024 144 816 144 WIRE 1168 144 1168 -160 WIRE 1168 144 1104 144 WIRE 1248 144 1168 144 WIRE 1392 144 1328 144 WIRE 1456 144 1392 144 WIRE 1600 144 1536 144 WIRE 1728 144 1600 144 WIRE 1824 160 1792 160 WIRE 1888 160 1824 160 WIRE 1920 160 1888 160 WIRE 1728 176 1680 176 WIRE 304 208 304 144 WIRE 560 208 560 144 WIRE 816 208 816 144 WIRE 1168 208 1168 144 WIRE 1392 208 1392 144 WIRE 1600 208 1600 144 WIRE 1760 224 1760 192 WIRE 1760 224 1728 224 WIRE 1168 304 1168 272 WIRE 1600 304 1600 272 WIRE 304 336 304 288 WIRE 560 336 560 288 WIRE 816 336 816 288 WIRE 1392 368 1392 272 WIRE 1680 368 1680 176 WIRE 1680 368 1392 368 WIRE 1824 368 1824 160 WIRE 1824 368 1680 368 FLAG 1600 304 0 FLAG 1728 224 P FLAG 1728 96 N FLAG 1888 160 OUT FLAG 304 336 0 FLAG 560 336 0 FLAG 368 144 P FLAG 608 144 N FLAG 1168 304 0 FLAG 112 -48 0 FLAG 176 -208 GEN FLAG 304 48 0 FLAG 816 16 0 FLAG 816 336 0 FLAG 624 -160 S SYMBOL res 1120 128 R90 WINDOW 0 -50 55 VBottom 2 WINDOW 3 -42 58 VTop 2 SYMATTR InstName R1 SYMATTR Value 1K SYMBOL cap 1152 208 R0 WINDOW 0 -69 28 Left 2 WINDOW 3 -74 66 Left 2 SYMATTR InstName C1 SYMATTR Value 27n SYMBOL res 1344 128 R90 WINDOW 0 -50 55 VBottom 2 WINDOW 3 -42 58 VTop 2 SYMATTR InstName R3 SYMATTR Value 5K SYMBOL res 1552 128 R90 WINDOW 0 -52 63 VBottom 2 WINDOW 3 -42 61 VTop 2 SYMATTR InstName R4 SYMATTR Value 5K SYMBOL cap 1376 208 R0 WINDOW 0 -67 31 Left 2 WINDOW 3 -71 68 Left 2 SYMATTR InstName C3 SYMATTR Value 10n SYMBOL cap 1584 208 R0 WINDOW 0 -71 32 Left 2 WINDOW 3 -67 68 Left 2 SYMATTR InstName C4 SYMATTR Value 1n SYMBOL Opamps\\UniversalOpamp2 1760 160 M180 WINDOW 0 28 46 Left 2 SYMATTR InstName U2 SYMBOL voltage 304 192 R0 WINDOW 0 58 46 Left 2 WINDOW 3 62 86 Left 2 SYMATTR InstName V2 SYMATTR Value 5 SYMBOL voltage 560 192 R0 WINDOW 0 58 46 Left 2 WINDOW 3 62 86 Left 2 SYMATTR InstName V3 SYMATTR Value -5 SYMBOL voltage 112 -176 R0 WINDOW 0 38 139 Left 2 WINDOW 3 -33 185 Left 2 WINDOW 123 27 173 Left 2 WINDOW 39 0 0 Left 2 SYMATTR InstName V4 SYMATTR Value SINE(0 1 5377) SYMBOL SpecialFunctions\\sample 480 -176 R0 WINDOW 0 -12 -40 Left 2 SYMATTR InstName A1 SYMBOL voltage 304 -96 R0 WINDOW 0 66 100 Left 2 WINDOW 3 39 138 Left 2 WINDOW 123 27 173 Left 2 WINDOW 39 0 0 Left 2 SYMATTR InstName V5 SYMATTR Value PULSE(0 2 0 1u 1u 5u 20u) SYMBOL voltage 816 -112 R0 WINDOW 0 87 23 Left 2 WINDOW 3 55 64 Left 2 WINDOW 123 71 108 Left 2 WINDOW 39 0 0 Left 2 SYMATTR InstName V1 SYMATTR Value SINE(0 1 1K) SYMATTR Value2 AC 1 SYMBOL res 1120 -176 R90 WINDOW 0 -50 55 VBottom 2 WINDOW 3 -42 58 VTop 2 SYMATTR InstName R2 SYMATTR Value 1T SYMBOL bv 816 192 R0 WINDOW 3 20 121 Left 2 WINDOW 0 62 40 Left 2 SYMATTR Value V=int(512.5*V(s))/512 SYMATTR InstName B1 TEXT 1616 -72 Left 2 !.tran 0 100m 0 500n TEXT 1232 -104 Left 2 ;P540 10KHz 3P DDS LPF TEXT 1288 -8 Left 2 ;JL Oct 21, 2017 TEXT 592 -112 Left 2 ;SAMPLER TEXT 360 -40 Left 2 ;50 KHz IRQ TEXT 1616 -16 Left 2 !;ac dec 20 1K 100K TEXT 864 272 Left 2 ;QUANTIZER TEXT 1256 -56 Left 2 ;10 BIT DDS AT 50 KHZ