Skip to content

Commit

Permalink
WIP backport quad rate
Browse files Browse the repository at this point in the history
Signed-off-by: Jeff Long <[email protected]>
  • Loading branch information
willcode committed Mar 29, 2023
1 parent 3718e13 commit e59260b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 deletions.
27 changes: 26 additions & 1 deletion scripts/plot_zmq_fft.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,23 @@
import sys
import json
import numpy as np
from scipy import signal as sig
import matplotlib.pyplot as plt
import matplotlib.colors as colors

META_FILE = '/tmp/fft.meta'
DATA_FILE = '/tmp/fft.data'

NUM_BINS = 0 # all bins
# NUM_BINS = 2000
START_BIN = 635000

LENGTH = 0 # all
START_TIME = 0

WIDTH = 1500
HEIGHT = 1500


# Create gqrx colormap for matplotlib, based on code in plotter.cpp
# The viridis, plasma, and turbo maps are already available in NumPy.
Expand Down Expand Up @@ -62,12 +73,26 @@ def gqrx_colormap():

a = np.memmap(DATA_FILE, mode='r', dtype=np.float32)
a = a.reshape((-1, fftsize))
if NUM_BINS != 0:
print(f'Using bins {START_BIN} to {START_BIN+NUM_BINS-1}')
a = a[:, START_BIN:START_BIN+NUM_BINS]
if LENGTH != 0:
print(f'Using interval {START_TIME} to {START_TIME+LENGTH-1}')
a = a[START_TIME:LENGTH, :]
if WIDTH:
print(f'Resampling to width {WIDTH}')
a = sig.resample(a, WIDTH, axis=0)
if HEIGHT:
print(f'Resampling to height {HEIGHT}')
a = sig.resample(a, HEIGHT, axis=1)

avg_db = np.average(a)
std_db = np.std(a)
min_db = avg_db - std_db
max_db = avg_db + 5 * std_db

plot = plt.pcolormesh(a, vmin=min_db, vmax=max_db, cmap=cmap)
print("Drawing")
plot = plt.pcolormesh(a, vmin=min_db, vmax=max_db, cmap=cmap, antialiased=False)

plt.colorbar(plot)
plt.show()
26 changes: 17 additions & 9 deletions scripts/record_zmq_fft_decim.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@

import numpy as np

DECIM = 5
DECIM = 100
URI = 'ipc:///tmp/gqrx_data'
TOPIC = b'data.fft.log'
META_FILE = '/tmp/fft.meta'
DATA_FILE = '/tmp/fft.data'
STD_FILE = '/tmp/fft.std'


def rx_loop(socket, outf=None, metaf=None):
def rx_loop(socket, outf=None, metaf=None, stdf=None):
win = None
i = 0
fftsize = None
Expand All @@ -38,13 +39,21 @@ def rx_loop(socket, outf=None, metaf=None):
if i == (DECIM - 1):

# Use maximum values from window. This is what Gqrx does.
xmax = np.max(win, 0)
x = xmax.astype(np.float32).tobytes()
if outf or metaf:
xmax = np.max(win, 0)

# Copy out data.
if outf:
x = xmax.astype(np.float32).tobytes()
outf.write(x)

if stdf or metaf:
xstd = np.std(win, 0)

if stdf:
x = xstd.astype(np.float32).tobytes()
stdf.write(x)

# Add more fields that readers would otherwise need to get from
# the data file.
if metaf:
Expand All @@ -53,12 +62,12 @@ def rx_loop(socket, outf=None, metaf=None):
meta['maxmax'] = max(xmax)
xmin = np.min(win, 0)
meta['minmin'] = min(xmin)
xstd = np.std(win, 0)
meta['minstd'] = min(xstd)
meta['maxstd'] = max(xstd)

metaf.write(json.dumps(meta))
metaf.write('\n')
metaf.flush()

i = 0

Expand All @@ -73,11 +82,10 @@ def rx_loop(socket, outf=None, metaf=None):
# Subscribe to single topic.
socket.setsockopt(zmq.SUBSCRIBE, TOPIC)

dataf = open(DATA_FILE, 'wb')
with open(META_FILE, 'w') as metaf:
with open(DATA_FILE, 'wb') as dataf, open(META_FILE, 'w') as metaf, open(STD_FILE, 'wb') as stdf:
try:
rx_loop(socket, dataf, metaf)
rx_loop(socket, dataf, metaf, stdf)
except KeyboardInterrupt:
print()
except Exception as e:
print(str(e))
print(str(e))
20 changes: 11 additions & 9 deletions src/applications/gqrx/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,11 +1382,12 @@ void MainWindow::iqFftTimeout()
{
unsigned int fftsize;
unsigned int i;
float pwr_scale;
double pwr_scale;
double quad_rate = rx->get_input_rate() / rx->get_input_decim();
double now = QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() / 1000.0;

// FIXME: fftsize is a reference
rx->get_iq_fft_data(d_fftData, fftsize);
rx->get_iq_sample_data(d_sampleData, fftsize);

if (fftsize == 0)
{
Expand All @@ -1399,9 +1400,9 @@ void MainWindow::iqFftTimeout()
{
json j;
j["frequency"] = rx->get_rf_freq();
j["rate"] = llround(rx->get_input_rate() / rx->get_input_decim());
j["rate"] = llround(quad_rate);
j["fftsize"] = fftsize;
j["timestamp"] = (double)QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() / 1000.0;
j["timestamp"] = now;
QString channel("data.sample.complex");
QString metadata(j.dump().c_str());
outputData(channel, metadata, d_sampleData, fftsize * sizeof(gr_complex));
Expand All @@ -1421,9 +1422,9 @@ void MainWindow::iqFftTimeout()
{
json j;
j["frequency"] = rx->get_rf_freq();
j["rate"] = llround(rx->get_input_rate() / rx->get_input_decim());
j["rate"] = llround(quad_rate);
j["fftsize"] = fftsize;
j["timestamp"] = (double)QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() / 1000.0;
j["timestamp"] = now;
QString channel("data.fft.linear");
QString metadata(j.dump().c_str());
outputData(channel, metadata, d_realFftData, fftsize * sizeof(float));
Expand All @@ -1437,9 +1438,9 @@ void MainWindow::iqFftTimeout()
{
json j;
j["frequency"] = rx->get_rf_freq();
j["rate"] = llround(rx->get_input_rate() / rx->get_input_decim());
j["rate"] = llround(quad_rate);
j["fftsize"] = fftsize;
j["timestamp"] = (double)QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() / 1000.0;
j["timestamp"] = now;
QString channel("data.fft.log");
QString metadata(j.dump().c_str());
outputData(channel, metadata, d_realFftData, fftsize * sizeof(float));
Expand Down Expand Up @@ -1823,7 +1824,8 @@ void MainWindow::dataSettingsChanged(void)
{
d_output_enabled = false;
// Close ZMQ
d_zmq_socket.close();
if (d_zmq_socket)
d_zmq_socket.close();
data_controls->setStatus("STOPPED");
}
}
Expand Down

0 comments on commit e59260b

Please sign in to comment.