miegl / PiFmAdv

Advanced Raspberry Pi FM transmitter with RDS encoding
GNU General Public License v3.0
487 stars 82 forks source link

Playing a webstation stops after 3~4 hours (buffer sync problem) #40

Open VincentBruinink opened 5 years ago

VincentBruinink commented 5 years ago

If I route the audio stream of a webstream to the transmitter the audio stops after 3~4 hours.

This is caused by a buffer overflow/underrun because both the input and output streams are not synchronized.

for instance, 44.1kHz input is converted to the internal 228kHz samplerate. So far so good. But in practice 44.1kHz input is not exactly 44.1kHz (it could be 44.050kHz). and the DMA engine which is set to 228kHz is not exactly 228kHz (it could be 227.981kHz). So over time a buffer overflow or under run will occur.

You could fix this by either keep track of the buffer and adjust the 228kHz samplerate of the DMA controller to keep in sync. So if the buffer grows then slightly speed up the 228kHz clock. If the buffer shrinks slow down the 288kHz.

Or,

If the buffer buffer grows, resample the 44.1kHz input data slightly above 228kHz, or if the buffer shrinks, resample slightly below 228kHz.

But both solutions require a major rewrite of the code!

The first solution, slow down or speed up the 228kHz clock will also adjust the 19kHz pilot, 38kHz modulator and 57kHz modulator because the LUT a pre calculated at 228.0kHz.

The second solution, resample the audio slightly below or above 228kHz looks like the best solution because there is no need to resample the 19kHz, 38kHz, 57kHz LUT`s.

Br, Vincent Bruinink.

ThorodanBrom commented 5 years ago

It looks like it's the same error #2 is facing

rashrf commented 5 years ago

Could a different approach that pre-conditions the incoming stream work?

This is likely to be needed anyway because the clock (for example derived from the crystal on a soundcard) won't be perfectly in sync with the local one, the error will eventually lead to an underrun or overrun.

ODR-Audioenc implements this. Could it be useful here?

https://github.com/Opendigitalradio/ODR-AudioEnc/blob/master/src/odr-audioenc.cpp

R.

On Mon, 8 Oct 2018, 07:42 ThorodanBrom, notifications@github.com wrote:

It looks like it's the same error #2 https://github.com/Miegl/PiFmAdv/issues/2 is facing

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Miegl/PiFmAdv/issues/40#issuecomment-427734274, or mute the thread https://github.com/notifications/unsubscribe-auth/AEqK4mMFXsni8kuy8d3p17SGP0DKzClcks5uivPJgaJpZM4XG8dz .

VincentBruinink commented 5 years ago

I think the best solution is implementing a interpolation filter that resamples the audio to 228kHz. Then you can tune the length of the interpolated buffer slightly above and below 228kHz. so you can stay in sync.