Skip to content

Add AM spectrum ZOOM x3/x4 with optimized x4 decimation - #3304

Merged
gullradriel merged 4 commits into
portapack-mayhem:nextfrom
Brumi-2021:feature/am-spectrum-zoom3-zoom4
Aug 28, 2026
Merged

Add AM spectrum ZOOM x3/x4 with optimized x4 decimation#3304
gullradriel merged 4 commits into
portapack-mayhem:nextfrom
Brumi-2021:feature/am-spectrum-zoom3-zoom4

Conversation

@Brumi-2021

@Brumi-2021 Brumi-2021 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Brief description of what you did

This PR addresses one of the points highlighted during the review of Feature/sliding freq (#3280).

After the sliding-frequency architecture was introduced, the AM/SSB spectrum view became significantly wider than before. While this wider spectrum is useful for sliding tuning, AM/SSB reception can also benefit from narrower spectrum views, especially when inspecting narrow-band signals.

This PR adds ZOOM x3 and ZOOM x4 to AM/SSB and AM-FM Wefax, recovering a level of spectrum detail closer to what was available before #3280 while retaining the new sliding-tuning architecture.

The existing audio DSP path is left unchanged. The additional zoom levels are implemented only in the spectrum branch.

Spectrum resolutions are now:

Zoom FFT input Fs Resolution
x1 192 kHz 750 Hz/bin
x2 96 kHz 375 Hz/bin
x3 48 kHz 187.5 Hz/bin
x4 24 kHz 93.75 Hz/bin

For ZOOM x4, the spectrum decimation path is optimized as:

384 kHz → /4 → 96 kHz → /2 → 48 kHz → /2 → 24 kHz

A dedicated 32-tap real FIR performs the first /4 decimation, followed by the existing half-band decimators. This substantially reduces M4 processing compared with the initial implementation using four consecutive /2 half-band stages.

Explicit capture-buffer ownership was also added to prevent a new real-time spectrum capture from overlapping with deferred spectrum processing.

AM-FM Wefax also gains ZOOM x3/x4 through the same spectrum-decimation mechanism. Its existing demodulation and tuning behavior is unchanged; sliding tuning is not enabled for Wefax.


Proof that your changes work

🖥️ Proof it compiles

Successfully compiled with both development and official toolchains.

Development build

  • GCC ARM 14.3.1
  • VS Code / CMake build
  • Build completed successfully with exit code 0.

Official GCC ARM 9.2.1 Docker builds

  • HackRF One target: compiled successfully.
  • HackRF Pro target: compiled successfully.
  • Both firmware images and PPFW packages were generated without errors.

HackRF One final build:
Space remaining in flash ROM: 28436 bytes (2.7%)

HackRF Pro final build:
Space remaining in flash ROM: 2575716 bytes (70.2%)

The HackRF Pro 4 MB image, including the FPGA bitstream, was also generated successfully.

Note : I uploaded both bin packages, (Hackrf one / Hackrf PRO) in the discord test-drive for your advance testing.

📱 Proof of testing on a real device

Tested successfully on real hardware:

  • HackRF One r1-r8
  • HackRF One r9
  • HackRF Pro

ZOOM x1, x2, x3 and x4 were tested on the AM/SSB receiver.

All four zoom levels show coherent spectrum scaling and normal waterfall cadence.

Measured M4 CPU utilization on HackRF One after the x4 optimization:

  • ZOOM x1: ~54%
  • ZOOM x2: ~62%
  • ZOOM x3: ~78%
  • ZOOM x4: ~67%

The optimized x4 implementation therefore restores substantial CPU margin compared with the initial implementation and maintains normal waterfall refresh behavior.

Remark :
On both HackRF One and HackRF Pro hardware, the previous Feature/sliding freq (#3280) implementation was observed to report ~100% M4 CPU utilization in both of its available AM spectrum zoom modes (x1/x2).

📡 Proof against a real emitter/receiver

Tested receiving real AM broadcast signals on HackRF One and HackRF Pro.

The same received signal was compared across ZOOM x1/x2/x3/x4. The spectrum shape remains coherent as the displayed bandwidth is progressively reduced, including ZOOM x4.

Image rejection was also checked with real signals and no problematic alias image was observed at normal, non-saturating RF levels.

The HackRF Pro shows symmetric components near ±23 kHz that are also present in firmware predating PR #3280. This appears to be a separate HackRF Pro hardware/RF configuration issue and is not introduced by this PR.

image image

📚 Wiki documentation commitment

  • [X ] I will (or already) create(d) wiki document for my newly added feature

Checklist

  • [X ] Kept changes minimal and limited to necessary files
  • [X ] Verified functionality remains intact and code compiles
  • [ X] Attached proof that the code compiles successfully (or marked N/A as a trusted contributor)
  • [X ] Attached proof of testing on real PortaPack hardware (or marked N/A as a trusted contributor)
  • [X ] Attached proof of testing against a real emitter/receiver (if RF-related), or marked N/A with justification
  • [X ] I understand that by getting this PR merged, I am implicitly agreeing to create or update the corresponding wiki page (including a main-screen screenshot, description, controls, and limitations)
  • [X ] I own all rights to this code (i.e., all code contained in this PR), including compliant usage rights for third-party libraries, and I agree that this code is licensed under the license of this project (GPL-3.0).
  • [N/A ] If any third-party libraries are used, I confirm that their licenses comply with the requirements for contributing to this repository.
  • [X ] Reviewed the Contributing Guidelines

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds AM/SSB and AM-FM Wefax spectrum zoom x3/x4 while preserving existing audio processing.

Changes:

  • Adds x3/x4 zoom controls and tuning limits.
  • Introduces optimized x4 FIR decimation.
  • Adds capture ownership to prevent overlapping processing.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
firmware/common/message.hpp Defines new zoom factors.
firmware/common/dsp_fir_taps.hpp Adds x4 FIR coefficients.
firmware/baseband/proc_nfm_audio.cpp Handles capture-start failure.
firmware/baseband/proc_am_audio.hpp Extends AM spectrum state.
firmware/baseband/proc_am_audio.cpp Applies variable decimation.
firmware/baseband/filtered_spectrum_collector.hpp Defines AM capture state machine.
firmware/baseband/filtered_spectrum_collector.cpp Implements deferred multistage decimation.
firmware/baseband/dsp_decimate.hpp Declares the /4 decimator.
firmware/baseband/dsp_decimate.cpp Implements optimized /4 FIR processing.
firmware/application/receiver_model.hpp Tracks spectrum zoom state.
firmware/application/receiver_model.cpp Propagates zoom configuration.
firmware/application/baseband_api.hpp Extends AM configuration API.
firmware/application/baseband_api.cpp Sends selected spectrum zoom.
firmware/application/apps/analog_audio_app.hpp Adds zoom options and limits.
firmware/application/apps/analog_audio_app.cpp Connects zoom UI and sliding tuning.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread firmware/application/receiver_model.hpp
@Brumi-2021

Brumi-2021 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I checked this flow against the current OptionsField implementation.

OptionsField::set_by_value() calls set_selected_index(), whose trigger_change argument defaults to true. set_selected_index() therefore invokes on_change() even when the selected index is already the same.

When switching from Wefax x4 to normal AM with persisted x1, the AM options view installs the callback first and then calls set_by_value() for the saved AM zoom. This re-applies ZOOM_x_1 through ReceiverModel::set_am_configuration() and sends the updated AMConfigureMessage to the M4 before the waterfall is restarted.

There may be a short intermediate x4 configuration while the AM baseband image is being restarted, but it is immediately overwritten and is not visible because the waterfall is stopped during the mode transition.

So the reported persistent UI/baseband mismatch does not occur with the current OptionsField behavior.

Additional Real test :
I also verified this on real hardware: AM and AM-FM Wefax retain different persisted zoom selections correctly when switching between modes, and the corresponding spectrum zoom is reapplied each time.

@gullradriel gullradriel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks @Brumi-2021 !

@gullradriel
gullradriel merged commit ee568ec into portapack-mayhem:next Aug 28, 2026
3 checks passed
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.

3 participants