|
22 | 22 |
|
23 | 23 | #include <wdsp.h>
|
24 | 24 |
|
| 25 | +#include "bpsk.h" |
25 | 26 | #include "discovered.h"
|
26 | 27 | #include "receiver.h"
|
27 | 28 | #include "bpsk.h"
|
|
39 | 40 | static int my_pixels=-1;
|
40 | 41 | static float *my_pixel_samples=NULL;
|
41 | 42 |
|
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; |
46 | 61 |
|
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); |
50 | 68 |
|
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 | + ); |
54 | 90 | }
|
55 | 91 |
|
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; |
68 | 100 | }
|
69 |
| - } else { |
70 |
| - for(int i=0;i<my_pixels;i++) { |
71 |
| - my_pixel_samples[i]+=rx->pixel_samples[i]; |
72 |
| - } |
73 |
| - } |
74 | 101 | }
|
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; |
79 | 135 | }
|
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; |
91 | 142 | }
|
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); |
106 | 161 | }
|
107 |
| - rx->bpsk_counter=0; |
| 162 | + bpsk->offset=0.0; |
| 163 | + bpsk->count=0; |
108 | 164 | }
|
109 | 165 | }
|
| 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; |
110 | 212 | }
|
| 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 | + |
0 commit comments