Skip to content

Commit 60a51bf

Browse files
committed
Added subrx.
Rewrite of vfo.c amd radio_info.c using gtk widgets and css.
1 parent 683c4e7 commit 60a51bf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+6323
-6171
lines changed

Makefile

+10-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ AUDIO_LIBS=-lasound -lpulse-simple -lpulse -lpulse-mainloop-glib -lsoundio
2626
# sudo apt-get install soapysdr-module-rtlsdr
2727
# sudo apt-get install soapysdr-module-lms7
2828
#
29-
#SOAPYSDR_INCLUDE=SOAPYSDR
29+
SOAPYSDR_INCLUDE=SOAPYSDR
3030

3131
ifeq ($(SOAPYSDR_INCLUDE),SOAPYSDR)
3232
SOAPYSDR_OPTIONS=-D SOAPYSDR
@@ -89,6 +89,7 @@ PROGRAM=linhpsdr
8989

9090
SOURCES=\
9191
main.c\
92+
css.c\
9293
audio.c\
9394
version.c\
9495
discovered.c\
@@ -131,13 +132,14 @@ puresignal_dialog.c\
131132
oc_dialog.c\
132133
xvtr_dialog.c\
133134
frequency.c\
134-
rigctl.c\
135135
error_handler.c\
136136
radio_info.c\
137-
bpsk.c
137+
bpsk.c \
138+
subrx.c
138139

139140
HEADERS=\
140141
main.h\
142+
css.h\
141143
audio.h\
142144
version.h\
143145
discovered.h\
@@ -181,13 +183,14 @@ puresignal_dialog.h\
181183
oc_dialog.h\
182184
xvtr_dialog.h\
183185
frequency.h\
184-
rigctl.h\
185186
error_handler.h\
186187
radio_info.h\
187-
bpsk.h
188+
bpsk.h \
189+
subrx.h
188190

189191
OBJS=\
190192
main.o\
193+
css.o\
191194
audio.o\
192195
version.o\
193196
discovered.o\
@@ -230,10 +233,10 @@ puresignal_dialog.o\
230233
oc_dialog.o\
231234
xvtr_dialog.o\
232235
frequency.o\
233-
rigctl.o\
234236
error_handler.o\
235237
radio_info.o\
236-
bpsk.o
238+
bpsk.o \
239+
subrx.o
237240

238241

239242
$(PROGRAM): $(OBJS) $(SOAPYSDR_OBJS) $(CWDAEMON_OBJS) $(MIDI_OBJS)

about_dialog.c

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#endif
3333

3434
#include "discovered.h"
35+
#include "bpsk.h"
3536
#include "receiver.h"
3637
#include "transmitter.h"
3738
#include "receiver.h"

audio.c

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "dac.h"
4747
#include "discovered.h"
4848
#include "wideband.h"
49+
#include "bpsk.h"
4950
#include "receiver.h"
5051
#include "transmitter.h"
5152
#include "radio.h"

bookmark_dialog.c

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <SoapySDR/Device.h>
2929
#endif
3030

31+
#include "bpsk.h"
3132
#include "receiver.h"
3233
#include "transmitter.h"
3334
#include "wideband.h"

bpsk.c

+172-57
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <wdsp.h>
2424

25+
#include "bpsk.h"
2526
#include "discovered.h"
2627
#include "receiver.h"
2728
#include "bpsk.h"
@@ -39,72 +40,186 @@
3940
static int my_pixels=-1;
4041
static float *my_pixel_samples=NULL;
4142

