# pavsa/hackrf-spectrum-analyzer architecture

> Architecture diagram of the GitHub repository pavsa/hackrf-spectrum-analyzer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/pavsa/hackrf-spectrum-analyzer
- Repository: https://github.com/pavsa/hackrf-spectrum-analyzer

## Overview

This is a Java desktop spectrum analyzer for HackRF. The main workflow is to configure a frequency range and capture settings, start native HackRF sweeps, receive FFT-bin callbacks, and render spectrum, peak/persistence, and waterfall views. Frequency-allocation bands, spur filtering, and screen capture are additional capabilities. The graph uses the README and source-index references plus shown excerpts; unsampled implementation details and some internal call paths are not asserted.

Main entry points: [`src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java) (Analyzer application), [`src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java`](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java) (Settings UI), [`src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrum.java`](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrum.java) (Spectrum dataset), [`src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocations.java`](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocations.java) (Allocation bands)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application"]
  node_analyzer["Analyzer application"]
  node_screen_capture["Screen capture<br/>[ScreenCapture.java]"]
end

subgraph group_controls["Settings and display"]
  node_settings_ui["Settings UI"]
  node_frequency_selector["Frequency selector"]
  node_range_binder["Range binder"]
  node_mvc["MVC controller<br/>[MVCController.java]"]
  node_settings["HackRF settings"]
  node_model_value["Observable values<br/>[ModelValue.java]"]
end

subgraph group_spectrum["Spectrum processing"]
  node_fft_bins["FFT bins<br/>[FFTBins.java]"]
  node_dataset["Spectrum dataset"]
  node_xy_series["Immutable chart series"]
  node_peak_dataset["Peak display data"]
  node_spur_filter["Spur filter<br/>[SpurFilter.java]"]
  node_persistent_display["Persistent display"]
  node_waterfall["Waterfall plot<br/>[WaterfallPlot.java]"]
  node_allocations["Allocation bands"]
  node_allocation_table["Allocation table"]
  node_frequency_band["Frequency bands<br/>[FrequencyBand.java]"]
  node_frequency_range["Frequency range"]
end

subgraph group_device["Device integration"]
  node_native_bridge["Native bridge"]
  node_native_library["Sweep library binding"]
  node_sweep_callback["Sweep callback"]
end

node_operator(("Operator"))
node_hackrf{{"HackRF device"}}

node_operator -->|"sets parameters"| node_settings_ui
node_operator -->|"views results"| node_analyzer
node_settings_ui -->|"binds controls"| node_mvc
node_mvc -->|"synchronizes values"| node_model_value
node_settings_ui -->|"configures"| node_settings
node_settings_ui -->|"uses selector"| node_frequency_selector
node_settings_ui -->|"binds range"| node_range_binder
node_range_binder -->|"updates range"| node_frequency_range
node_analyzer -->|"starts sweeps"| node_native_bridge
node_native_bridge -->|"invokes binding"| node_native_library
node_native_library -->|"captures radio data"| node_hackrf
node_native_bridge -->|"delivers bins"| node_sweep_callback
node_sweep_callback -.->|"reports spectrum"| node_analyzer
node_analyzer -->|"queues sweep bins"| node_fft_bins
node_analyzer -->|"updates spectrum"| node_dataset
node_dataset -->|"consumes bins"| node_fft_bins
node_dataset -->|"creates series"| node_xy_series
node_analyzer -->|"filters spectrum"| node_spur_filter
node_analyzer -->|"uses peak data"| node_peak_dataset
node_analyzer -->|"updates persistence"| node_persistent_display
node_persistent_display -->|"accumulates spectrum"| node_dataset
node_analyzer -->|"renders waterfall"| node_waterfall
node_waterfall -->|"plots spectrum"| node_dataset
node_analyzer -->|"selects bands"| node_allocations
node_allocations -->|"loads tables"| node_allocation_table
node_allocations -->|"uses bands"| node_frequency_band
node_allocation_table -->|"renders bands"| node_frequency_band
node_analyzer -->|"captures screen"| node_screen_capture

click node_analyzer "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java"
click node_settings_ui "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java"
click node_frequency_selector "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/FrequencySelectorPanel.java"
click node_range_binder "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/FrequencySelectorRangeBinder.java"
click node_mvc "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/shared/mvc/MVCController.java"
click node_settings "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/HackRFSettings.java"
click node_model_value "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/shared/mvc/ModelValue.java"
click node_native_bridge "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepNativeBridge.java"
click node_native_library "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/hackrfsweep/HackrfSweepLibrary.java"
click node_sweep_callback "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepDataCallback.java"
click node_fft_bins "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FFTBins.java"
click node_dataset "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrum.java"
click node_xy_series "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/jfc/XYSeriesImmutable.java"
click node_peak_dataset "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrumPeak.java"
click node_spur_filter "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/SpurFilter.java"
click node_persistent_display "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/PersistentDisplay.java"
click node_waterfall "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/WaterfallPlot.java"
click node_allocations "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocations.java"
click node_allocation_table "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocationTable.java"
click node_frequency_band "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyBand.java"
click node_frequency_range "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyRange.java"
click node_screen_capture "https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/capture/ScreenCapture.java"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_analyzer,node_screen_capture toneBlue
class node_settings_ui,node_frequency_selector,node_range_binder,node_mvc,node_settings,node_model_value toneAmber
class node_fft_bins,node_dataset,node_xy_series,node_peak_dataset,node_spur_filter,node_persistent_display,node_waterfall,node_allocations,node_allocation_table,node_frequency_band,node_frequency_range toneMint
class node_native_bridge,node_native_library,node_sweep_callback toneRose
class node_operator,node_hackrf toneIndigo
```

## Components

### Application

- [Analyzer application](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`
- [Screen capture](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/capture/ScreenCapture.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/capture/ScreenCapture.java`

### Settings and display

- [Settings UI](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java`
- [Frequency selector](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/FrequencySelectorPanel.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/FrequencySelectorPanel.java`
- [Range binder](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/FrequencySelectorRangeBinder.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/FrequencySelectorRangeBinder.java`
- [MVC controller](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/shared/mvc/MVCController.java): `src/hackrf-sweep/src/main/java/shared/mvc/MVCController.java`
- [HackRF settings](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/HackRFSettings.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/HackRFSettings.java`
- [Observable values](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/shared/mvc/ModelValue.java): `src/hackrf-sweep/src/main/java/shared/mvc/ModelValue.java`

### Spectrum processing

- [FFT bins](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FFTBins.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FFTBins.java`
- [Spectrum dataset](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrum.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrum.java`
- [Immutable chart series](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/jfc/XYSeriesImmutable.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/jfc/XYSeriesImmutable.java`
- [Peak display data](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrumPeak.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrumPeak.java`
- [Spur filter](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/SpurFilter.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/SpurFilter.java`
- [Persistent display](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/PersistentDisplay.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/PersistentDisplay.java`
- [Waterfall plot](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/WaterfallPlot.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/WaterfallPlot.java`
- [Allocation bands](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocations.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocations.java`
- [Allocation table](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocationTable.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocationTable.java`
- [Frequency bands](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyBand.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyBand.java`
- [Frequency range](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyRange.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyRange.java`

### Device integration

- [Native bridge](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepNativeBridge.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepNativeBridge.java`
- [Sweep library binding](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/hackrfsweep/HackrfSweepLibrary.java): `src/hackrf-sweep/src/main/java/hackrfsweep/HackrfSweepLibrary.java`
- [Sweep callback](https://github.com/pavsa/hackrf-spectrum-analyzer/blob/master/src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepDataCallback.java): `src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepDataCallback.java`

### Other components

- **Operator**
- **HackRF device**

## Connections

- Operator → Settings UI: sets parameters (evidence: `Readme.md`)
- Operator → Analyzer application: views results (evidence: `Readme.md`)
- Settings UI → MVC controller: binds controls (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java`)
- MVC controller → Observable values: synchronizes values (evidence: `src/hackrf-sweep/src/main/java/shared/mvc/MVCController.java`)
- Settings UI → HackRF settings: configures (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java`)
- Settings UI → Frequency selector: uses selector (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java`)
- Settings UI → Range binder: binds range (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/HackRFSweepSettingsUI.java`)
- Range binder → Frequency range: updates range (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/FrequencySelectorRangeBinder.java`)
- Analyzer application → Native bridge: starts sweeps (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Native bridge → Sweep library binding: invokes binding (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepNativeBridge.java`)
- Sweep library binding → HackRF device: captures radio data (evidence: `Readme.md`)
- Native bridge → Sweep callback: delivers bins (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/nativebridge/HackRFSweepNativeBridge.java`)
- Sweep callback → Analyzer application: reports spectrum (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Analyzer application → FFT bins: queues sweep bins (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Analyzer application → Spectrum dataset: updates spectrum (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Spectrum dataset → FFT bins: consumes bins (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrum.java`)
- Spectrum dataset → Immutable chart series: creates series (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/DatasetSpectrum.java`)
- Analyzer application → Spur filter: filters spectrum (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Analyzer application → Peak display data: uses peak data (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Analyzer application → Persistent display: updates persistence (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Persistent display → Spectrum dataset: accumulates spectrum (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/PersistentDisplay.java`)
- Analyzer application → Waterfall plot: renders waterfall (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Waterfall plot → Spectrum dataset: plots spectrum (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/ui/WaterfallPlot.java`)
- Analyzer application → Allocation bands: selects bands (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
- Allocation bands → Allocation table: loads tables (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocations.java`)
- Allocation bands → Frequency bands: uses bands (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocations.java`)
- Allocation table → Frequency bands: renders bands (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/core/FrequencyAllocationTable.java`)
- Analyzer application → Screen capture: captures screen (evidence: `src/hackrf-sweep/src/main/java/jspectrumanalyzer/HackRFSweepSpectrumAnalyzer.java`)
