Extract main.js's client-side state makers for reuse.
Suppress unnecessary LocalCell updates.
Introduce a local but read-only cell
Use meter widget for read-only range types.
Add visible client audio state and revise buffer-sizing algorithm.

The audio buffer is now measured in samples instead of chunks
(which were arbitrary) and the target buffer size is determined
continuously and directly from the min/max buffer fullness. The old
algorithm seemed to be wrong; e.g. it would only _decrease_ the queue
limit in the event of an _overrun_.

All the console spam about overrun/underrun is replaced with the info
object. In the future there might be settings such as mute, volume, or
preferences about latency.
Use separate spectrum_fft msg_queue for every state stream.

Previously, in the presence of multiple state streams each FFT frame
would go only to whichever one of them grabbed it first; now all of
them get it.

Note that StreamCell.get now returns uninterpreted bytes rather than any
more sensible value -- but we never actually use that value, so it's not
worth fixing for now.

In a future revision I hope to arrange so that the FFT processing itself
is shut off when no client is actually looking at it, and the frame rate
(and possibly averaging) is selected based on client request (much like
the audio stream); this does none of that but is a step in the right
direction.