42-
void create_bpsk(RECEIVER *rx) {
43-
rx->bpsk_counter=0;
44-
rx->bpsk=TRUE;
45-
}
43+
void bpsk_init_analyzer(BPSK *bpsk) {
44+
int flp[] = {0};
45+
double keep_time = 0.1;
46+
int n_pixout=1;
47+
int spur_elimination_ffts = 1;
48+
int data_type = 1;
49+
int fft_size = 8192;
50+
int window_type = 4;
51+
double kaiser_pi = 14.0;
52+
int overlap = 2048;
53+
int clip = 0;
54+
int span_clip_l = 0;
55+
int span_clip_h = 0;
56+
int pixels=bpsk->pixels;
57+
int stitches = 1;
58+
int calibration_data_set = 0;
59+
double span_min_freq = 0.0;
60+
double span_max_freq = 0.0;
4661

47-
void destroy_bpsk(RECEIVER *rx) {
48-
rx->bpsk=FALSE;
49-
}
62+
g_print("bpsk_init_analyzer: channel=%d pixels=%d pixel_samples=%p\n",bpsk->channel,bpsk->pixels,bpsk->pixel_samples);
63+
64+
int max_w = fft_size + (int) fmin(keep_time * (double) bpsk->fps, keep_time * (double) fft_size * (double) bpsk->fps);
65+
66+
67+
g_print("SetAnalyzer id=%d buffer_size=%d fft_size=%d overlap=%d\n",bpsk->channel,bpsk->buffer_size,fft_size,overlap);
5068

51-
void reset_bpsk(RECEIVER *rx) {
52-
fprintf(stderr,"reset_bpsk\n");
53-
rx->bpsk_counter=0;
69+
70+
SetAnalyzer(bpsk->channel,
71+
n_pixout,
72+
spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination
73+
data_type, //0 for real input data (I only); 1 for complex input data (I & Q)
74+
flp, //vector with one elt for each LO frequency, 1 if high-side LO, 0 otherwise
75+
fft_size, //size of the fft, i.e., number of input samples
76+
bpsk->buffer_size, //number of samples transferred for each OpenBuffer()/CloseBuffer()
77+
window_type, //integer specifying which window function to use
78+
kaiser_pi, //PiAlpha parameter for Kaiser window
79+
overlap, //number of samples each fft (other than the first) is to re-use from the previous
80+
clip, //number of fft output bins to be clipped from EACH side of each sub-span
81+
span_clip_l, //number of bins to clip from low end of entire span
82+
span_clip_h, //number of bins to clip from high end of entire span
83+
pixels, //number of pixel values to return. may be either <= or > number of bins
84+
stitches, //number of sub-spans to concatenate to form a complete span
85+
calibration_data_set, //identifier of which set of calibration data to use
86+
span_min_freq, //frequency at first pixel value8192
87+
span_max_freq, //frequency at last pixel value
88+
max_w //max samples to hold in input ring buffers
89+
);
5490
}
5591

56-
void process_bpsk(RECEIVER *rx) {
57-
if(rx->pixel_samples!=NULL) {
58-
if(my_pixels!=rx->pixels) {
59-
if(my_pixel_samples!=NULL) {
60-
g_free(my_pixel_samples);
61-
}
62-
my_pixels=rx->pixels;
63-
my_pixel_samples=g_new(float,my_pixels);
64-
} else {
65-
if(rx->bpsk_counter==0) {
66-
for(int i=0;i<my_pixels;i++) {
67-
my_pixel_samples[i]=rx->pixel_samples[i];
92+
int maximum(float data[], int len) {
93+
float m = -200.0;
94+
int mi=-1;
95+
int i;
96+
for(i=0; i<len; ++i) {
97+
if(data[i]>m) {
98+
m=data[i];
99+
mi=i;
68100
}
69-
} else {
70-
for(int i=0;i<my_pixels;i++) {
71-
my_pixel_samples[i]+=rx->pixel_samples[i];
72-
}
73-
}
74101
}
75-
rx->bpsk_counter++;
76-
if(rx->bpsk_counter==rx->fps) {
77-
for(int i=0;i<my_pixels;i++) {
78-
my_pixel_samples[i]=my_pixel_samples[i]/(float)rx->fps;
102+
return mi;
103+
}
104+
105+
static gboolean bpsk_local_timer_cb(void *data) {
106+
// look +/-1KHz
107+
// assume sample rate is 768000
108+
// assume 15360 samples
109+
// assume 50Hz per sample
110+
111+
#define SIGNALS 200
112+
113+
BPSK *bpsk=(BPSK *)data;
114+
int mid=bpsk->pixels/2;
115+
int signal[SIGNALS];
116+
int lag=10;
117+
float threshold = -70.0;
118+
float influence = 1;
119+
int rc;
120+
121+
g_mutex_lock(&bpsk->mutex);
122+
GetPixels(bpsk->channel,0,bpsk->pixel_samples,&rc);
123+
g_mutex_unlock(&bpsk->mutex);
124+
125+
if(rc) {
126+
int max1=maximum(&bpsk->pixel_samples[mid-(SIGNALS/2)],SIGNALS);
127+
128+
int max2=-1;;
129+
float max2_value=-200.0;
130+
131+
for(int i=max1-16;i<max1-4;i++) {
132+
if(bpsk->pixel_samples[mid-(SIGNALS/2)+i]>max2_value) {
133+
max2_value=bpsk->pixel_samples[mid-(SIGNALS/2)+i];
134+
max2=i;
79135
}
80-
float threshold=5.0;
81-
int gap=(int)(800.0/rx->hz_per_pixel);
82-
//float last=-140;
83-
int last_index=-1;
84-
for(int i=my_pixels-3;i>gap;i--) {
85-
if((my_pixel_samples[i]>=(my_pixel_samples[i-1]+threshold)) &&
86-
(my_pixel_samples[i-gap]>=(my_pixel_samples[i-1]+threshold))) {
87-
last_index=i;
88-
//last=my_pixel_samples[last_index];
89-
break;
90-
}
136+
}
137+
138+
for(int i=max1+5;i<max1+17;i++) {
139+
if(bpsk->pixel_samples[mid-(SIGNALS/2)+i]>max2_value) {
140+
max2_value=bpsk->pixel_samples[mid-(SIGNALS/2)+i];
141+
max2=i;
91142
}
92-
if(last_index!=-1) {
93-
//last_index=last_index-(gap/2);
94-
double frequency=(double)rx->frequency_a;
95-
double half=(double)rx->sample_rate/2.0;
96-
double min_frequency=frequency-half;
97-
double max_frequency=frequency+half;
98-
if(10489800000>min_frequency&&10489800000<max_frequency) {
99-
double f=min_frequency+((double)last_index*rx->hz_per_pixel);
100-
long long offset=(long long)(f-10489800000.0);
101-
if(llabs(offset)>=100 && llabs(offset)<100000) {
102-
g_print("lo_error_update: offset=%lld f=%f half=%f min_frequency=%f max_frequency=%f last_index=%d val=%f hz_per_pixel=%f zoom=%d pixels=%d threshold=%f gap=%d\n",offset,f,half,min_frequency,max_frequency,last_index,rx->pixel_samples[last_index],rx->hz_per_pixel,rx->zoom,rx->pixels,threshold,gap);
103-
lo_error_update(rx,offset);
104-
}
105-
}
143+
}
144+
145+
int offset;
146+
if(max1>max2) {
147+
offset=max2+((max1-max2)/2);
148+
} else {
149+
offset=max1+((max2-max1)/2);
150+
}
151+
offset=offset-(SIGNALS/2);
152+
offset=offset*50;
153+
154+
bpsk->offset+=(double)offset;
155+
bpsk->count++;
156+
if(bpsk->count==300) {
157+
offset=(int)(bpsk->offset/300.0);
158+
//g_print("offset=%d\n",offset);
159+
if(abs(offset)>10) {
160+
lo_error_update(bpsk->band,(long long)offset);
106161
}
107-
rx->bpsk_counter=0;
162+
bpsk->offset=0.0;
163+
bpsk->count=0;
108164
}
109165
}
166+
return TRUE;
167+
}
168+
169+
void bpsk_add_iq_samples(BPSK *bpsk,double i_sample,double q_sample) {
170+
bpsk->input_buffer[bpsk->samples*2]=i_sample;
171+
bpsk->input_buffer[(bpsk->samples*2)+1]=q_sample;
172+
bpsk->samples++;
173+
174+
if(bpsk->samples>=bpsk->buffer_size) {
175+
g_mutex_lock(&bpsk->mutex);
176+
Spectrum0(1, bpsk->channel, 0, 0, bpsk->input_buffer);
177+
g_mutex_unlock(&bpsk->mutex);
178+
bpsk->samples=0;
179+
}
180+
}
181+
182+
BPSK *create_bpsk(int channel,int band) {
183+
BPSK *bpsk=g_new0(BPSK,1);
184+
185+
g_print("create_bpsk: channel=%d\n",channel);
186+
bpsk->channel=channel;
187+
bpsk->band=band;
188+
bpsk->pixels=15360; // 50Hz per pixel at 768000 sample rate
189+
bpsk->buffer_size=2048;
190+
bpsk->input_buffer=g_new0(gdouble,bpsk->buffer_size*2);
191+
bpsk->fft_size=bpsk->buffer_size;
192+
bpsk->pixel_samples=g_new0(float,bpsk->pixels);
193+
bpsk->fps=10;
194+
bpsk->samples=0;
195+
bpsk->count=0;
196+
bpsk->offset=0.0;
197+
g_mutex_init(&bpsk->mutex);
198+
199+
int result;
200+
XCreateAnalyzer(bpsk->channel, &result, 262144, 1, 1, "");
201+
if(result != 0) {
202+
g_print("XCreateAnalyzer channel=%d failed: %d\n", bpsk->channel, result);
203+
} else {
204+
bpsk_init_analyzer(bpsk);
205+
}
206+
207+
SetDisplayDetectorMode(bpsk->channel, 0, DETECTOR_MODE_AVERAGE);
208+
SetDisplayAverageMode(bpsk->channel, 0, AVERAGE_MODE_LOG_RECURSIVE);
209+
210+
bpsk->update_timer_id=g_timeout_add(100,bpsk_local_timer_cb,(gpointer)bpsk);
211+
return bpsk;
110212
}
213+
214+
void destroy_bpsk(BPSK *bpsk) {
215+
g_print("destroy_bpsk\n");
216+
g_source_remove(bpsk->update_timer_id);
217+
g_free(bpsk->input_buffer);
218+
g_free(bpsk->pixel_samples);
219+
g_free(bpsk);
220+
}
221+
222+
void reset_bpsk(BPSK *bpsk) {
223+
g_print("reset_bpsk\n");
224+
}
225+

bpsk.h

+24-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,27 @@
1717
*
1818
*/
1919

20-
void create_bpsk(RECEIVER *rx);
21-
void destroy_bpsk(RECEIVER *rx);
22-
void reset_bpsk(RECEIVER *rx);
23-
void process_bpsk(RECEIVER *rx);
20+
#ifndef BPSK_H
21+
#define BPSK_H
22+
23+
typedef struct _bpsk {
24+
gint channel;
25+
gint band;
26+
gint buffer_size;
27+
gint fft_size;
28+
gint samples;
29+
gint pixels;
30+
gint fps;
31+
gdouble *input_buffer;
32+
gfloat *pixel_samples;
33+
GMutex mutex;
34+
gint update_timer_id;
35+
int count;
36+
double offset;
37+
} BPSK;
38+
39+
extern BPSK *create_bpsk(int channel,int band);
40+
extern void destroy_bpsk(BPSK *bpsk);
41+
extern void bpsk_add_iq_samples(BPSK *bpsk,double i_sample,double q_sample);
42+
43+
#endif

configure_dialog.c

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <SoapySDR/Device.h>
3131
#endif
3232

33+
#include "bpsk.h"
3334
#include "receiver.h"
3435
#include "transmitter.h"
3536
#include "wideband.h"

0 commit comments

Comments
 (0)