Skip to content

Improved IMBE decoder for p25p2#1044

Merged
robotastic merged 4 commits intoTrunkRecorder:masterfrom
staticinvocation:p2_soft_vocoder_upstream
Oct 19, 2025
Merged

Improved IMBE decoder for p25p2#1044
robotastic merged 4 commits intoTrunkRecorder:masterfrom
staticinvocation:p2_soft_vocoder_upstream

Conversation

@staticinvocation
Copy link
Contributor

This patch improves audio quality for P25 Phase 2 by porting Pavel Yazev's fixed-point IMBE decoder which is generally regarded to produce higher-quality audio. Currently, p2 audio is decoded by dequantizing AMBE codewords into IMBE parameters and then feeding those to the "software IMBE decoder" credited to Steve Glass. This patch now optionally enables these dequantized codewords to be fed to the fixed-point decoder instead, through the existing softVocoder config option. AMBE tones are decoded by the "software" decoder

I haven't tested this on a live p2 system (I don't have access to one), but I have tested it using my MBE re-encoding tool. I'm particularly concerned about tones. My testing with pure sine tones didn't go very well, but I think that's actually a problem with the AMBE encoders.

I'm submitting this patch directly to this project instead of op25 because this project already has the softVocoder config option with this implemented for p25p1 and thus I believe this isn't a great fit for upstream.

@SimonSheehan
Copy link
Contributor

Been running this for the last day without issue on multiple machines. P2 audio certainly seems to be much clearer overall. Though I don't understand the code behind it, I can say it's stable as normal and certainly could be merged I feel.

@taclane
Copy link
Contributor

taclane commented Oct 5, 2025

I've had a similar experience with P25p2 audio as well. Somewhat importantly, this PR recognizes the use of the softVocoder config option for P2 systems.

If it turns out that this change produces undesirable audio for your system, it's easy to toggle it back to the way it was with a single line in the config.json. While it doesn't necessarily have to happen in this PR, it should be noted in the documentation that the softVocoder fallback would now apply to Phase 1 and Phase 2 systems.

@staticinvocation
Copy link
Contributor Author

Ah yes good catch @taclane about the documentation. I’ll add that and DMR support in this PR.

I think this is worthy of a larger discussion with boatbod, but it’s my ultimate vision to completely deprecate/remove the software decoder. It’s my opinion that its design is fundamentally flawed, and any attempt to improve it will be a reimplementation of the fixed-point design by Pavel Yazev. Going through the OP25 git history shows that they switched away from fixed-point to the software decoder 12 years ago and without much explanation. My suspicion is because the API was more convenient for the initial phase 2 implementation since it happened around the same time/same commits. My patch has exposed an API that’s mostly equivalent for both decoders so this isn’t a deciding factor anymore.

One of the concerns I have is that the software decoder mixes concerns between IMBE decoding and error handling. Per the P25 spec, there’s a clear delineation point between parameter decode and voice synthesis. That’s because decoding parameters, dequantization, and error correction are the responsibility of the protocol (P25, DMR, etc), not the vocoder. This mix of responsibility explains why some people report better audio quality with the software decoder when they have poor reception. I’d rather just modularize the error correction/handling code out of the vocoders.

@robotastic
Copy link
Collaborator

Thanks @staticinvocation for this very impactful contribution!! If you are able to add more details to the Docs, that would be great. I will merge this in when you give me the thumbs up.

@tadscottsmith
Copy link
Contributor

@robotastic Would you be open to creating a dev branch in the TrunkRecorder repo for this PR? I think working from branches within the same repo could make it easier to compare changes and contribute collaboratively.

@staticinvocation staticinvocation force-pushed the p2_soft_vocoder_upstream branch from 5034bb0 to 24f065c Compare October 7, 2025 17:14
@SimonSheehan
Copy link
Contributor

So one thing I would be looking for with this... i want to be able to use the softVocoder for P1 audio, but take advantage of this improvement on P2 audio. Is this possible?

@ZeroChaos-
Copy link
Contributor

by request I tested this on dmr. While the spectrogram showed a clear improvement, the audio was not perceptibly different. As the audio was good before this patch and remains good with this patch, I have no concerns here.

DMR guy approved.

@staticinvocation
Copy link
Contributor Author

@robotastic I think this is gtg. It would be nice to have a vocoder testing branch for future improvements.

@robotastic
Copy link
Collaborator

Great! Thanks so much @staticinvocation for digging into this and making this upgrade. Happy to put together a branch for future improvements. Just let me know when you need it.

@robotastic robotastic merged commit 065501e into TrunkRecorder:master Oct 19, 2025
1 check passed
TheGreatCodeholio added a commit to TheGreatCodeholio/trunk-recorder that referenced this pull request Feb 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants