MMO-Style Spectrum Analyzer
Three independently fading signals across a simulated 1 MHz RF channel demonstrate the Spectrum Analyzer's MMO Mode with received-power health bars, leveling, damage effects, enemy classes, and a strongest-signal boss.
- Author GNU Radio World
- Category Spectrum Analysis
- Blocks 21
- Connections 15
- File
spectrum-analysis/mmo_style_spectrum_analyzer.grc
Blocks used
| Block | Module | Used |
|---|---|---|
| Variable | GNU Radio | 4 |
| Multiply Const | GNU Radio | 2 |
| Add | GNU Radio | 1 |
| Constellation Modulator | GNU Radio | 1 |
| Constellation Object | GNU Radio | 1 |
| GUI Layout | GNU Radio | 1 |
| JS Block | GNU Radio | 1 |
| Noise Source | GNU Radio | 1 |
| Note | GNU Radio | 1 |
| OFDM Transmitter | GNU Radio | 1 |
| Random Uniform Source | GNU Radio | 1 |
| Rotator | GNU Radio | 1 |
| Signal Source | GNU Radio | 1 |
| Spectrum Analyzer | GNU Radio | 1 |
| Stream to Tagged Stream | GNU Radio | 1 |
| Throttle | GNU Radio | 1 |
| Vector Source | GNU Radio | 1 |
Notes in this flowgraph
- A simulated 1 MHz channel centered at 915 MHz Left: narrow carrier at -300 kHz Center: pulse-shaped QPSK, 8 samples/symbol Right: QPSK OFDM at +300 kHz, 256-point FFT with 52 active carriers Each signal slowly eases toward an independent random power level every 3-7 seconds, making health changes and damage effects easy to see. Low-level receiver noise gives the automatic detector a realistic floor to learn.
Flowgraph source
spectrum-analysis/mmo_style_spectrum_analyzer.grc
options:
parameters:
author: GNU Radio World
comment: ''
copyright: ''
description: Three independently fading signals across a simulated 1 MHz RF channel demonstrate the Spectrum Analyzer's MMO Mode with received-power health bars, leveling, damage effects, enemy classes, and a strongest-signal boss.
generate_options: qt_gui
id: MMO_Style_Spectrum_Analyzer
title: MMO-Style Spectrum Analyzer
states:
coordinate: [10, 10]
rotation: 0
state: enabled
blocks:
- name: center_freq
id: variable
parameters:
comment: ''
value: '915000000'
states:
coordinate: [600, 10]
rotation: 0
state: enabled
- name: ofdm_offset
id: variable
parameters:
comment: ''
value: '300000'
states:
coordinate: [770, 10]
rotation: 0
state: enabled
- name: samp_rate
id: variable
parameters:
comment: ''
value: '1000000'
states:
coordinate: [950, 10]
rotation: 0
state: enabled
- name: tone_offset
id: variable
parameters:
comment: ''
value: '-300000'
states:
coordinate: [1120, 10]
rotation: 0
state: enabled
- name: analyzer
id: wasm_spectrum_analyzer_sink
parameters:
affinity: ''
alias: ''
average: '0.2'
center_freq: center_freq
comment: ''
db_per_div: '10'
fftsize: '8192'
level_offset_db: '0'
level_unit: dBFS
mmo_mode: 'True'
name: Three-Signal Spectrum
reference_level: '0'
samp_rate: samp_rate
trace_mode: average
type: complex
update_time: '0.1'
wintype: window.WIN_BLACKMAN_hARRIS
states:
coordinate: [1390, 1110]
rotation: 0
state: enabled
- name: channel_sum
id: blocks_add_xx
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
num_inputs: '4'
type: complex
vlen: '1'
states:
coordinate: [820, 1170]
rotation: 0
state: enabled
- name: channel_throttle
id: blocks_throttle2
parameters:
affinity: ''
alias: ''
comment: ''
ignoretag: 'True'
limit: time
maximum: '0.02'
maxoutbuf: '0'
minoutbuf: '0'
samples_per_second: samp_rate
type: complex
vlen: '1'
states:
coordinate: [1060, 1190]
rotation: 0
state: enabled
- name: gui_layout
id: wasm_gui_layout
parameters:
affinity: ''
alias: ''
columns: '12'
comment: ''
layout: '{"analyzer":[0,0,12,8]}'
row_height: '60'
states:
coordinate: [310, 10]
rotation: 0
state: enabled
- name: ofdm_frequency_shift
id: blocks_rotator_cc
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
phase_inc: 2*math.pi*ofdm_offset/samp_rate
tag_inc_update: 'False'
states:
coordinate: [100, 1410]
rotation: 0
state: enabled
- name: ofdm_level
id: blocks_multiply_const_vxx
parameters:
affinity: ''
alias: ''
comment: ''
const: '0.2'
maxoutbuf: '0'
minoutbuf: '0'
mode: scalar
type: complex
vlen: '1'
states:
coordinate: [1090, 720]
rotation: 0
state: enabled
- name: ofdm_packet_tagger
id: blocks_stream_to_tagged_stream
parameters:
affinity: ''
alias: ''
comment: ''
len_tag_key: length
maxoutbuf: '0'
minoutbuf: '0'
packet_len: '96'
type: byte
vlen: '1'
states:
coordinate: [340, 720]
rotation: 0
state: enabled
- name: ofdm_payload
id: blocks_vector_source_x
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
repeat: 'True'
tags: '[]'
type: byte
vector: '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95]'
vlen: '1'
states:
coordinate: [10, 710]
rotation: 0
state: enabled
- name: ofdm_transmitter
id: digital_ofdm_tx
parameters:
affinity: ''
alias: ''
comment: ''
cp_len: '64'
fft_len: '256'
header_mod: '"BPSK"'
log: 'False'
maxoutbuf: '0'
minoutbuf: '0'
occupied_carriers: ()
packet_len_key: length
payload_mod: '"QPSK"'
pilot_carriers: ()
pilot_symbols: ()
rolloff: '0'
scramble_bits: 'True'
sync_word1: ()
sync_word2: ()
states:
coordinate: [720, 610]
rotation: 0
state: enabled
- name: overview
id: note
parameters:
affinity: ''
alias: ''
comment: ''
note: "A simulated 1 MHz channel centered at 915 MHz\n\nLeft: narrow carrier at -300 kHz\nCenter: pulse-shaped QPSK, 8 samples/symbol\nRight: QPSK OFDM at +300 kHz, 256-point FFT with 52 active carriers\n\nEach signal slowly eases toward an independent random power level every 3-7 seconds, making health changes and damage effects easy to see. Low-level receiver noise gives the automatic detector a realistic floor to learn."
states:
coordinate: [1290, 10]
rotation: 0
state: enabled
- name: qpsk_constellation
id: variable_constellation
parameters:
affinity: ''
alias: ''
comment: ''
const_points: '[-1-1j, -1+1j, 1+1j, 1-1j]'
dims: '1'
normalization: digital.constellation.AMPLITUDE_NORMALIZATION
npwr: '1'
precision: '8'
rot_sym: '4'
soft_dec_lut: None
sym_map: '[0, 1, 3, 2]'
type: qpsk
states:
coordinate: [10, 370]
rotation: 0
state: enabled
- name: qpsk_data
id: analog_random_uniform_source_x
parameters:
affinity: ''
alias: ''
comment: ''
maximum: '255'
maxoutbuf: '0'
minimum: '0'
minoutbuf: '0'
seed: '23'
type: byte
states:
coordinate: [720, 930]
rotation: 0
state: enabled
- name: qpsk_level
id: blocks_multiply_const_vxx
parameters:
affinity: ''
alias: ''
comment: ''
const: '0.22'
maxoutbuf: '0'
minoutbuf: '0'
mode: scalar
type: complex
vlen: '1'
states:
coordinate: [100, 1310]
rotation: 0
state: enabled
- name: qpsk_modulator
id: digital_constellation_modulator
parameters:
affinity: ''
alias: ''
comment: ''
constellation: qpsk_constellation
differential: 'False'
excess_bw: '0.35'
log: 'False'
maxoutbuf: '0'
minoutbuf: '0'
samples_per_symbol: '8'
truncate: 'False'
verbose: 'False'
states:
coordinate: [1090, 890]
rotation: 0
state: enabled
- name: random_power_fades
id: wasm_js_block
parameters:
_js_io: '{"decim":1,"doc":"Slow, independent random power changes for the three signals in the MMO spectrum demo.","general":false,"hasStart":true,"hasStop":false,"history":1,"inputs":[{"dtype":"complex","vlen":1},{"dtype":"complex","vlen":1},{"dtype":"complex","vlen":1}],"interp":1,"label":"Random Power Fades","numericParams":["sample_rate","min_gain","max_gain"],"outputMultiple":0,"outputs":[{"dtype":"complex","vlen":1},{"dtype":"complex","vlen":1},{"dtype":"complex","vlen":1}],"overridesForecast":false,"params":[["sample_rate",1000000],["min_gain",0.25],["max_gain",1.3]],"relativeRate":1}'
_js_source: ''
_source_code: "// Give each signal its own smooth, deterministic pseudo-random power envelope.\ngr.export({\n label: 'Random Power Fades',\n doc: 'Slow, independent random power changes for the three signals in the MMO spectrum demo.',\n inputs: ['complex', 'complex', 'complex'],\n outputs: ['complex', 'complex', 'complex'],\n params: { sample_rate: 1000000, min_gain: 0.25, max_gain: 1.3 },\n\n start() {\n this.rng = [0x13579bdf, 0x2468ace1, 0x10203040];\n this.gain = [1, 0.85, 1.15];\n this.step = [0, 0, 0];\n this.remaining = [0, 0, 0];\n },\n\n nextRandom(port) {\n this.rng[port] = (Math.imul(this.rng[port], 1664525) + 1013904223) >>> 0;\n return this.rng[port] / 4294967296;\n },\n\n chooseTarget(port) {\n const low = Math.min(this.min_gain, this.max_gain);\n const high = Math.max(this.min_gain, this.max_gain);\n const target = low + (high - low) * this.nextRandom(port);\n const seconds = 3 + 4 * this.nextRandom(port);\n const samples = Math.max(1, Math.round(seconds * Math.max(1, this.sample_rate)));\n this.step[port] = (target - this.gain[port]) / samples;\n this.remaining[port] = samples;\n },\n\n work(nout, input, output) {\n for (let port = 0; port < 3; port++) {\n const source = input[port];\n const destination = output[port];\n let gain = this.gain[port];\n let step = this.step[port];\n let remaining = this.remaining[port];\n\n for (let item = 0; item < nout; item++) {\n if (remaining <= 0) {\n this.gain[port] = gain;\n this.chooseTarget(port);\n step = this.step[port];\n remaining = this.remaining[port];\n }\n const offset = item * 2;\n destination[offset] = source[offset] * gain;\n destination[offset + 1] = source[offset + 1] * gain;\n gain += step;\n remaining--;\n }\n\n this.gain[port] = gain;\n this.step[port] = step;\n this.remaining[port] = remaining;\n }\n return nout;\n },\n});\n"
affinity: ''
alias: ''
comment: ''
max_gain: '1.3'
min_gain: '0.25'
sample_rate: samp_rate
states:
coordinate: [460, 1170]
rotation: 0
state: enabled
- name: receiver_noise
id: analog_noise_source_x
parameters:
affinity: ''
alias: ''
amp: '0.002'
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
noise_type: analog.GR_GAUSSIAN
seed: '7'
type: complex
states:
coordinate: [460, 1330]
rotation: 0
state: enabled
- name: tone
id: analog_sig_source_x
parameters:
affinity: ''
alias: ''
amp: '0.3'
comment: ''
freq: tone_offset
maxoutbuf: '0'
minoutbuf: '0'
offset: '0'
phase: '0'
samp_rate: samp_rate
type: complex
waveform: analog.GR_COS_WAVE
states:
coordinate: [100, 1130]
rotation: 0
state: enabled
connections:
- [channel_sum, '0', channel_throttle, '0']
- [channel_throttle, '0', analyzer, '0']
- [ofdm_frequency_shift, '0', random_power_fades, '2']
- [ofdm_level, '0', ofdm_frequency_shift, '0']
- [ofdm_packet_tagger, '0', ofdm_transmitter, '0']
- [ofdm_payload, '0', ofdm_packet_tagger, '0']
- [ofdm_transmitter, '0', ofdm_level, '0']
- [qpsk_data, '0', qpsk_modulator, '0']
- [qpsk_level, '0', random_power_fades, '1']
- [qpsk_modulator, '0', qpsk_level, '0']
- [random_power_fades, '0', channel_sum, '0']
- [random_power_fades, '1', channel_sum, '1']
- [random_power_fades, '2', channel_sum, '2']
- [receiver_noise, '0', channel_sum, '3']
- [tone, '0', random_power_fades, '0']
metadata:
file_format: 1
grc_version: 3.11.0.0