Skip to content

Implement elastic buffering for audio output#399

Merged
argilo merged 1 commit into
masterfrom
elastic-v2
May 5, 2025
Merged

Implement elastic buffering for audio output#399
argilo merged 1 commit into
masterfrom
elastic-v2

Conversation

@argilo
Copy link
Copy Markdown
Collaborator

@argilo argilo commented May 3, 2025

Replaces #343.
Fixes #68.
Fixes #177.
Fixes #261.
Fixes #330.

The NRSC-5 standard uses a variable-rate audio codec. To account for variations in the instantaneous bit rate, the standard specifies that both the transmitter and receiver use an elastic buffer, so that audio packets enter the transmitter and leave the receiver at a fixed rate, even though the number of packets sent in individual audio PDUs may vary. Unfortunately, the standard does not explain how elastic buffering is implemented, so we are left to guess many of the details.

Up until now, nrsc5 did not implement elastic buffering at all, and instead reported audio packets through its API immediately upon decoding. In this PR I have added elastic buffers (one per stream) which queue audio packets. A batch of audio packets (2 for FM, 4 for AM) is released each time an L1 block is decoded. (In a future PR, we could perhaps even shorten the cadence so that audio packets are released one at a time.)

API clients shouldn't need to make any changes to take advantage of elastic buffering. They will notice that audio packets are now produced in much smaller bursts (2 for FM, 4 for AM) and that the burst size is always identical. As a result, API clients should not need to buffer more than a handful of audio packets.

This PR is a simplified version of #343. That PR attempted to maintain an exact ratio of input RF samples to output audio samples, and I have dispensed with that requirement for now to simplify the implementation. We may need to return to that approach in the future to implement analog blending (#80).

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 3, 2025

Some notable changes:

  • The audio decoder is now reset any time an audio packet is missed. This should help reduce audio artifacts, since the decoder carries over state from one packet to the next, and does not cope well with omitted packets.
  • When an audio packet is missed, the API will still report an audio event, but with silence in the audio buffer.
  • The API now only reports HDC events for the "core" audio stream, and not the "enhanced" stream. (It was a mistake to report both, since the API does not provide any way to distinguish the two streams. In a future PR, we can add separate fields for enhanced packets, as proposed in Enhanced hdc #245).

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 3, 2025

I'll leave this open for a couple days to allow some time for testing. Perhaps some of the usual suspects like @markjfine, @TheDaChicken, and @pclov3r might have some feedback.

@argilo argilo mentioned this pull request May 3, 2025
@markjfine
Copy link
Copy Markdown
Contributor

Seems ok. Trick was finding an intermittent station to test on. The audio is either there or it isn't, with no artifacts when it transitions. Will also continue to test on these as well as stronger stations to see if any overflows happen over an extended listening period.

@markjfine
Copy link
Copy Markdown
Contributor

So while I'm testing, just noticed WWWT removed their broken HD5. 🤦🏻‍♂️

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 4, 2025

Are they still using MP11, or have they switched back to MP3?

@markjfine
Copy link
Copy Markdown
Contributor

Lol. They've removed it completely. Back down to only 4 programs now.
Screenshot 2025-05-04 at 12 55 26 PM

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 4, 2025

What does nrsc5 show for the primary service mode? (You'd need to build with library debug logging turned on to see that.)

@markjfine
Copy link
Copy Markdown
Contributor

11

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 4, 2025

Interesting. I have very few recordings of MP11, so I'd be interested to get another one of WWWT to see how they have things configured now. One minute would be enough.

@markjfine
Copy link
Copy Markdown
Contributor

Uploaded an iq file to https://fineware-swl.com/downloads/WWWT_2505041719.iq

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 4, 2025

Got it, thanks!

The P4 logical channel is completely empty, so they're just wasting the bandwidth.

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 4, 2025

More specifically, the logical channel contains an endless stream of 0x22 0x22 0x22 [...] 0x22.

@markjfine
Copy link
Copy Markdown
Contributor

markjfine commented May 4, 2025

Lol. The station it was carrying was low power and I can't remember if he said were paying to be on HD5 or not. Always thought it was weird that if they were paying for the ride that WWWT didn't care if they were using some corrupted protocol or if car radios couldn't even hear it.

@markjfine
Copy link
Copy Markdown
Contributor

Ok, so I've had this thing going for hours now on WAMU. There were a few crc dropouts, but I'm in a fringe area and that's to be expected (someone could've moved their hay baler on the next road over). No artifacts at any time. 👍🏼

@pclov3r
Copy link
Copy Markdown
Contributor

pclov3r commented May 5, 2025

Doing some testing it seems to be ok and match the behavior that would see on a real hd radio.

@pclov3r
Copy link
Copy Markdown
Contributor

pclov3r commented May 5, 2025

Actually, It appears the elastic buffering doesn't do so well with low SNR conditions and fading.

https://gofile.io/d/UjiYi9

Without the elastic buffering it appears without it decodes a bit better.

Although, This is really pushing the limits and abusing the decoder but something I just noticed.

@argilo
Copy link
Copy Markdown
Collaborator Author

argilo commented May 5, 2025

It looks like the old & new produce the same amount of audio, it's just that the new version inserts silence where the missing packets are, whereas the old version doesn't.

@argilo argilo merged commit 1214b78 into master May 5, 2025
8 checks passed
@argilo argilo deleted the elastic-v2 branch May 5, 2025 14:51
FoxxMD added a commit to FoxxMD/nrsc5-rtlsdr-icecast that referenced this pull request May 5, 2025
@argilo argilo mentioned this pull request May 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Underruns & cracking noises Python CLI has lots of underrun issues Audio events are bursty Pop / click suppression

3 participants