0
\$\begingroup\$

I recently started to jump into voice streaming for my RPG game, for players to communicate by a central server point. I use TCP packets to communication from client->server and from server->client(s).

What I currently do is streaming the microphone from the client (push-to-talk), send the voice data in 4096 bytes chunks, and send them to the client. However, since TCP packets take some time to send and process, as well as standard latency issues, the server forwards the packets to other clients with a certain delay (sometimes up to half a second).

How should I compensate for this delay? (What technique do you recommend?)

enter image description here

\$\endgroup\$
3
\$\begingroup\$

I would use UDP since it has lower latency. When a packet is lost, UDP carries on with the next packet instead of waiting for the previous packet to be sent. UDP will also reorder packets, since it is just sending blocks of data, not a stream like TCP. You would need to track the packets as you will have to manually sort the order of the incoming data. Normally you establish an acceptable latency, reordering the packets as they come in (as long as they arrive before your artificial latency) and reject those that are older than your established latency. This packet loss/drop will cause gaps in your audio, but you can mitigate it somewhat by sending redundant audio data in each packet. By detecting and tracking packet loss you can establish a 'quality of service' of the connection and reduce/increase the amount of duplicated data sent per packet.

UDP's lower latency with some drop out is preferable, IMHO, as it lets players have closer-to-realtime conversations.

Alternatively, you could consider slowing down your entire game so the voice matches in game events, but that's not going to make round-trip conversations work very well.

As for how you track packet ordering, I think that's a different question, but basically you need to establish some amount of 'acceptable' latency - say 100ms. You buffer up in-coming packets, putting them back in order as they arrive. Once you have 100ms or more of data you start pulling the data off the front, consuming the now in-order packets. Of course there will likely be dropped packets so you would want to either use the redundant data or incorporate an resend system using ACK/NAK, which sounds like re-inventing TCP but the results are more light weight - for example if the 100ms buffer has been consumed, there's no point requesting data that has already been 'played through'. It's the back bone of most reliable-over-UDP protocols used in most realtime networked games for the past couple of decades.

\$\endgroup\$
  • 1
    \$\begingroup\$ I don't think UDP handles packet order (as you mentioned, packets don't wait for the previous ones), which would mean that voice packets could be mixed with one another (in no particular order) \$\endgroup\$ – Momo Apr 26 '16 at 2:38
  • \$\begingroup\$ @Momo updated the response to reflect your comment, thanks! \$\endgroup\$ – Steven Apr 26 '16 at 2:50
  • \$\begingroup\$ This does answer my question on latency, but how should I handle packet order? For example, if I attributed an ID to each packet (incrementing as they are sent) for the server to order them, it would break the system if a packet was lost. For example, the client would send packets 1, 2, 3, the server could receive 3, 1, and won't know if the packet 2 has yet to be received (to order the packets) or if it was lost. \$\endgroup\$ – Momo Apr 26 '16 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.