(hopefully I'm addressing the proper community)

I'm building a KaRadio32 internet radio variant.

Every now and then I'm experiencing some annoying hiccups from my radio (due to my flaky internet connection, probably): I'm watching my radio's queue status in real time and see how it empties itself right before a hiccup.

Some streams behave nice and fill up the queue up to a certain percentage, then they just play indefinitely. Some streams don't behave nice and fill up the queue too much, and then stop filling it up for a while, while it empties completely and causes hiccups.

While this problem may indeed be my internet connection, or something on the streaming end, troubleshooting it now left me wondering - how, if at all, does internet radio handle synchronization with the source?

Apologies if that's a basic question (or if I'm looking at it wrong), but I cannot seem to find any proper answer anywhere. But...

Let's consider an audio stream of 44100 samples per second, that originated at someone's computer on the other side of the globe, and, by the means of internet, arrived to my radio. Originating computer has its own master clock, and derives 44100Hz to drive its soundcard ADC (and in turn get samples) from that.

But local radio's master clock, while being close in frequency to master clock of the source, cannot possibly be equal to source's master clock, and therefore, cannot derive the same exact 44100Hz required to reproduce stream with exact same speed. Since both clocks are freerunning (I assume), this will eventually, depending on frequency difference, lead to local queue either being overflown and missing bits of data, or underflown, causing hiccups.

For this to not happen, there should be some kind of mechanism that would slightly adjust local playback speed/master clock, according to some average stream speed. Or, perhaps, perform slight resampling, or drop/duplicate samples.

I've taken a look into KaRadio32 source code, and at the moment I don't see anything our of ordinary - there's a FIFO, which is filled by stream data writer thread (as data arrives), and gets read by either a software decoder or VS1053b codec threads. So far I only see that there's no special processing for such situations, suggesting to me that this is either handled somewhere not on the receiving end, or not handled at all.

  • 1
    Most crystals are at 20 ppm or better, so even if one is at the high end of the range and the other at the low end of the range, that’s less than 4 seconds difference over a whole day. If the receiver is faster than the sender it will slowly empty its buffer and at some point will stop and start buffering again. If the sender is faster, the queue will fill up until it overflows and the same thing will happen, I suppose…
    – jcaron
    Nov 23 '21 at 14:09

Your Answer

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

Browse other questions tagged or ask your own question.