OK, here's the circuit:-
Parts List
As mentioned earlier, S1 and S2 are 2P6T "shorting" (make-before-break) rotary switches. At the risk of stating the obvious, the circuit shows a mono attenuator so you need to duplicate for stereo using S1b and S2b.
For the resistors, the calculated "ideal" resistor values are listed, followed by the actual resistors I used in square brackets. All values in Ohms
Rin 4.7 [4.7]
R1 12 [12]
R2 3.6 [3.9]
R3 4.7 [4.7]
R4 5.8 [5.76]
R5 6.8 [6.8]
R6 7.3 [7.3, being 10 parallel 26.7]
R7 1.33 [1.32, being 2.2 parallel 3.3]
R8 1.45 [1.5]
R9 3.3 [3.3]
R10 8.3 [8.2]
R11 18.9 [18]
R12 23 [22]
Rout 150 [150]
Specifications
Minimum input impedance (with 32 Ohms headphones connected): 17 Ohms
Maximum output impedance (with a 16 Ohm source connected): 16 Ohms
Adjustment range: 40dB in 2dB steps
Insertion loss (with 32 Ohm headphones, 16 Ohm source): 5dB
Design
The design goals were:-
i) consistent 6dB and 2dB steps
ii) low output impedance
iii) acceptable input impedance
iv) low insertion loss
Being a passive circuit, some compromise is necessary, so these goals were combined to make an error function which was then minimised using the "solve" function in a spreadsheet.
Are Rin and Rout really necessary?
The impact of source impedance and headphone impedance on the step sizes was investigated. It turns out that the small steps get bigger if the attenuator is connected to a low impedance source and get smaller when connected to a high impedance source. Having the input resistor Rin reduces this effect. Another advantage of Rin is that it makes the input impedance of the attenuator less dependent on the volume setting of the switches. This is handy if you are sharing a headphone output with someone else, because you don't want your volume setting to affect their listening level.
To a lesser extent, the big steps are affected by different headphone impedances and Rout acts to reduce that dependency.
In summary, Rout could happily be omitted, whereas Rin provides two worthwhile benefits.
Step sizes
Steps
should not be too fine and absolutely
must not be too wide. If you can't set a comfortable listening level then the project is a failure. That said, I find the 1.5dB steps on my portable CD player annoyingly narrow. Steps of 3dB would look good on paper (nice ratios) but I suspect 3dB may be a bit coarse, hence the 2dB choice. After a few hours of listening with the attenuator, I'd say 2dB is
almost too narrow, but overall I'm happy. A revised design would have 2.5dB and 7.5dB steps with Rout omitted.
No zero
There is no "off" position, i.e. the attenuator is always letting some signal through. If that's a problem, the fully anticlockwise tab of the "big step" switch S2 could be connected to the ground rail instead of the junction between R7 and R8. This gives a no-output setting but also reduces the attenuation range by 6dB. Personally, I'd add a mute switch to implement this feature.