1 // Copyright (c) <2012> <Leif Asbrink>
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without restriction,
6 // including without limitation the rights to use, copy, modify,
7 // merge, publish, distribute, sublicense, and/or sell copies of
8 // the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22
23
24 #include "globdef.h"
25 #include "uidef.h"
26 #include "seldef.h"
27 #include "fft1def.h"
28 #include "fft2def.h"
29 #include "fft3def.h"
30 #include "screendef.h"
31 #include "sigdef.h"
32
33 #define BWFAC 0.03 // 3% of the bandwidth for AFC 2nd/3rd order modulation.
34
35 // The mix1 routines shift selected frequency bands to the baseband.
36 // Since we have overlapping fourier transforms already there is no
37 // need to multiply with the cos/sin table - we just select some
38 // lines in the fft and make a back transformation.
39 // We do that with a reduced transform size and get the reduced
40 // sampling rate that we want at the reduced bandwidth automatically.
41
42 float phrot_step_save=0;
43
do_mix1(int ss,float dfq)44 void do_mix1(int ss, float dfq)
45 {
46 int i, j, n, pa, k, mm, ia, ib, ic, id;
47 int p0, poffs;
48 float t1,t2,t3,t4,r1,r2,r3,r4,w1,w2,a1,a2;
49 float old_phrot_step,phrot_step;
50 dfq=0;
51 phrot_step=dfq*fftx_points_per_hz*2*PI_L/mix1.size;
52 old_phrot_step=phrot_step_save;
53 phrot_step_save=phrot_step;
54 mm=twice_rxchan;
55 k=mm*mix1.interleave_points/2;
56 poffs=ss*timf3_size;
57 pa=timf3_pa+poffs;
58 // There is a lot of memory in our computers but speed may be a problem
59 // Process in different loops depending on no of rx channels.
60 i=0;
61 j=mix1.size-1;
62 n=mix1.size/2-1;
63 if(sw_onechan)
64 {
65 t1=mix1_fqwin[n];
66 fftn_tmp[2*i ]*=t1;
67 fftn_tmp[2*i+1]*=t1;
68 i++;
69 while(j>i)
70 {
71 t1=mix1_fqwin[n];
72 fftn_tmp[2*i ]*=t1;
73 fftn_tmp[2*i+1]*=t1;
74 fftn_tmp[2*j ]*=t1;
75 fftn_tmp[2*j+1]*=t1;
76 j--;
77 n--;
78 i++;
79 }
80 t1=mix1_fqwin[n];
81 fftn_tmp[2*i ]*=t1;
82 fftn_tmp[2*i+1]*=t1;
83 fftback(mix1.size, mix1.n, fftn_tmp,
84 mix1.table, mix1.permute, yieldflag_ndsp_mix1);
85 // In case there is no window the whole thing is trival.
86 // Just place the back transforms after each other.
87
88 if(mix1.interleave_points == 0)
89 {
90 t2=mix1_phase_rot[ss];
91 t1=mix1_phase[ss];
92 j=2*mix1.size;
93 for(i=0; i<j; i+=2)
94 {
95 t3=sin(t1);
96 t4=cos(t1);
97 timf3_float[pa+i ]=t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1];
98 timf3_float[pa+i+1]=t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ];
99 t1+=t2;
100 }
101 mix1_phase[ss]=t1;
102 }
103 else
104 {
105 // If a sin squared window is used, place the transforms with 50%
106 // overlap and add them together. sin squared + cos squared ==1
107 pa=timf3_pa+poffs;
108 if(mix1.interleave_points == mix1.new_points)
109 {
110 ia=mix1.size;
111 t2=mix1_phase_rot[ss];
112 t1=mix1_phase[ss];
113 r1=mix1_old_phase[ss];
114 r2=t2-2*(mix1_old_point[ss]-mix1_point[ss])*PI_L/mix1.size;
115 r2-=old_phrot_step/4;
116 t2-=phrot_step/4;
117 old_phrot_step/=mix1.size;
118 phrot_step/=mix1.size;
119 for(i=0; i<ia; i+=2)
120 {
121 t3=sin(t1);
122 t4=cos(t1);
123 r3=sin(r1);
124 r4=cos(r1);
125 a1=timf3_float[pa+i ];
126 a2=timf3_float[pa+i+1];
127 timf3_float[pa+i ]=r4*a1-r3*a2+t4*fftn_tmp[i ]-t3*fftn_tmp[i+1];
128 timf3_float[pa+i+1]=r4*a2+r3*a1+t4*fftn_tmp[i+1]+t3*fftn_tmp[i ];
129 r1+=r2;
130 t1+=t2;
131 r2-=old_phrot_step;
132 t2+=phrot_step;
133 }
134 mix1_phase[ss]=t1;
135 pa=((timf3_pa+timf3_block)&timf3_mask)+2*ss*timf3_size-timf3_block;
136 ib=2*mix1.size;
137 for(i=ia; i<ib; i+=2)
138 {
139 timf3_float[pa+i ]=fftn_tmp[i ];
140 timf3_float[pa+i+1]=fftn_tmp[i+1];
141 }
142 }
143 else
144 {
145 p0=timf3_pa;
146 t2=mix1_phase_rot[ss];
147 t1=mix1_phase[ss];
148 r1=mix1_old_phase[ss];
149 r2=t2-2*(mix1_old_point[ss]-mix1_point[ss])*PI_L/mix1.size;
150 r2+=old_phrot_step/4;
151 t2+=phrot_step/4;
152 old_phrot_step/=mix1.size;
153 phrot_step/=mix1.size;
154 k-=2*(mix1.crossover_points/2);
155 j=k/2+mix1.crossover_points;
156 ia=2*mix1.crossover_points;
157 for(i=0; i<ia; i+=2)
158 {
159 pa=p0+poffs;
160 t3=sin(t1);
161 t4=cos(t1);
162 r3=sin(r1);
163 r4=cos(r1);
164 w1=mix1.sin2win[i>>1];
165 w2=mix1.cos2win[i>>1];
166 a1=w2*timf3_float[pa ];
167 a2=w2*timf3_float[pa+1];
168 timf3_float[pa ]=r4*a1-r3*a2+
169 (t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1])*w1;
170 timf3_float[pa+1]=r4*a2+r3*a1+
171 (t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ])*w1;
172 t1+=t2;
173 r1+=r2;
174 r2+=old_phrot_step;
175 t2+=phrot_step;
176 p0=(p0+2)&timf3_mask;
177 }
178 ib=mix1.new_points+2+2*(mix1.crossover_points/2);
179 for(i=ia; i<ib; i+=2)
180 {
181 t3=sin(t1);
182 t4=cos(t1);
183 pa=p0+poffs;
184 r1=mix1.window[j];
185 timf3_float[pa ]=(t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1])*r1;
186 timf3_float[pa+1]=(t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ])*r1;
187 p0=(p0+2)&timf3_mask;
188 t1+=t2;
189 t2+=phrot_step;
190 j++;
191 }
192 j--;
193 ic=2*mix1.new_points;
194 for(i=ib; i<ic; i+=2)
195 {
196 j--;
197 pa=p0+poffs;
198 t3=sin(t1);
199 t4=cos(t1);
200 r1=mix1.window[j];
201 timf3_float[pa ]=(t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1])*r1;
202 timf3_float[pa+1]=(t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ])*r1;
203 t1+=t2;
204 t2+=phrot_step;
205 p0=(p0+2)&timf3_mask;
206 }
207 mix1_phase[ss]=t1;
208 id=2*(mix1.crossover_points+mix1.new_points);
209 for(i=ic; i<id; i+=2)
210 {
211 j--;
212 pa=p0+poffs;
213 timf3_float[pa ]=fftn_tmp[i+k ];
214 timf3_float[pa+1]=fftn_tmp[i+k+1];
215 p0=(p0+2)&timf3_mask;
216 }
217 }
218 }
219 }
220 else
221 {
222 t1=mix1_fqwin[n];
223 fftn_tmp[4*i ]*=t1;
224 fftn_tmp[4*i+1]*=t1;
225 fftn_tmp[4*i+2]*=t1;
226 fftn_tmp[4*i+3]*=t1;
227 fftn_tmp[4*j ]*=t1;
228 fftn_tmp[4*j+1]*=t1;
229 fftn_tmp[4*j+2]*=t1;
230 fftn_tmp[4*j+3]*=t1;
231 i++;
232 while(j>i)
233 {
234 t1=mix1_fqwin[n];
235 fftn_tmp[4*i ]*=t1;
236 fftn_tmp[4*i+1]*=t1;
237 fftn_tmp[4*i+2]*=t1;
238 fftn_tmp[4*i+3]*=t1;
239 fftn_tmp[4*j ]*=t1;
240 fftn_tmp[4*j+1]*=t1;
241 fftn_tmp[4*j+2]*=t1;
242 fftn_tmp[4*j+3]*=t1;
243 j--;
244 n--;
245 i++;
246 }
247 t1=mix1_fqwin[n];
248 fftn_tmp[4*i ]*=t1;
249 fftn_tmp[4*i+1]*=t1;
250 fftn_tmp[4*i+2]*=t1;
251 fftn_tmp[4*i+3]*=t1;
252 fftn_tmp[4*j ]*=t1;
253 fftn_tmp[4*j+1]*=t1;
254 fftn_tmp[4*j+2]*=t1;
255 fftn_tmp[4*j+3]*=t1;
256 dual_fftback(mix1.size, mix1.n, fftn_tmp,
257 mix1.table, mix1.permute, yieldflag_ndsp_mix1);
258 if(mix1.interleave_points == 0)
259 {
260 t2=mix1_phase_rot[ss];
261 t1=mix1_phase[ss];
262 j=4*mix1.size;
263 for(i=0; i<j; i+=4)
264 {
265 t3=sin(t1);
266 t4=cos(t1);
267 timf3_float[pa+i ]=t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1];
268 timf3_float[pa+i+1]=t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ];
269 timf3_float[pa+i+2]=t4*fftn_tmp[i+k+2]-t3*fftn_tmp[i+k+3];
270 timf3_float[pa+i+3]=t4*fftn_tmp[i+k+3]+t3*fftn_tmp[i+k+2];
271 t1+=t2;
272 }
273 mix1_phase[ss]=t1;
274 }
275 else
276 {
277 pa=timf3_pa+poffs;
278 if(mix1.interleave_points == mix1.new_points)
279 {
280 ia=2*mix1.size;
281 t2=mix1_phase_rot[ss];
282 t1=mix1_phase[ss];
283 r1=mix1_old_phase[ss];
284 r2=t2-2*(mix1_old_point[ss]-mix1_point[ss])*PI_L/mix1.size;
285 r2-=old_phrot_step/4;
286 t2-=phrot_step/4;
287 old_phrot_step/=mix1.size;
288 phrot_step/=mix1.size;
289 for(i=0; i<ia; i+=4)
290 {
291 t3=sin(t1);
292 t4=cos(t1);
293 r3=sin(r1);
294 r4=cos(r1);
295 a1=timf3_float[pa+i ];
296 a2=timf3_float[pa+i+1];
297 timf3_float[pa+i ]=r4*a1-r3*a2+t4*fftn_tmp[i ]-t3*fftn_tmp[i+1];
298 timf3_float[pa+i+1]=r4*a2+r3*a1+t4*fftn_tmp[i+1]+t3*fftn_tmp[i ];
299 a1=timf3_float[pa+i+2];
300 a2=timf3_float[pa+i+3];
301 timf3_float[pa+i+2]=r4*a1-r3*a2+t4*fftn_tmp[i+2]-t3*fftn_tmp[i+3];
302 timf3_float[pa+i+3]=r4*a2+r3*a1+t4*fftn_tmp[i+3]+t3*fftn_tmp[i+2];
303 r1+=r2;
304 t1+=t2;
305 r2-=old_phrot_step;
306 t2+=phrot_step;
307 }
308 mix1_phase[ss]=t1;
309 pa=((timf3_pa+timf3_block)&timf3_mask)+4*ss*timf3_size-timf3_block;
310 ib=4*mix1.size;
311 for(i=ia; i<ib; i+=4)
312 {
313 timf3_float[pa+i ]=fftn_tmp[i ];
314 timf3_float[pa+i+1]=fftn_tmp[i+1];
315 timf3_float[pa+i+2]=fftn_tmp[i+2];
316 timf3_float[pa+i+3]=fftn_tmp[i+3];
317 }
318 }
319 else
320 {
321 p0=timf3_pa;
322 t2=mix1_phase_rot[ss];
323 t1=mix1_phase[ss];
324 r1=mix1_old_phase[ss];
325 r2=t2-2*(mix1_old_point[ss]-mix1_point[ss])*PI_L/mix1.size;
326 r2+=old_phrot_step/4;
327 t2+=phrot_step/4;
328 old_phrot_step/=mix1.size;
329 phrot_step/=mix1.size;
330 k-=4*(mix1.crossover_points/2);
331 j=k/4+mix1.crossover_points;
332 ia=4*mix1.crossover_points;
333 for(i=0; i<ia; i+=4)
334 {
335 pa=p0+poffs;
336 t3=sin(t1);
337 t4=cos(t1);
338 r3=sin(r1);
339 r4=cos(r1);
340 w1=mix1.sin2win[i>>2];
341 w2=mix1.cos2win[i>>2];
342 a1=w2*timf3_float[pa ];
343 a2=w2*timf3_float[pa+1];
344 timf3_float[pa ]=r4*a1-r3*a2+
345 (t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1])*w1;
346 timf3_float[pa+1]=r4*a2+r3*a1+
347 (t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ])*w1;
348 a1=w2*timf3_float[pa+2];
349 a2=w2*timf3_float[pa+3];
350 timf3_float[pa+2]=r4*a1-r3*a2+
351 (t4*fftn_tmp[i+k+2]-t3*fftn_tmp[i+k+3])*w1;
352 timf3_float[pa+3]=r4*a2+r3*a1+
353 (t4*fftn_tmp[i+k+3]+t3*fftn_tmp[i+k+2])*w1;
354 t1+=t2;
355 r1+=r2;
356 r2+=old_phrot_step;
357 t2+=phrot_step;
358
359 p0=(p0+4)&timf3_mask;
360 }
361 ib=2*mix1.new_points+4+4*(mix1.crossover_points/2);;
362 for(i=ia; i<ib; i+=4)
363 {
364 t3=sin(t1);
365 t4=cos(t1);
366 pa=p0+poffs;
367 r1=mix1.window[j];
368 timf3_float[pa ]=(t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1])*r1;
369 timf3_float[pa+1]=(t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ])*r1;
370 timf3_float[pa+2]=(t4*fftn_tmp[i+k+2]-t3*fftn_tmp[i+k+3])*r1;
371 timf3_float[pa+3]=(t4*fftn_tmp[i+k+3]+t3*fftn_tmp[i+k+2])*r1;
372 p0=(p0+4)&timf3_mask;
373 t1+=t2;
374 t2+=phrot_step;
375 j++;
376 }
377 j--;
378 ic=4*mix1.new_points;
379 for(i=ib; i<ic; i+=4)
380 {
381 j--;
382 pa=p0+poffs;
383 t3=sin(t1);
384 t4=cos(t1);
385 r1=mix1.window[j];
386 timf3_float[pa ]=(t4*fftn_tmp[i+k ]-t3*fftn_tmp[i+k+1])*r1;
387 timf3_float[pa+1]=(t4*fftn_tmp[i+k+1]+t3*fftn_tmp[i+k ])*r1;
388 timf3_float[pa+2]=(t4*fftn_tmp[i+k+2]-t3*fftn_tmp[i+k+3])*r1;
389 timf3_float[pa+3]=(t4*fftn_tmp[i+k+3]+t3*fftn_tmp[i+k+2])*r1;
390 t1+=t2;
391 t2+=phrot_step;
392 p0=(p0+4)&timf3_mask;
393 }
394 mix1_phase[ss]=t1;
395 id=4*(mix1.crossover_points+mix1.new_points);
396 for(i=ic; i<id; i+=4)
397 {
398 pa=p0+poffs;
399 timf3_float[pa ]=fftn_tmp[i+k ];
400 timf3_float[pa+1]=fftn_tmp[i+k+1];
401 timf3_float[pa+2]=fftn_tmp[i+k+2];
402 timf3_float[pa+3]=fftn_tmp[i+k+3];
403 p0=(p0+4)&timf3_mask;
404 }
405 }
406 }
407 }
408 }
409
do_mix1_afc(int ss)410 void do_mix1_afc(int ss)
411 {
412 int k, ia, ib;
413 int na, nx, ka, kb;
414 float error;
415 float curv;
416 int kk;
417 float t1,t2,t3;
418 float *fq, *dfq, *d2fq, *fqs;
419 // The back transforms form a time function that is mixed to
420 // zero frequency by an oscillator that is stepped in frequency
421 // with a frequency value mix1_fq_mid[i] for each transform.
422 // We may be mixing from a long transform so we do not want to
423 // wait for the next one in order to step the frequency.
424 // The routine that supplied mix1_fq_mid is responsible for
425 // supplying a value for the next transform too.
426 // Based on the old frequencies we already have used we want
427 // the center frequency at the center of the next transform
428 // to be be the current frequency plus the first and second derivatives.
429 if(genparm[SECOND_FFT_ENABLE] == 0)
430 {
431 fq=&mix1_fq_mid[ss*max_fft1n];
432 dfq=&mix1_fq_slope[ss*max_fft1n];
433 d2fq=&mix1_fq_curv[ss*max_fft1n];
434 fqs=&mix1_fq_start[ss*max_fft1n];
435 ka=(fft1_nx+fft1n_mask)&fft1n_mask;
436 kb=(fft1_nx+1)&fft1n_mask;
437 nx=fft1_nx;
438 na=fft1_nb;
439 }
440 else
441 {
442 fq=&mix1_fq_mid[ss*max_fft2n];
443 dfq=&mix1_fq_slope[ss*max_fft2n];
444 d2fq=&mix1_fq_curv[ss*max_fft2n];
445 fqs=&mix1_fq_start[ss*max_fft2n];
446 ka=(fft2_nx+fft2n_mask)&fft2n_mask;
447 kb=(fft2_nx+1)&fft2n_mask;
448 nx=fft2_nx;
449 na=fft2_na;
450 }
451 t1=fq[nx]+dfq[ka];
452 t2=fq[kb];
453 // If t1 and t2 differ we may have to make a compromise.
454 // Assuming the user has selected a reasonable bandwidth for
455 // Morse code, we do not want to modulate with frequencies
456 // above BWFAC of the bandwidth in this first AFC.
457 // Later coherent processing will be at lower bandwidth and
458 // will not handle high frequency errors we introduce here.
459 // Here the signal is noisy because of the high bandwidth required
460 // to follow a drifting signal.
461 if(fabs(t2-t1) < BWFAC*baseband_bw_hz)
462 {
463 // Extrapolation of old used data fits well to our new frequency.
464 // Store new first and second derivatives.
465 dfq [nx]= fq[kb]- fq[nx];
466 d2fq[nx]=dfq[nx]-dfq[ka];
467 }
468 else
469 {
470 // Use the maximum allowed curvature to produce a frequency that
471 // goes as quickly as possible towards the desired frequency.
472 error=t2-t1;
473 curv=BWFAC*baseband_bw_hz;
474 if(error < 0)curv=-curv;
475 t3=fabs(error)/2;
476 kk=nx;
477 k=0;
478 ia=ka;
479 ib=kb;
480 while(fabs(error) > t3 && kk != na)
481 {
482 d2fq[kk]=curv;
483 dfq[kk]=dfq[ia]+curv;
484 t1=fq[kk] + dfq[kk];
485 error=fq[ib]-t1;
486 if(t1 < mix1_lowest_fq)t1=mix1_lowest_fq;
487 if(t1 > mix1_highest_fq)t1=mix1_highest_fq;
488 fq[ib]=t1;
489 ia=(ia+1)&fftxn_mask;
490 kk=(kk+1)&fftxn_mask;
491 ib=(ib+1)&fftxn_mask;
492 k++;
493 }
494 t3=error;
495 curv=-curv;
496 // The error is reduced by 50% so we reverse the sign of the curvature.
497 while(k > 0 && kk != na && t3*error>0)
498 {
499 d2fq[kk]=curv;
500 dfq[kk]=dfq[ia]+curv;
501 t1=fq[kk] + dfq[kk];
502 error=fq[ib]-t1;
503 fq[ib]=t1;
504 ia=(ia+1)&fftxn_mask;
505 kk=(kk+1)&fftxn_mask;
506 ib=(ib+1)&fftxn_mask;
507 k--;
508 }
509 }
510 // Using the data for the transform midpoints, we get the
511 // frequency for the endpoint by adding slope/2+curv/4
512 fqs[kb]=fq[nx]+0.5*dfq[nx]+0.25*d2fq[nx];
513 t1=fqs[nx]-fq[nx];
514 t2=fqs[kb]-fq[nx];
515 // The current baseband signal produced by mix1 has an error of
516 // t1 Hz at the first point and t2 Hz at the last point.
517 // **********************************************************
518 // Actually the frequency vs time function is not quite aqurate.
519 // The way the errors t1 and t1 are used below do not agree
520 // with the explanation above.
521 // The timing seems to be slightly different depending
522 // on what window was selected.
523 // The corrections below do make the AFC work well which
524 // can be verified by feeding a frequency modulated carrier
525 // into Linrad. Typically the frequency swing would be 20 Hz
526 // and the modulation frequency 0.1 Hz for a fft1/fft2
527 // bandwidth of 2 to 5 Hz.
528 // ******************************************************************
529 do_mix1(ss,t2-t1);
530 }
531
mix1_clear(int ss)532 void mix1_clear(int ss)
533 {
534 int i, poffs, pa;
535 poffs=ss*timf3_size;
536 pa=timf3_pa+poffs;
537 for(i=0; i<timf3_block; i++)
538 {
539 timf3_float[pa+i]=0;
540 }
541 }
542
set_mix1_phases(float fq,int ss)543 void set_mix1_phases(float fq, int ss)
544 {
545 float t1, t2;
546 int k;
547 int fftx_pnt;
548 if(fq<mix1_lowest_fq)
549 {
550 lirerr(55232);
551 return;
552 }
553 if(fq>mix1_highest_fq)
554 {
555 lirerr(55233);
556 return;
557 }
558 // Find out what point in fft1/fft2 to pick as the center
559 // frequency in the back transformation into timf3 by mix1.
560 t1=fq*fftx_points_per_hz;
561 fftx_pnt=t1+0.5;
562 // When we do the back transformation there will be a phase shift
563 // from sample to sample (frequency shift) that depends on
564 // whether the the selected point goes even in mix1_points.
565 // Our selected frequency is a fractional number, add
566 // whatever frequency shift that originates in the decimals
567 // of t1.
568 k=fftx_pnt%mix1.size;
569 t2=mix1.size*(fftx_pnt/mix1.size);
570 t2=t1-t2-k;
571 t2=t2-(int)(t2);
572 mix1_phase_rot[ss]=t2*2*PI_L/mix1.size;
573 // when we go from one transform to the next one there is a phase
574 // jump that we store in mix1_phase_step.
575 k=(k*(mix1.new_points))%mix1.size;
576 mix1_old_phase[ss]=mix1_phase[ss];
577 mix1_phase[ss]+=mix1_phase_step[ss];
578 mix1_phase_step[ss]=k*2*PI_L/mix1.size;
579 if(mix1_point[ss] != -1)
580 {
581 mix1_old_point[ss]=mix1_point[ss];
582 }
583 else
584 {
585 mix1_old_point[ss]=fftx_pnt;
586 }
587 mix1_point[ss]=fftx_pnt;
588 if(mix1_phase[ss] > PI_L)mix1_phase[ss]-=2*PI_L;
589 if(mix1_phase[ss] < PI_L)mix1_phase[ss]+=2*PI_L;
590 }
591
fft2_mix1_afc(void)592 void fft2_mix1_afc(void)
593 {
594 // Use fft2 with a frequency shift that is different for each transform.
595 // The frequency shift is calculated by fft2_afc and stored
596 // in mix1_fq_mid
597 int i,n,n2,ss,mm;
598 float t1;
599 int nn,kk,ia,ib,ic;
600 float *z;
601 short int *zxy;
602 n=mix1.size*ui.rx_rf_channels;
603 n2=2*n;
604 mm=twice_rxchan;
605 nn=twice_rxchan*fft2_to_fft1_ratio;
606 for(ss=0; ss<genparm[MIX1_NO_OF_CHANNELS]; ss++)
607 {
608 if(mix1_selfreq[ss] >= 0)
609 {
610 // Frequency no ss is selected.
611 t1=mix1_fq_mid[ss*max_fft2n+fft2_nx];
612 set_mix1_phases(t1,ss);
613 kk=mix1_point[ss]*mm;
614 // Copy mix1.size points to fftn_tmp and make the transform
615 // This way we select a limited frequency range and reduce
616 // the sampling rate by mix1.size/fft1_size
617 ia=nn*fft1_first_point;
618 ib=n;
619 if(ib > nn*fft1_last_point-kk)ib=nn*fft1_last_point-kk;
620 if(ib < 0)ib=0;
621 ia=0;
622 if(ia < nn*fft1_first_point-kk)ia=nn*fft1_first_point-kk;
623 for(i=0; i<ia; i++)fftn_tmp[i]=0;
624 if(fft_cntrl[FFT2_CURMODE].mmx == 0)
625 {
626 z=&fft2_float[kk+mm*fft2_nx*fft2_size];
627 for(i=ia; i<ib; i++)fftn_tmp[i]=z[i];
628 }
629 else
630 {
631 zxy=&fft2_short_int[kk+mm*fft2_nx*fft2_size];
632 for(i=ia; i<ib; i++)fftn_tmp[i]=zxy[i];
633 }
634 for(i=ib; i<n+1; i++)fftn_tmp[i]=0;
635 kk-=n2;
636 ib=n;
637 if(ib < nn*fft1_first_point-kk)ib=nn*fft1_first_point-kk;
638 for(i=n+1; i<ib; i++)fftn_tmp[i]=0;
639 ic=n2;
640 if(ic > nn*fft1_last_point-kk)ic=nn*fft1_last_point-kk;
641 if(fft_cntrl[FFT2_CURMODE].mmx == 0)
642 {
643 z=&fft2_float[kk+mm*fft2_nx*fft2_size];
644 for(i=ib; i<ic; i++)fftn_tmp[i]=z[i];
645 }
646 else
647 {
648 zxy=&fft2_short_int[kk+mm*fft2_nx*fft2_size];
649 for(i=ib; i<ic; i++)fftn_tmp[i]=zxy[i];
650 }
651 for(i=ic; i<n2; i++)fftn_tmp[i]=0;
652 do_mix1_afc(ss);
653 }
654 else
655 {
656 mix1_clear(ss);
657 }
658 }
659 timf3_pa=(timf3_pa+timf3_block)&timf3_mask;
660 fft2_nx=(fft2_nx+1)&fft2n_mask;
661 }
662
fft2_mix1_fixed(void)663 void fft2_mix1_fixed(void)
664 {
665 // Use fft2 with a constant frequency shift given by mix1_point[]
666 int ib,i,k,n,n2,ss,mm,nn;
667 float *z;
668 float t1;
669 short int *zxy;
670 n=mix1.size*ui.rx_rf_channels;
671 n2=2*n;
672 mm=twice_rxchan;
673 nn=twice_rxchan*fft2_to_fft1_ratio;
674 for(ss=0; ss<genparm[MIX1_NO_OF_CHANNELS]; ss++)
675 {
676 t1=mix1_selfreq[ss];
677 if(t1 >= 0)
678 {
679 // Frequency no ss is selected.
680 set_mix1_phases(t1,ss);
681 // Copy mix1.size points to fftn_tmp and make the transform
682 // This way we select a limited frequency range and reduce
683 // the sampling rate by mix1.size/fft1_size
684 k=mix1_point[ss]*mm;
685 ib=n;
686 if(ib > nn*fft1_last_point-k)ib=nn*fft1_last_point-k;
687 if(ib < 0) ib=0;
688 if(fft_cntrl[FFT2_CURMODE].mmx == 0)
689 {
690 z=&fft2_float[k+mm*fft2_nx*fft2_size];
691 for(i=0; i<ib; i++)fftn_tmp[i]=z[i];
692 }
693 else
694 {
695 zxy=&fft2_short_int[k+mm*fft2_nx*fft2_size];
696 for(i=0; i<ib; i++)fftn_tmp[i]=zxy[i];
697 }
698 for(i=ib; i<n; i++)fftn_tmp[i]=0;
699 k-=n2;
700 ib=n;
701 if(ib < nn*fft1_first_point-k)ib=nn*fft1_first_point-k;
702 for(i=n; i<ib; i++)fftn_tmp[i]=0;
703 if(fft_cntrl[FFT2_CURMODE].mmx == 0)
704 {
705 z=&fft2_float[k+mm*fft2_nx*fft2_size];
706 for(i=ib; i<n2; i++)fftn_tmp[i]=z[i];
707 }
708 else
709 {
710 zxy=&fft2_short_int[k+mm*fft2_nx*fft2_size];
711 for(i=ib; i<n2; i++)fftn_tmp[i]=zxy[i];
712 }
713 do_mix1(ss,0);
714 }
715 else
716 {
717 mix1_clear(ss);
718 }
719 }
720 timf3_pa=(timf3_pa+timf3_block)&timf3_mask;
721 fft2_nx=(fft2_nx+1)&fft2n_mask;
722 }
723
fft1_mix1_fixed(void)724 void fft1_mix1_fixed(void)
725 {
726 // Use fft1 with a constant frequency shift given by mix1_point[]
727 int i,n,n2,ss,mm;
728 float *x;
729 int kk,ib;
730 float t1;
731 n=mix1.size*ui.rx_rf_channels;
732 n2=2*n;
733 mm=twice_rxchan;
734 for(ss=0; ss<genparm[MIX1_NO_OF_CHANNELS]; ss++)
735 {
736 t1=mix1_selfreq[ss];
737 if(t1 >= 0)
738 {
739 // Frequency no ss is selected.
740 if(rx_mode != MODE_TXTEST)
741 {
742 set_mix1_phases(t1,ss);
743 }
744 kk=mix1_point[ss]*mm;
745 // Copy mix1.size points to fftn_tmp and make the transform
746 // This way we select a limited frequency range and reduce
747 // the sampling rate by mix1.size/fft1_size
748 x=&fft1_float[fft1_px+kk];
749 ib=n;
750 if(ib > mm*fft1_last_point-kk)ib=mm*fft1_last_point-kk;
751 if(ib < 0) ib=0;
752 for(i=0; i<ib; i++)fftn_tmp[i]=x[i];
753 for(i=ib; i<=n; i++)fftn_tmp[i]=0;
754 kk-=n2;
755 x=&fft1_float[fft1_px+kk];
756 ib=n;
757 if(ib < mm*fft1_first_point-kk)ib=mm*fft1_first_point-kk;
758 for(i=n; i<ib; i++)fftn_tmp[i]=0;
759 for(i=ib; i<n2; i++)fftn_tmp[i]=x[i];
760 do_mix1(ss,0);
761 }
762 else
763 {
764 mix1_clear(ss);
765 }
766 }
767 timf3_pa=(timf3_pa+timf3_block)&timf3_mask;
768 fft1_nx=(fft1_nx+1)&fft1n_mask;
769 fft1_px=(fft1_px+fft1_block)&fft1_mask;
770 }
771
772
773
fft1_mix1_afc(void)774 void fft1_mix1_afc(void)
775 {
776 // Use fft1 with a frequency shift that is different for each transform.
777 // The frequency shift is calculated by fft1_afc and stored
778 // in mix1_fq_mid
779 int i,n,n2,ss,mm;
780 float *x;
781 float t1;
782 int kk,ia,ib,ic;
783 n=mix1.size*ui.rx_rf_channels;
784 n2=2*n;
785 mm=twice_rxchan;
786 for(ss=0; ss<genparm[MIX1_NO_OF_CHANNELS]; ss++)
787 {
788 if(mix1_selfreq[ss] >= 0)
789 {
790 // Frequency no ss is selected.
791 t1=mix1_fq_mid[ss*max_fft1n+fft1_nx];
792 set_mix1_phases(t1,ss);
793 kk=mix1_point[ss]*mm;
794 // Copy mix1.size points to fftn_tmp and make the transform
795 // This way we select a limited frequency range and reduce
796 // the sampling rate by mix1.size/fft1_size
797 x=&fft1_float[fft1_nx*fft1_block+kk];
798 ia=mm*fft1_first_point;
799 ib=n;
800 if(ib > mm*fft1_last_point-kk)ib=mm*fft1_last_point-kk;
801 if(ib < 0)ib=0;
802 ia=0;
803 if(ia < mm*fft1_first_point-kk)ia=mm*fft1_first_point-kk;
804 for(i=0; i<ia; i++)fftn_tmp[i]=0;
805 for(i=ia; i<ib; i++)fftn_tmp[i]=x[i];
806 for(i=ib; i<n+1; i++)fftn_tmp[i]=0;
807 kk-=n2;
808 x=&fft1_float[fft1_nx*fft1_block+kk];
809 ib=n;
810 if(ib < mm*fft1_first_point-kk)ib=mm*fft1_first_point-kk;
811 for(i=n+1; i<ib; i++)fftn_tmp[i]=0;
812 ic=n2;
813 if(ic > mm*fft1_last_point-kk)ic=mm*fft1_last_point-kk;
814 for(i=ib; i<ic; i++)fftn_tmp[i]=x[i];
815 for(i=ic; i<n2; i++)fftn_tmp[i]=0;
816 do_mix1_afc(ss);
817 }
818 else
819 {
820 mix1_clear(ss);
821 }
822 }
823 timf3_pa=(timf3_pa+timf3_block)&timf3_mask;
824 fft1_nx=(fft1_nx+1)&fft1n_mask;
825 fft1_px=(fft1_px+fft1_block)&fft1_mask;
826 }
827
828
829
830
831
832
833
834
835