snapcast icon indicating copy to clipboard operation
snapcast copied to clipboard

Automatic buffer detection

Open sashahilton00 opened this issue 7 years ago • 3 comments

First of all this is a feature suggestion. I have been playing around with snapcast on my network, and have noticed that on various networks, the buffer settings need to be changed from anywhere between 200 to 1500 to be both reliable and snappy in terms of response time. Given that the client knows when it has to stuff frames or drop them, would it not be possible for the various snapclient instances to feed back that data to snapserver, which in turn increases or decreases the server-side buffer to optimise response time and minimise dropout depending on the network conditions?

sashahilton00 avatar Jun 24 '17 23:06 sashahilton00

it isn't. snapcast is designed to be fed by a player. Clients need to play synchronously. So when being fed a chunk of data on the input pipe, it must be tagged with a timestamp at which the data is going to be played back by the client. This concept does not allow for dynamically adjusting the amount of latency.

Think about it this way: the latency induced is the amount of time the network or your server can stall.

christf avatar Jan 11 '19 17:01 christf

I understand that the latency can't be changed; it results from network conditions and such. What I am suggesting is that the buffer (as passed in the -b parameter) has an optimal value that varies from network to network.

For example, let us assume a network with 420ms latency (highest between client/server out of the group of clients), and the buffer at the default of 1000ms.

What I am proposing is that after, say, 30 seconds of playback without having to play silence/stuff frames, we drop the buffer size by 50ms. This continues until we start seeing the clients playing silence, at which point we raise the buffer back up by 50ms, and set it at that stable level, potentially pairing it with less frequent polling and minor buffer size updates over the duration that the process runs. This results in the fastest response time whilst maintaining an audio stream that doesn't drop out.

Using the above example, the buffer size would steadily decrease until it hit 400ms, at which point we would start seeing dropped frames, etc. which the client reports back to the server, with the server subsequently raising the buffer back to 450ms, which is the optimal buffer size.

Can you explain why that isn't possible? Granted, it may be a bit tricky to handle memory allocation for a dynamically sized buffer, but beyond that, it should be possible?

sashahilton00 avatar Jan 11 '19 17:01 sashahilton00

it is possible, complex and error-prone because the algorithm you describe makes the assumption that latency is constant which it isn't. If you look at the characteristics of wifi, you never know when you get packet drops.

At the same time the back and forth between buffer sizes has to be done synchronously and will be audible. If you want the minimum buffer time, you will have to experiment with different settings and then use the one that seems most appropriate. It is the best solution.

christf avatar Jan 12 '19 14:01 christf