Frank Paynter and I have been going round this well-trodden route. After reading through it again, I was struck by an idea for a QoS heuristic, based on my previous chats in this area with Stuart Cheshire.
A key difference between TCP streams and VoIP or other 'real time' streams is that TCP packets always tend toward the size of the maximum permissible packet size for the route (often around 1500 bytes due to Ethernet packet sizes). Real-time packets sacrifice efficiency to achieve lower latency, and typically send smaller packets (the efficiency loss is that the per-packet addressing overhead is a larger proportion of the overall stream).
Stuart has argued that the best QoS algorithm is the simplest - move RT packets to the front of the queue, minimizing their latency. This only needs a single QoS bit.
So here's my proposal: use packet length as a heuristic for latency needs. When queuing, move shorter packets to the front of the queue.
You're only queueing when congestion is involved, so this should have little or no effect on the uncongested case. It will increase the Round Trip Time marginally for TCP, which should make it back off accordingly, and will make TCP-type packets more prone to dropping due to queue overflow (which is the desired effect as TCP adapts to this).