Raising the buffer duration to 8 000ms didn't do a whole lot. But raising it to 30 000ms, and also lowering the low watermark to 0.10 has almost fixed the issue. There is now just the occasional skip (e.g. once every LP play).

Isn't it possible to implement Subsonic in such a way that it buffers the entire song? This is how Sublime works, it actually buffers the playing song plus the two next tracks in the play queue.