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 "sigdef.h"
27 #include "screendef.h"
28 #include "fft1def.h"
29 #include "options.h"
30 #include "llsqdef.h"
31 #include "fft3def.h"
32 
33 #define MIN_DASHNO 8
34 #define CW_CORRELATE_GOODLEN 25
35 #define MIN_CORRELATE_SEP 70
36 #define MAX_CORRSUM 10
37 #define OVFL_PROTECT 0.00000000000000001
38 #define MORSE_CLOCK_COH_TIME 16
39 
40 
41 #define ZZ 0.000001
42 //   name     data    length
43 // CW_DASH    |---_|     4
44 // CW_DOT     |-_|       2
45 // CW_SPACE   |__|       2
46 // CW_WORDSEP |____|     4
47 
48 void check_cw(int num,int type);
49 void first_morse_decode(void);
50 void continued_morse_decode(void);
51 void show_cw(char *caller);
52 
53 // *********************************************************
54 // *********************************************************
55 // These defines allow a lot of information to be written to dmp
56 // define DUMPFILE 1 in main.c to use this.
57 #if DUMPFILE == TRUE
58 #define PR00 0
59 #define PR01 0
60 #define PR02 1
61 #define PR03 0
62 #define PR04 0
63 #define PR05 0
64 #define PR06 0
65 #define PR07 0
66 #define PR08 0
67 #define PR09 0
68 #define PR10 0
69 #else
70 #define PR00 0
71 #define PR01 0
72 #define PR02 0
73 #define PR03 0
74 #define PR04 0
75 #define PR05 0
76 #define PR06 0
77 #define PR07 0
78 #define PR08 0
79 #define PR09 0
80 #define PR10 0
81 #endif
82 
83 
84 #define PRT00 if(PR00 != 0)DEB
85 #define PRT01 if(PR01 != 0)DEB
86 #define PRT02 if(PR02 != 0)DEB
87 #define PRT03 if(PR03 != 0)DEB
88 #define PRT04 if(PR04 != 0)DEB
89 #define PRT05 if(PR05 != 0)DEB
90 #define PRT06 if(PR06 != 0)DEB
91 #define PRT07 if(PR07 != 0)DEB
92 #define PRT08 if(PR08 != 0)DEB
93 #define PRT09 if(PR09 != 0)DEB
94 #define PRT10 if(PR10 != 0)DEB
95 // *********************************************************
96 // *********************************************************
97 
98 // float[2] baseb_out=data to send to loudspeaker
99 // float[2] baseb=complex amplitude of first level coherent data.
100 // float[2] baseb_raw=complex amplitude of baseband signal. Raw data, pol. adapted.
101 // float[2] baseb_raw_orthog=complex amplitude of pol. orthog signal. Raw data.
102 // float[2] baseb_carrier=phase of carrier. Complex data, cosines and sines.
103 // float[1] baseb_carrier_ampl=amplitude of carrier
104 // float[1] baseb_totpwr=total power of baseb_raw
105 // float[2] baseb_envelope=complex amplitude from fitted dots and dashes.
106 // float[1] baseb_upthreshold=forward peak detector for power
107 // float[1] baseb_threshold=combined forward and backward peak detector at -6dB
108 // float[2] baseb_fit=fitted dots and dashes.
109 // float[2] baseb_tmp=array for intermediate data in complex format
110 // float[2] baseb_sho1=array for showing intermediate data in complex format
111 // float[2] baseb_sho2=array for showing intermediate data in complex format
112 // float[1] baseb_agc_level=used only when AGC is enabled.
113 // short int[1] baseb_ramp=indicator for time of power above/below threshold.
114 // short_int[1] baseb_clock=CW code clock
115 // float[2] baseb_tmp=for debug during development
116 
117 // baseb_pa  The starting point of the latest mix2.size/2 points.
118 // baseb_pb  The point up to which thresholds exist.
119 // baseb_pc  The point up to which cw speed statistics and ramp is collected.
120 // baseb_pd  A key up region close before baseb_pc
121 // baseb_pe  The point up to which we have run first detect.
122 // baseb_pf
123 // baseb_px  The oldest point that contains valid data.
124 
125 int best_corr_ia;
126 int best_corr_ib;
127 float best_corr_ampl;
128 int corr_len;
129 int no_of_corr;
130 int msig_ptr;
131 float msig_signal;
132 float msig_noise;
133 
134 #define MAX_GUESS_DATA 100
135 typedef struct {
136 float pos;
137 float re;
138 float im;
139 float noise;
140 int wei;
141 } GUESS_DATA;
142 
143 GUESS_DATA msig[MAX_GUESS_DATA];
144 
145 typedef struct {
146 int pos;
147 int sep;
148 float fpos;
149 float val;
150 } CORR_INFO;
151 
152 CORR_INFO corr[MAX_CORRSUM];
153 CORR_INFO tmpcorr;
154 
show_msig(int ic)155 void show_msig(int ic)
156 {
157 int k;
158 for(k=0; k<ic; k++)
159   {
160   fprintf( dmp,"\nmsig[%d] [%.1f]=%f, (%f,%f) W=%d",k,msig[k].pos,
161     msig[k].pos/cwbit_pts,ZZ*msig[k].re,ZZ*msig[k].im,msig[k].wei);
162    }
163 }
164 
165 
fit_msig(void)166 void fit_msig(void)
167 {
168 int i, k, m;
169 float t1, r1, re, im, midpoint;
170 // The structure msig[0] to msig[msig_ptr-1] contains complex amplitudes
171 // that are hopefully reasonably well synchronized to the Morse symbol clock.
172 // msig[].wei is > 0 for those points that the current guess assumes
173 // the key is pressed. Fit a slowly varying complex amplitude to
174 // all points with wei > 0.
175 
176 // The time interval contained in msig is typically 30 ticks of the
177 // morse symbol clock.
178 // Over a short time like this, the complex amplitude of the
179 // carrier can not change very much so we should only fit a
180 // small number of parameters to describe it.
181 t1=msig[msig_ptr-1].pos-msig[0].pos;
182 if(t1<0)t1+=baseband_size;
183 t1/=2;
184 midpoint=msig[0].pos+t1;
185 if(midpoint >= baseband_size)midpoint+=baseband_size;
186 t1=sqrt(t1);
187 llsq_neq=0;
188 for(i=0; i<msig_ptr; i++)
189   {
190   if(msig[i].wei > 0)llsq_neq++;
191   }
192 llsq_errors=fftn_tmp;
193 llsq_derivatives=&llsq_errors[2*llsq_neq];
194 k=0;
195 for(i=0; i<msig_ptr; i++)
196   {
197   if(msig[i].wei > 0)
198     {
199     llsq_errors[2*k  ]=msig[i].re*msig[i].wei;
200     llsq_errors[2*k+1]=msig[i].im*msig[i].wei;
201     llsq_derivatives[k]=t1*msig[i].wei;
202     r1=msig[i].pos-midpoint;
203     if(r1<-(baseband_size>>1))r1+=baseband_size;
204     llsq_derivatives[llsq_neq+k]=r1*msig[i].wei;
205     llsq_derivatives[2*llsq_neq+k]=r1*r1*msig[i].wei;
206     llsq_derivatives[3*llsq_neq+k]=r1*r1*r1*msig[i].wei/t1;
207     k++;
208     }
209   }
210 llsq_npar=4;
211 if(llsq2() != 0)
212   {
213   lirerr(9361050);
214   return;
215   }
216 // compute signal and noise
217 
218 msig_noise=0;
219 msig_signal=0;
220 k=0;
221 m=0;
222 for(i=0; i<msig_ptr; i++)
223   {
224   if(msig[i].wei > 0)
225     {
226     llsq_errors[2*k  ]=msig[i].re*msig[i].wei;
227     llsq_errors[2*k+1]=msig[i].im*msig[i].wei;
228     llsq_derivatives[k]=t1*msig[i].wei;
229     r1=msig[i].pos-midpoint;
230     if(r1<-(baseband_size>>1))r1+=baseband_size;
231     re=t1*llsq_steps[0]+r1*llsq_steps[2]+r1*r1*llsq_steps[4]+r1*r1*r1*llsq_steps[6]/t1;
232     im=t1*llsq_steps[1]+r1*llsq_steps[3]+r1*r1*llsq_steps[5]+r1*r1*r1*llsq_steps[7]/t1;
233     msig_signal+=msig[i].wei*(re*re+im*im);
234     re-=msig[i].re;
235     im-=msig[i].im;
236 // Dashes integrate 3 times longer so their noise is sqrt(3) smaller.
237 // Take that into account.
238 // A region with noise only would give Ndots=n1*n1+n2*n2+n3*n3 when
239 // evaluated as a dot (assume n1=n2=n3 on the average) so the
240 // noise contribution from a false dash would be Ndots=3*n*n.
241 // When evaluated as a dash, Ndash=3*n4*n4, because we have three parts
242 // with the same complex amplitude n4. n4 is n/sqrt(3) on the average
243 // because of the longer integration time so when evaluating as a
244 // dash we would get 3 times less noise when there is no signal.
245 // Therefore, multiply the contribution to msig_noise by 9 for a dash.
246     re*=msig[i].wei;
247     im*=msig[i].wei;
248     msig_noise+=msig[i].wei*(re*re+im*im);
249     m+=msig[i].wei;
250     k++;
251     }
252   else
253     {
254     if(msig[i].wei == 0)msig_noise+=msig[i].noise;
255     }
256   }
257 msig_signal=sqrt(msig_signal/m);
258 msig_noise=sqrt(msig_noise/msig_ptr);
259 }
260 
261 
store_msig(int k)262 void store_msig(int k)
263 {
264 int j;
265 switch (cw[k].type)
266   {
267   case CW_DOT:
268 // CW_DOT     |-_|       2
269 //             ^
270   msig[msig_ptr].pos=cw[k].midpoint;
271   msig[msig_ptr].wei=1;
272   msig[msig_ptr].re=cw[k].raw_re;
273   msig[msig_ptr].im=cw[k].raw_im;
274   msig_ptr++;
275   cg_wave_midpoint=cw[k].midpoint+cwbit_pts;
276   if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
277   msig[msig_ptr].pos=cg_wave_midpoint;
278   wb_investigate_region(cg_wave_midpoint, 1);
279   msig[msig_ptr].re=reg_dot_re[0];
280   msig[msig_ptr].im=reg_dot_im[0];
281   msig[msig_ptr].noise=reg_dot_re[0]*reg_dot_re[0]+reg_dot_im[0]*reg_dot_im[0];
282   msig[msig_ptr].wei=0;
283   msig_ptr++;
284   break;
285 
286   case CW_SPACE:
287 // CW_SPACE   |__|       2
288 //             ^
289   cg_wave_midpoint=cw[k].midpoint;
290   msig[msig_ptr].pos=cg_wave_midpoint;
291   wb_investigate_region(cg_wave_midpoint, 1);
292   msig[msig_ptr].re=reg_dot_re[0];
293   msig[msig_ptr].im=reg_dot_im[0];
294   msig[msig_ptr].noise=reg_dot_re[0]*reg_dot_re[0]+reg_dot_im[0]*reg_dot_im[0];
295   msig[msig_ptr].wei=0;
296   msig_ptr++;
297   cg_wave_midpoint+=cwbit_pts;
298   if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
299   msig[msig_ptr].pos=cg_wave_midpoint;
300   wb_investigate_region(cg_wave_midpoint, 1);
301   msig[msig_ptr].re=reg_dot_re[0];
302   msig[msig_ptr].im=reg_dot_im[0];
303   msig[msig_ptr].noise=reg_dot_re[0]*reg_dot_re[0]+reg_dot_im[0]*reg_dot_im[0];
304   msig[msig_ptr].wei=0;
305   msig_ptr++;
306   break;
307 
308   case CW_DASH:
309 // CW_DASH    |---_|     4
310 //              ^
311   msig[msig_ptr].pos=cw[k].midpoint-cwbit_pts;
312   msig[msig_ptr].wei=0;
313   msig[msig_ptr].re=0;
314   msig[msig_ptr].im=0;
315   msig[msig_ptr].noise=0;
316   msig_ptr++;
317   msig[msig_ptr].pos=cw[k].midpoint;
318   msig[msig_ptr].wei=3;
319   msig[msig_ptr].re=cw[k].raw_re;
320   msig[msig_ptr].im=cw[k].raw_im;
321   msig_ptr++;
322   msig[msig_ptr].pos=cw[k].midpoint+cwbit_pts;
323   cg_wave_midpoint=msig[msig_ptr].pos;
324   msig[msig_ptr].wei=0;
325   msig[msig_ptr].re=0;
326   msig[msig_ptr].im=0;
327   msig[msig_ptr].noise=0;
328   msig_ptr++;
329   cg_wave_midpoint+=cwbit_pts;
330   if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
331   msig[msig_ptr].pos=cg_wave_midpoint;
332   wb_investigate_region(cg_wave_midpoint, 1);
333   msig[msig_ptr].re=reg_dot_re[0];
334   msig[msig_ptr].im=reg_dot_im[0];
335   msig[msig_ptr].noise=reg_dot_re[0]*reg_dot_re[0]+reg_dot_im[0]*reg_dot_im[0];
336   msig[msig_ptr].wei=0;
337   msig_ptr++;
338   break;
339 
340   case CW_WORDSEP:
341 // CW_WORDSEP |____|     4
342 //              ^
343   cg_wave_midpoint=cw[k].midpoint;
344   wb_investigate_region(cg_wave_midpoint, 3);
345   cg_wave_midpoint-=cwbit_pts;
346   if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
347   for(j=0; j<3; j++)
348     {
349     msig[msig_ptr].pos=cg_wave_midpoint;
350     msig[msig_ptr].re=reg_dot_re[j];
351     msig[msig_ptr].im=reg_dot_im[j];
352     msig[msig_ptr].noise=reg_dot_re[j]*reg_dot_re[j]+reg_dot_im[j]*reg_dot_im[j];
353     msig[msig_ptr].wei=0;
354     msig_ptr++;
355     cg_wave_midpoint+=cwbit_pts;
356     if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
357     }
358   msig[msig_ptr].pos=cg_wave_midpoint;
359   wb_investigate_region(cg_wave_midpoint, 1);
360   msig[msig_ptr].re=reg_dot_re[0];
361   msig[msig_ptr].im=reg_dot_im[0];
362   msig[msig_ptr].noise=reg_dot_re[0]*reg_dot_re[0]+reg_dot_im[0]*reg_dot_im[0];
363   msig[msig_ptr].wei=0;
364   msig_ptr++;
365   break;
366 
367   default:
368   lirerr(874529);
369   break;
370   }
371 }
372 
fill_known_high_msig(void)373 void fill_known_high_msig(void)
374 {
375 int k, dist;
376 // ptr points to a decoded Morse part in the CW array.
377 // Step downwards through decoded parts until the first
378 // undecoded is encountered or until the total distance is
379 // 10 parts.
380 show_cw("----- fill high guesses  -----");
381 dist=0;
382 k=cw_ptr+1;
383 if(cw[k].unkn == 0)lirerr(8835263);
384 store_msig(k);
385 k++;
386 while(k<no_of_cwdat && cw[k].unkn == 0 && dist < 10)
387   {
388   dist+=cw[k].len;
389   store_msig(k);
390   k++;
391   }
392 }
393 
fill_known_low_msig(void)394 void fill_known_low_msig(void)
395 {
396 int k, dist;
397 // ptr points to a decoded Morse part in the CW array.
398 // Step downwards through decoded parts until the first
399 // undecoded is encountered or until the total distance is
400 // 10 parts.
401 dist=0;
402 k=cw_ptr;
403 while(k>0 && cw[k].unkn == 0 && dist < 10)
404   {
405   dist+=cw[k].len;
406   k--;
407   }
408 // fill known info into msig.
409 while(k<cw_ptr || cw[k].unkn == 0)
410   {
411   store_msig(k);
412   k++;
413   }
414 }
415 
check_hguess3(int val,int bits,int charval_dwn_rev,int charbits_dwn)416 char check_hguess3(int val, int bits, int charval_dwn_rev, int charbits_dwn)
417 {
418 int i, m, charbits, charval;
419 charbits=bits+charbits_dwn+2;
420 if(charbits > 6)return FALSE;
421 charval=val<<2;
422 m=charval_dwn_rev;
423 for(i=0; i<charbits_dwn; i++)
424   {
425   charval<<=1;
426   charval+=m&1;
427   m>>=1;
428   }
429 if(morsascii[charbits-1][charval] == 242 ||
430    morsascii[charbits-1][charval] == 243)return FALSE;
431 return TRUE;
432 }
433 
check_hguess4(int val,int bits,int charval_dwn_rev,int charbits_dwn)434 char check_hguess4(int val, int bits, int charval_dwn_rev, int charbits_dwn)
435 {
436 int i, m, charbits, charval;
437 charbits=bits+charbits_dwn+1;
438 if(charbits > 6)return FALSE;
439 charval=val<<1;
440 charval++;
441 m=charval_dwn_rev;
442 for(i=0; i<charbits_dwn; i++)
443   {
444   charval<<=1;
445   charval+=m&1;
446   m>>=1;
447   }
448 if(morsascii[charbits-1][charval] == 242 ||
449    morsascii[charbits-1][charval] == 243)return FALSE;
450 return TRUE;
451 }
452 
check_hguess3a(int val,int bits,int charval_dwn_rev,int charbits_dwn)453 char check_hguess3a(int val, int bits, int charval_dwn_rev, int charbits_dwn)
454 {
455 int i, m, charbits, charval;
456 charbits=bits+charbits_dwn+1;
457 if(charbits > 6)return FALSE;
458 charval=val<<1;
459 m=charval_dwn_rev;
460 for(i=0; i<charbits_dwn; i++)
461   {
462   charval<<=1;
463   charval+=m&1;
464   m>>=1;
465   }
466 if(morsascii[charbits-1][charval] == 242 ||
467    morsascii[charbits-1][charval] == 243)return FALSE;
468 return TRUE;
469 }
470 
check_hguess4a(int val,int bits,int charval_dwn_rev,int charbits_dwn)471 char check_hguess4a(int val, int bits, int charval_dwn_rev, int charbits_dwn)
472 {
473 int i, m, charbits, charval;
474 charbits=bits+charbits_dwn;
475 if(charbits > 6)return FALSE;
476 charval=val;
477 m=charval_dwn_rev;
478 for(i=0; i<charbits_dwn; i++)
479   {
480   charval<<=1;
481   charval+=m&1;
482   m>>=1;
483   }
484 if(morsascii[charbits-1][charval] == 242 ||
485    morsascii[charbits-1][charval] == 243)return FALSE;
486 return TRUE;
487 }
488 
part_guesses(void)489 int part_guesses(void)
490 {
491 // Look for long undecoded regions where a decision might be certain
492 // enough based on an extrapolation from the surrounding decoded
493 // regions.
494 
495 return 0;
496 }
497 
character_guesses(void)498 int character_guesses(void)
499 {
500 char lguess_flag[7],hguess_flag[5],guess_flag[7][5];
501 int charval_up, charbits_up;
502 int charval_dwn, charval_dwn_rev, charbits_dwn;
503 int added_parts;
504 int i, j, k, m, ia, ib, ic, gap, iptr;
505 int nlg, nhg, mlg, mhg;
506 int val, bits;
507 float r1, t1;
508 float dash_re[3], dash_im[3];
509 float dot_re[20], dot_im[20],dot_pwr[20];
510 // We have dashes and hopefully some dots and separators.
511 // Look for a space or a word separator and try to decode upwards.
512 show_cw("  char guesses");
513 cw_ptr=0;
514 added_parts=0;
515 region_guesses:;
516 show_cw("  char guesses");
517 while(cw_ptr < no_of_cwdat &&
518       cw[cw_ptr].type != CW_WORDSEP &&
519       cw[cw_ptr].type != CW_SPACE)cw_ptr++;
520 fprintf( dmp,"\nCHARGUESS cw_ptr=%d",cw_ptr);
521 if(cw_ptr < no_of_cwdat)
522   {
523 // We have a separator here!
524 // Check for an undecoded region above it.
525   iptr=cw_ptr+1;
526   while(iptr < no_of_cwdat && cw[iptr].unkn == 0)
527     {
528     if( cw[iptr].type == CW_WORDSEP || cw[iptr].type == CW_SPACE)cw_ptr=iptr;
529     iptr++;
530     }
531 fprintf( dmp,"\ncw_ptr %d   iptr %d",cw_ptr,iptr);
532   if(iptr < no_of_cwdat-1)
533     {
534     charval_up=0;
535     charbits_up=0;
536     k=cw_ptr;
537     k++;
538     while(k < iptr)
539       {
540       charbits_up++;
541       charval_up<<=1;
542       if(cw[k].type==CW_DASH)charval_up++;
543       k++;
544       }
545     gap=cw[iptr].unkn;
546 fprintf( dmp,"\ngap=%d iptr %d",gap,iptr);
547 fprintf( dmp,"\nbits %d  val %d  %c", charbits_up,charval_up,
548                 morsascii[charbits_up-1][charval_up]);
549     if(charbits_up > 6 ||
550        morsascii[charbits_up-1][charval_up] == 243 ||
551        gap >= 16 ||
552        gap <= 4 ||
553        cw[iptr].type == CW_WORDSEP ||
554        cw[iptr].type == CW_SPACE)
555       {
556       cw_ptr=iptr;
557 fprintf( dmp,"\nERROR below");
558 // This is an error. Do nothing for now.
559       goto region_guesses;
560       }
561 // We here have a sequence like this:
562 //  known-_??????????????_-known
563 // gap is the length of the undecoded region and it has to be
564 // an even number.
565     msig_ptr=0;
566 // This is a small gap. Use the information from decoded dots and
567 // dashes from both sides of the region.
568     cw_ptr=iptr-1;
569     fill_known_low_msig();
570     ia=msig_ptr;
571     msig_ptr+=gap;
572     ib=msig_ptr;
573     fill_known_high_msig();
574     ic=msig_ptr;
575     cg_wave_midpoint=msig[ib].pos-cwbit_pts;
576     ib--;
577     if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
578     wb_investigate_region(cg_wave_midpoint, 1);
579     msig[ib].pos=cg_wave_midpoint;
580     msig[ib].re=reg_dot_re[0];
581     msig[ib].im=reg_dot_im[0];
582     msig[ib].noise=reg_dot_re[0]*reg_dot_re[0]+reg_dot_im[0]*reg_dot_im[0];
583     msig[ib].wei=0;
584 // We will fill in different guesses in the region ia to ib.
585 // First we fill in what is known above the undecoded region.
586 // note that we do not trust the symbol clock speed very much -
587 // we only use it 4 positions into the unknown region from
588 // either side. The operator could use hand keying and
589 // the length of dots, dashes and separators could be
590 // deviating from the nominal values.
591     t1=msig[ia-1].pos;
592     for(k=ia; k<ib; k++)
593       {
594       t1+=cwbit_pts;
595       if(t1>=baseband_size)t1-=baseband_size;
596       msig[k].pos=t1;
597       msig[k].re=0;
598       msig[k].im=k;
599       msig[k].wei=-1;
600       }
601     ib--;
602     t1=cg_wave_midpoint;
603     k=1+(ia+ib)/2;
604     t1-=(ib-k+2)*cwbit_pts;
605     if(t1<0)t1+=baseband_size;
606     while(k<=ib)
607       {
608       t1+=cwbit_pts;
609       if(t1>=baseband_size)t1-=baseband_size;
610       msig[k].pos=t1;
611       k++;
612       }
613 // The Morse code goes in units of 2 or 4.
614 // The region has key-down at both ends so we know that the first
615 // pand the last points in the gap region must be key-up.
616 // Here are all possible guesses for the beginning:
617 //  ****-_____?????_-****   lguess 0
618 //  ****-___-_?????_-****   lguess 1
619 //  ****-_-___?????_-****   lguess 2
620 //  ****-_-_-_?????_-****   lguess 3
621 //  ****-_---_?????_-****   lguess 4
622 //  ****-___--?????_-****   lguess 5
623 //  ****-_-_--?????_-****   lguess 6
624 //      ia^
625 //        0123
626 //
627 // Here are all possible guesses for the end:
628 //  ****-_?????____-****   hguess 0
629 //  ****-_?????-___-****   hguess 1
630 //  ****-_?????__-_-****   hguess 2
631 //  ****-_?????-_-_-****   hguess 3
632 //  ****-_?????---_-****   hguess 4
633 //             ib^
634 //             210
635 //
636 // In all we have 35 guesses, but many of them are likely
637 // to be impossible since the decoded data would not fit
638 // the Morse alphabet.
639     for(nlg=0; nlg<7; nlg++)lguess_flag[nlg]=TRUE;
640     for(nhg=0; nhg<5; nhg++)hguess_flag[nhg]=TRUE;
641 // Fill in acceptable guesses in lguess_flag.
642     if(charbits_up == 6)
643       {
644 // This is the maximum length for a Morse character.
645 // Skip if not legal, force key-up otherwise.
646       if(morsascii[charbits_up-1][charval_up] == 243)
647         {
648 fprintf( dmp,"\nERROR above");
649         goto skip_guesses;
650         }
651       lguess_flag[2]=FALSE;
652       lguess_flag[3]=FALSE;
653       lguess_flag[4]=FALSE;
654       lguess_flag[6]=FALSE;
655       }
656     else
657       {
658       if(charbits_up == 5)
659         {
660 // Skip guesses that would add more than one part.
661         lguess_flag[3]=FALSE;
662         lguess_flag[6]=FALSE;
663 // In case the character is not legal, but adding one part
664 // could make it legal, skip guesses that do not add one part.
665         if(morsascii[charbits_up-1][charval_up] == 242)
666           {
667           lguess_flag[0]=FALSE;
668           lguess_flag[1]=FALSE;
669           lguess_flag[5]=FALSE;
670           }
671 // Check whether adding a dot would give a legal character.
672         if(morsascii[charbits_up][charval_up<<1] == 243)
673           {
674           lguess_flag[2]=FALSE;
675           }
676 // Check whether adding a dash would give a legal character.
677         if(morsascii[charbits_up][(charval_up<<1)+1] == 243)
678           {
679           lguess_flag[4]=FALSE;
680           }
681         }
682       else
683         {
684         if(charbits_up == 4)
685           {
686           if(morsascii[charbits_up][charval_up<<1] == 243)
687             {
688             lguess_flag[2]=FALSE;
689             }
690           if(morsascii[charbits_up+1][charval_up<<2] == 243)
691             {
692             lguess_flag[3]=FALSE;
693             }
694           if(morsascii[charbits_up][(charval_up<<1)+1] == 243)
695             {
696             lguess_flag[4]=FALSE;
697             }
698           if(morsascii[charbits_up+1][(charval_up<<2)+1] == 243)
699             {
700             lguess_flag[6]=FALSE;
701             }
702           }
703         }
704       }
705 // Look for a separator upwards.
706     k=iptr+1;
707     while( k < no_of_cwdat &&
708            cw[k].unkn==0 &&
709            cw[k].type != CW_WORDSEP &&
710            cw[k].type != CW_SPACE)k++;
711     if( k == no_of_cwdat || cw[k].unkn != 0)goto skip_guesses;
712 // There is a known separator above the current region.
713 // Decode it downwards.
714     charbits_dwn=0;
715     charval_dwn_rev=0;
716     while(k > iptr)
717       {
718       charval_dwn_rev<<=1;
719       k--;
720       if(cw[k].type==CW_DASH)charval_dwn_rev++;
721       charbits_dwn++;
722       }
723     if(charbits_dwn > 6)goto skip_guesses;
724     k=0;
725     m=charval_dwn_rev;
726     for(i=0; i<charbits_dwn; i++)
727       {
728       k<<=1;
729       k+=m&1;
730       m>>=1;
731       }
732     charval_dwn=k;
733     if(charbits_dwn==6)
734       {
735       if(morsascii[charbits_dwn-1][charval_dwn] == 243)
736         {
737         goto skip_guesses;
738         }
739       hguess_flag[2]=FALSE;
740       hguess_flag[3]=FALSE;
741       hguess_flag[4]=FALSE;
742       }
743     else
744       {
745       if(charbits_dwn==5)
746         {
747         hguess_flag[3]=FALSE;
748         if(morsascii[charbits_dwn-1][charval_dwn] == 243)
749           {
750           hguess_flag[0]=FALSE;
751           hguess_flag[1]=FALSE;
752           }
753         if(morsascii[charbits_dwn][charval_dwn] == 243)
754           {
755           hguess_flag[2]=FALSE;
756           }
757         if(morsascii[charbits_dwn][charval_dwn+32] == 243)
758           {
759           hguess_flag[4]=FALSE;
760           }
761         }
762       else
763         {
764         if(charbits_dwn==4)
765           {
766           if(morsascii[charbits_dwn+1][charval_dwn] == 243)
767             {
768             hguess_flag[3]=FALSE;
769             }
770           }
771         }
772       }
773     for(nlg=0;nlg<7;nlg++)
774       {
775       for(nhg=0;nhg<5;nhg++)
776         {
777         guess_flag[nlg][nhg]=lguess_flag[nlg]&hguess_flag[nhg];
778         }
779       }
780     if(gap == 8)
781       {
782 // The regions touch each other.
783 // We can not combine lguesses 5 and 6 with hguesses 0,2 or 4
784       for(i=5; i<=6; i++)
785         {
786         for(j=0; j<=4; j+=2)
787           {
788           guess_flag[i][j]=FALSE;
789           }
790         }
791 // When we combine lguesses and hguesses that both contain no
792 // space or word separator, the entire region has to be a valid
793 // Morse code.
794 // We have to check l=3,4,6 combined with h=3,4
795 // **************************************************
796 // lguess=3
797       val=charval_up<<2;
798       bits=charbits_up+2;
799       guess_flag[3][3]=check_hguess3(val, bits, charval_dwn_rev, charbits_dwn);
800       guess_flag[3][4]=check_hguess4(val, bits, charval_dwn_rev, charbits_dwn);
801 // lguess=4
802       val=(charval_up<<1)+1;
803       bits=charbits_up+1;
804       guess_flag[4][3]=check_hguess3(val, bits, charval_dwn_rev, charbits_dwn);
805       guess_flag[4][4]=check_hguess4(val, bits, charval_dwn_rev, charbits_dwn);
806 // lguess=6
807       val=(charval_up<<2)+1;
808       bits=charbits_up+2;
809       guess_flag[6][3]=check_hguess3a(val, bits, charval_dwn_rev, charbits_dwn);
810       }
811     else
812       {
813       if(gap == 6)
814         {
815 // Two positions overlap. Make all combinations that have
816 // different patterns in the overlapping region illegal.
817         guess_flag[0][1]=FALSE;
818         guess_flag[0][3]=FALSE;
819         guess_flag[0][4]=FALSE;
820         guess_flag[1][0]=FALSE;
821         guess_flag[1][2]=FALSE;
822         guess_flag[1][4]=FALSE;
823         guess_flag[2][1]=FALSE;
824         guess_flag[2][3]=FALSE;
825         guess_flag[2][4]=FALSE;
826         guess_flag[3][0]=FALSE;
827         guess_flag[3][2]=FALSE;
828         guess_flag[3][4]=FALSE;
829         guess_flag[4][0]=FALSE;
830         guess_flag[4][2]=FALSE;
831         guess_flag[4][4]=FALSE;
832         guess_flag[5][0]=FALSE;
833         guess_flag[5][1]=FALSE;
834         guess_flag[5][2]=FALSE;
835         guess_flag[5][3]=FALSE;
836         guess_flag[6][0]=FALSE;
837         guess_flag[6][1]=FALSE;
838         guess_flag[6][2]=FALSE;
839         guess_flag[6][3]=FALSE;
840 // When we combine lguesses and hguesses without any space
841 // or word separator, the entire region has to be a valid
842 // Morse code.
843 // We have to check lguess=3,4,6 when combined with hguess=2,3,4
844 // **************************************************
845 // lguess=3: only hguess=3 is possible.
846         val=charval_up<<1;
847         bits=charbits_up+1;
848         guess_flag[3][3]=check_hguess3(val, bits, charval_dwn_rev, charbits_dwn);
849 // lguess=4: only hguess=3 is possible.
850         val=(charval_up<<1)+1;
851         bits=charbits_up+1;
852         guess_flag[4][3]=check_hguess3a(val, bits, charval_dwn_rev, charbits_dwn);
853 // lguess=6: only hguess=4 is possible.
854         val=(charval_up<<2)+1;
855         bits=charbits_up+2;
856         guess_flag[6][4]=check_hguess4a(val, bits, charval_dwn_rev, charbits_dwn);
857         }
858       }
859 
860 fprintf( dmp,"\nib-ia %d, gap %d",ib-ia,gap);
861 fprintf( dmp,"\nia %d  ib %d",ia,ib);
862 for(k=1; k<msig_ptr; k++)
863 fprintf( dmp,"\n%d  %f  (%f,%f)  %d  %f",k,msig[k].pos,ZZ*msig[k].re,ZZ*msig[k].im,msig[k].wei,msig[k].pos-msig[k-1].pos);
864 for(k=0; k<7; k++)fprintf( dmp,"\nlguess_flag[%d]  %d",k,lguess_flag[k]);
865 for(k=0; k<5; k++)fprintf( dmp,"\nhguess_flag[%d]  %d",k,hguess_flag[k]);
866 fprintf( dmp,"\n");
867 for(i=0; i<7; i++)
868   {
869   fprintf( dmp,"\n");
870   for(j=0; j<5; j++)fprintf( dmp,"[%d][%d] %d   ",i,j,guess_flag[i][j]);
871   }
872 fprintf( dmp,"\n");
873 show_msig(ic);
874 
875 
876 
877 // *****************************************************************
878 // Prepare to set up msig for all allowed guesses.
879 // Dashes may be placed at ia+1 and at ib-2.
880     cg_wave_midpoint=msig[ia+1].pos;
881     wb_investigate_region(cg_wave_midpoint, -5);
882     dash_re[0]=reg_dash_re;
883     dash_im[0]=reg_dash_im;
884     cg_wave_midpoint=msig[ia+3].pos;
885     wb_investigate_region(cg_wave_midpoint, -5);
886     dash_re[1]=reg_dash_re;
887     dash_im[1]=reg_dash_im;
888 
889 
890     cg_wave_midpoint=msig[ib-2].pos;
891     wb_investigate_region(cg_wave_midpoint, -5);
892     dash_re[2]=reg_dash_re;
893     dash_im[2]=reg_dash_im;
894     for(k=ia; k<ib; k++)
895       {
896       cg_wave_midpoint=msig[k].pos;
897       wb_investigate_region(cg_wave_midpoint, 1);
898       dot_re[k-ia]=reg_dot_re[0];
899       dot_im[k-ia]=reg_dot_im[0];
900       dot_pwr[k-ia]=reg_dot_re[0]*reg_dot_re[0]+reg_dot_im[0]*reg_dot_im[0];
901       }
902 // Fill in all allowed guesses in msig one by one.
903 // Fit a smooth function to the carrier at those points where there
904 // is a key down according to the current guess.
905 // Compute the associated RMS error (noise) and average carrier
906 // amplitude (signal.) Remember S and N for each valid guess.
907     r1=0;
908     mlg=-1;
909     mhg=-1;
910     for(nlg=0; nlg<7; nlg++)
911       {
912       if(lguess_flag[nlg] == TRUE)
913         {
914         for(k=0; k<4; k++)
915           {
916           msig[ia+k].wei=0;
917           msig[ia+k].re=dot_re[k];
918           msig[ia+k].im=dot_im[k];
919           msig[ia+k].noise=dot_pwr[k];
920           }
921         switch (nlg)
922           {
923           case 0:
924 //  ****-_____?????_-****   lguess 0
925 //      ia^
926 //        0123
927           break;
928 
929           case 1:
930 //  ****-___-_?????_-****   lguess 1
931 //      ia^
932 //        0123
933           msig[ia+2].wei=1;
934           break;
935 
936           case 2:
937 //  ****-_-___?????_-****   lguess 2
938 //      ia^
939 //        0123
940           msig[ia].wei=1;
941           break;
942 
943           case 3:
944 //  ****-_-_-_?????_-****   lguess 3
945 //      ia^
946 //        0123
947           msig[ia].wei=1;
948           msig[ia+2].wei=1;
949           break;
950 
951           case 4:
952 //  ****-_---_?????_-****   lguess 4
953 //      ia^
954 //        0123
955           msig[ia  ].wei=0;
956           msig[ia  ].re=0;
957           msig[ia  ].im=0;
958           msig[ia  ].noise=0;
959           msig[ia+1].wei=3;
960           msig[ia+1].re=dash_re[0];
961           msig[ia+1].im=dash_im[0];
962           msig[ia+1].noise=dash_re[0]*dash_re[0]+dash_im[0]*dash_im[0];
963           msig[ia+2].wei=0;
964           msig[ia+2].re=0;
965           msig[ia+2].im=0;
966           msig[ia+2].noise=0;
967           break;
968 
969           case 5:
970 //  ****-___--?????_-****   lguess 5
971 //      ia^
972 //        0123
973           msig[ia+2].wei=1;
974           msig[ia+3].wei=1;
975           break;
976 
977           case 6:
978 //  ****-_-_--?????_-****   lguess 6
979 //      ia^
980 //        0123
981           msig[ia  ].wei=1;
982           msig[ia+2].wei=1;
983           msig[ia+3].wei=1;
984           break;
985           }
986         for(nhg=0; nhg<5; nhg++)
987           {
988           if(guess_flag[nlg][nhg]==TRUE)
989             {
990             for(k=ib-ia-3; k<ib-ia; k++)
991               {
992               msig[ia+k].wei=0;
993               msig[ia+k].re=dot_re[k];
994               msig[ia+k].im=dot_im[k];
995               msig[ia+k].noise=dot_pwr[k];
996               }
997             switch (nhg)
998               {
999               case 0:
1000 //  ****-_?????____-****   hguess 0
1001 //             ib^
1002 //             210
1003               break;
1004 
1005               case 1:
1006 //  ****-_?????-___-****   hguess 1
1007 //             ib^
1008 //             210
1009               msig[ib-2].wei=1;
1010               break;
1011 
1012               case 2:
1013 //  ****-_?????__-_-****   hguess 2
1014 //             ib^
1015 //             210
1016               msig[ib].wei=1;
1017               break;
1018 
1019               case 3:
1020 //  ****-_?????-_-_-****   hguess 3
1021 //             ib^
1022 //             210
1023               msig[ib].wei=1;
1024               msig[ib-2].wei=1;
1025               break;
1026 
1027               case 4:
1028 //  ****-_?????---_-****   hguess 4
1029 //             ib^
1030 //             210
1031               msig[ib-2].wei=0;
1032               msig[ib-2].re=0;
1033               msig[ib-2].im=0;
1034               msig[ib-2].noise=0;
1035               msig[ib-1].wei=3;
1036               msig[ib-1].re=dash_re[2];
1037               msig[ib-1].im=dash_im[2];
1038               msig[ib-1].noise=dash_re[2]*dash_re[2]+dash_im[2]*dash_im[2];
1039               msig[ib].wei=0;
1040               msig[ib].re=0;
1041               msig[ib].im=0;
1042               msig[ib].noise=0;
1043               break;
1044               }
1045 
1046             fit_msig();
1047             t1=msig_signal/msig_noise;
1048             if(t1 > r1)
1049               {
1050               r1=t1;
1051               mhg=nhg;
1052               mlg=nlg;
1053               }
1054             }
1055           }
1056         }
1057       }
1058 // Implement the best guess.
1059     if(mlg < 0)goto skip_guesses;
1060     cw_ptr=iptr;
1061 
1062 fprintf( dmp,"\n\n!!!!!!!!!!!! mlg %d  mhg %d !!!!!!!!!!!!!",mlg,mhg);
1063 fprintf( dmp,"\nia %d  ib %d",ia,ib);
1064 //  ****-_____?????_-****   lguess 0
1065 //  ****-___-_?????_-****   lguess 1
1066 //  ****-_-___?????_-****   lguess 2
1067 //  ****-_-_-_?????_-****   lguess 3
1068 //  ****-_---_?????_-****   lguess 4
1069 //  ****-___--?????_-****   lguess 5
1070 //  ****-_-_--?????_-****   lguess 6
1071 //      ia^
1072 //        0123
1073 //
1074 // Here are all possible guesses for the end:
1075 //  ****-_?????____-****   hguess 0
1076 //  ****-_?????-___-****   hguess 1
1077 //  ****-_?????__-_-****   hguess 2
1078 //  ****-_?????-_-_-****   hguess 3
1079 //  ****-_?????---_-****   hguess 4
1080 //             ib^
1081 //             210
1082 
1083     switch (mlg)
1084       {
1085       case 0:
1086 //  ****-_____?????_-****   lguess 0
1087 //      ia^
1088 //        0123
1089       cg_wave_raw_re=0;
1090       cg_wave_raw_im=0;
1091       cg_wave_midpoint=msig[ia+1].pos;
1092       insert_item(CW_WORDSEP);
1093       cw_ptr++;
1094       break;
1095 
1096       case 1:
1097 //  ****-___-_?????_-****   lguess 1
1098 //      ia^
1099 //        0123
1100       cg_wave_raw_re=0;
1101       cg_wave_raw_im=0;
1102       cg_wave_midpoint=msig[ia].pos;
1103       insert_item(CW_SPACE);
1104       cw_ptr++;
1105       cg_wave_raw_re=dot_re[2];
1106       cg_wave_raw_im=dot_im[2];
1107       cg_wave_midpoint=msig[ia+2].pos;
1108       insert_item(CW_DOT);
1109       cw_ptr++;
1110       break;
1111 
1112       case 2:
1113 //  ****-_-___?????_-****   lguess 2
1114 //      ia^
1115 //        0123
1116       cg_wave_raw_re=dot_re[0];
1117       cg_wave_raw_im=dot_im[0];
1118       cg_wave_midpoint=msig[ia].pos;
1119       insert_item(CW_DOT);
1120       cw_ptr++;
1121       cg_wave_raw_re=0;
1122       cg_wave_raw_im=0;
1123       cg_wave_midpoint=msig[ia+2].pos;
1124       insert_item(CW_SPACE);
1125       cw_ptr++;
1126       break;
1127 
1128           case 3:
1129 //  ****-_-_-_?????_-****   lguess 3
1130 //      ia^
1131 //        0123
1132       cg_wave_raw_re=dot_re[0];
1133       cg_wave_raw_im=dot_im[0];
1134       cg_wave_midpoint=msig[ia].pos;
1135       insert_item(CW_DOT);
1136       cw_ptr++;
1137       cg_wave_raw_re=dot_re[2];
1138       cg_wave_raw_im=dot_im[2];
1139       cg_wave_midpoint=msig[ia+2].pos;
1140       insert_item(CW_DOT);
1141       cw_ptr++;
1142       break;
1143 
1144       case 4:
1145 //  ****-_---_?????_-****   lguess 4
1146 //      ia^
1147 //        0123
1148       cg_wave_raw_re=dash_re[0];
1149       cg_wave_raw_im=dash_im[0];
1150       cg_wave_midpoint=msig[ia+1].pos;
1151       insert_item(CW_DASH);
1152       cw_ptr++;
1153       break;
1154 
1155       case 5:
1156 //  ****-___--?????_-****   lguess 5
1157 //      ia^
1158 //        0123
1159       cg_wave_raw_re=0;
1160       cg_wave_raw_im=0;
1161       cg_wave_midpoint=msig[ia].pos;
1162       insert_item(CW_SPACE);
1163       cw_ptr++;
1164       if(gap==8)goto gap8_add_dash;
1165       break;
1166 
1167       case 6:
1168 //  ****-_-_--?????_-****   lguess 6
1169 //      ia^
1170 //        0123
1171       cg_wave_raw_re=dot_re[0];
1172       cg_wave_raw_im=dot_im[0];
1173       cg_wave_midpoint=msig[ia].pos;
1174       insert_item(CW_DOT);
1175       cw_ptr++;
1176       if(gap==8)
1177         {
1178 gap8_add_dash:;
1179         cg_wave_raw_re=dash_re[1];
1180         cg_wave_raw_im=dash_im[1];
1181         cg_wave_midpoint=msig[ia+3].pos;
1182         insert_item(CW_DOT);
1183         cw_ptr++;
1184         }
1185       break;
1186 
1187       default:
1188       lirerr(634293);
1189       return 0;
1190       }
1191     switch (mhg)
1192       {
1193       case 0:
1194 //  ****-_?????____-****   hguess 0
1195 //             ib^
1196 //             210
1197       cg_wave_raw_re=0;
1198       cg_wave_raw_im=0;
1199       if(gap==8)
1200         {
1201         cg_wave_midpoint=msig[ib-1].pos;
1202         insert_item(CW_WORDSEP);
1203         }
1204       else
1205         {
1206         cg_wave_midpoint=msig[ib].pos;
1207         insert_item(CW_SPACE);
1208         }
1209       cw_ptr++;
1210       break;
1211 
1212       case 1:
1213 //  ****-_?????-___-****   hguess 1
1214 //             ib^
1215 //             210
1216       if(gap==8)
1217         {
1218         cg_wave_raw_re=dot_re[ib-ia-2];
1219         cg_wave_raw_im=dot_im[ib-ia-2];
1220         cg_wave_midpoint=msig[ib-2].pos;
1221         insert_item(CW_DOT);
1222         cw_ptr++;
1223         }
1224       cg_wave_raw_re=0;
1225       cg_wave_raw_im=0;
1226       cg_wave_midpoint=msig[ib].pos;
1227       insert_item(CW_SPACE);
1228       cw_ptr++;
1229       break;
1230 
1231 
1232       case 2:
1233 //  ****-_?????__-_-****   hguess 2
1234 //             ib^
1235 //             210
1236       if(gap==8)
1237         {
1238         cg_wave_raw_re=0;
1239         cg_wave_raw_im=0;
1240         cg_wave_midpoint=msig[ib-2].pos;
1241         insert_item(CW_SPACE);
1242         cw_ptr++;
1243         }
1244       cg_wave_raw_re=dot_re[ib-ia];
1245       cg_wave_raw_im=dot_im[ib-ia];
1246       cg_wave_midpoint=msig[ib].pos;
1247       insert_item(CW_DOT);
1248       cw_ptr++;
1249       break;
1250 
1251       case 3:
1252 //  ****-_?????-_-_-****   hguess 3
1253 //             ib^
1254 //             210
1255       if(gap==8)
1256         {
1257         cg_wave_raw_re=dot_re[ib-ia-2];
1258         cg_wave_raw_im=dot_im[ib-ia-2];
1259         cg_wave_midpoint=msig[ib-2].pos;
1260         insert_item(CW_DOT);
1261         cw_ptr++;
1262         }
1263       cg_wave_raw_re=dot_re[ib-ia];
1264       cg_wave_raw_im=dot_im[ib-ia];
1265       cg_wave_midpoint=msig[ib].pos;
1266       insert_item(CW_DOT);
1267       cw_ptr++;
1268       break;
1269 
1270       case 4:
1271 //  ****-_?????---_-****   hguess 4
1272 //             ib^
1273 //             210
1274       cg_wave_raw_re=dash_re[2];
1275       cg_wave_raw_im=dash_im[2];
1276       cg_wave_midpoint=msig[ib-1].pos;
1277       insert_item(CW_DASH);
1278       cw_ptr++;
1279       break;
1280 
1281       default:
1282       lirerr(634294);
1283       return 0;
1284       }
1285     added_parts+=cw_ptr-iptr;
1286     iptr=cw_ptr;
1287  skip_guesses:;
1288     cw_ptr=iptr;
1289     goto region_guesses;
1290     }
1291   }
1292 
1293 cw_detect_flag=CWDETECT_DEBUG_STOP;
1294 show_cw("  char guesses finished ");
1295 return added_parts;
1296 }
1297 
1298 
1299 
1300 
1301 
make_baseb_sho1(void)1302 void make_baseb_sho1(void)
1303 {
1304 int i,k;
1305 k=2*baseband_size;
1306 for(i=0; i<k; i++)baseb_sho1[i]=baseb_tmp[i]*0.5;
1307 }
1308 
make_baseb_sho2(void)1309 void make_baseb_sho2(void)
1310 {
1311 int i,k;
1312 k=2*baseband_size;
1313 for(i=0; i<k; i++)baseb_sho2[i]=baseb_fit[i]*0.5;
1314 }
1315 
correlated_detect(void)1316 void correlated_detect(void)
1317 {
1318 int pa;
1319 int ia, ka;
1320 char s[80];
1321 // Check the detected dots and dashes against the average waveform.
1322 ka=corr[0].pos;
1323 pa=-1;
1324 for(cw_ptr=0; cw_ptr<no_of_cwdat; cw_ptr++)
1325   {
1326   ia=((int)(cw[cw_ptr].midpoint+0.5)-ka+baseband_size)&baseband_mask;
1327   if(ia > baseband_sizhalf)goto outside;
1328   ia=(ia-corr_len+baseband_size)&baseband_mask;
1329   if(ia < baseband_sizhalf)goto outside;
1330   if(pa < 0)pa=cw_ptr;
1331   switch (cw[cw_ptr].type)
1332     {
1333     case CW_DASH:
1334     sprintf(s,"dash   ");
1335     break;
1336 
1337     case CW_DOT:
1338     sprintf(s,"dot    ");
1339     break;
1340 
1341     case CW_SPACE:
1342     sprintf(s,"space  ");
1343     break;
1344 
1345     case CW_WORDSEP:
1346     sprintf(s,"wordsep");
1347     break;
1348 
1349     default:
1350     sprintf(s,"{%3d} %c",cw[cw_ptr].type,cw[cw_ptr].type);
1351     break;
1352     }
1353   DEB"\n%s %5d [%8.3f]%8.3f %2d %3d   (%f  %f)",
1354                      s,cw_ptr,cw[cw_ptr].midpoint,cw[cw_ptr].sep,cw[cw_ptr].len,cw[cw_ptr].unkn,
1355                     ZZ*cw[cw_ptr].coh_re,ZZ*cw[cw_ptr].coh_im);
1356 outside:;
1357   }
1358 }
1359 
find_best_region(void)1360 int find_best_region(void)
1361 {
1362 int i, j, k, m;
1363 int ia, ib;
1364 float t1,da;
1365 // Locate the best region by use of the amplitudes stored in cw[].tmp
1366 j=0;
1367 t1=0;
1368 for(i=0; i<no_of_cwdat; i++)
1369   {
1370   if(cw[i].tmp > t1)
1371     {
1372     j=i;
1373     t1=cw[i].tmp;
1374     }
1375   }
1376 if(best_corr_ampl==0)
1377   {
1378   best_corr_ampl=t1;
1379   }
1380 else
1381   {
1382   if(t1 < 0.33*best_corr_ampl)
1383     {
1384 PRT10"\n-----------  exit -------------");
1385     return FALSE;
1386     }
1387   }
1388 // Decide what length to use for correlation.
1389 ia=j;
1390 ib=j;
1391 k=no_of_cwdat-1;
1392 t1*=.25;
1393 m=0;
1394 get_corrlen:;
1395 da=cw[ib].midpoint-cw[ia].midpoint;
1396 if(da < 0)da+=baseband_size;
1397 if(da < MIN_CORRELATE_SEP*cwbit_pts)
1398   {
1399   if(ia > 0)
1400     {
1401     if(ib < k)
1402       {
1403       if(cw[ia-1].tmp > cw[ib+1].tmp)
1404         {
1405         goto iadec;
1406         }
1407       else
1408         {
1409         goto ibinc;
1410         }
1411       }
1412     else
1413       {
1414       goto iadec;
1415       }
1416     }
1417   else
1418     {
1419     if(ib < k)
1420       {
1421       goto ibinc;
1422       }
1423     }
1424 iadec:;
1425   if(cw[ia-1].tmp > t1)
1426     {
1427     ia--;
1428     m=-1;
1429     goto get_corrlen;
1430     }
1431   goto corrlen_x;
1432 ibinc:;
1433   if(cw[ib+1].tmp > t1)
1434     {
1435     m=1;
1436     ib++;
1437     goto get_corrlen;
1438     }
1439   }
1440 corrlen_x:;
1441 best_corr_ia=((int)(cw[ia].midpoint-3*cwbit_pts)+baseband_size)&baseband_mask;
1442 best_corr_ib=((int)(cw[ib].midpoint+3*cwbit_pts))&baseband_mask;
1443 i=(best_corr_ib-best_corr_ia+baseband_size)&baseband_mask;
1444 i-=MIN_CORRELATE_SEP*cwbit_pts;
1445 if(i > 0)
1446   {
1447   if(m>0)
1448     {
1449     ib--;
1450     best_corr_ib=(best_corr_ib-i+baseband_size)&baseband_mask;
1451     }
1452   else
1453     {
1454     ia++;
1455     best_corr_ia=(best_corr_ia+i)&baseband_mask;
1456     }
1457   }
1458 corr_len=(best_corr_ib-best_corr_ia+baseband_size)&baseband_mask;
1459 // best_corr_ia and best_corr_ib are pointers in the baseband.
1460 // Clear cw[].tmp for points within the region ia to ib so we
1461 // will not try to correlate the same region again.
1462 ib++;
1463 while(ia != ib)
1464   {
1465   cw[ia].tmp=0;
1466   ia++;
1467   }
1468 return TRUE;
1469 }
1470 
compute_region_quality(void)1471 void compute_region_quality(void)
1472 {
1473 int i, ia, ib;
1474 float amp, da, db, t1, trilen;
1475 //
1476 // Good regions contain several dashes and or dots within a time
1477 // frame corresponding to a morse character.
1478 // Store a triangle of width +/- CW_CORRELATE_GOODLEN norse code units
1479 // around each part.
1480 // Make the height A or 3*A for dots and dashes respectively
1481 // where A is the signal amplitude.
1482 // Good regions are characterised by sucessful detection of the
1483 // carrier so we use cw[].coh_re for the amplitude A.
1484 trilen=CW_CORRELATE_GOODLEN*cwbit_pts;
1485 for(i=0; i<no_of_cwdat; i++)
1486   {
1487   cw[i].tmp=0;
1488   }
1489 for(i=0; i<no_of_cwdat; i++)
1490   {
1491   if(cw[i].type==CW_DOT)
1492     {
1493     amp=1;
1494     }
1495   else
1496     {
1497     if(cw[i].type==CW_DASH)
1498       {
1499       amp=3;
1500       }
1501     else
1502       {
1503       goto keyup;
1504       }
1505     }
1506   amp*=cw[i].coh_re;
1507   cw[i].tmp+=amp;
1508   amp/=trilen;
1509   ia=i-1;
1510   ib=i+1;
1511   da=0.5*cw[i].len;
1512   db=da;
1513   while(ia >=0 && da<trilen)
1514     {
1515     da+=0.5*(cw[ia+1].len+cw[ia].len)+cw[ia+1].unkn;
1516     t1=trilen-da;
1517     if(t1>0)
1518       {
1519       cw[ia].tmp+=t1*amp;
1520       }
1521     ia--;
1522     }
1523   while(ib < no_of_cwdat && db<trilen)
1524     {
1525     db+=0.5*(cw[ib].len+cw[ib-1].len)+cw[ib].unkn;
1526     t1=trilen-db;
1527     if(t1>0)
1528       {
1529       cw[ib].tmp+=t1*amp;
1530       }
1531     ib++;
1532     }
1533 keyup:;
1534   }
1535 }
1536 
find_good_regions(void)1537 void find_good_regions(void)
1538 {
1539 int i, j, k, m, ia, ib, ja, jb, corr_step, clrlen;
1540 int first_corr, last_corr;
1541 float t1, t2, maxval;
1542 double dt2;
1543 // Our data does not change very rapidly. The shortest signal
1544 // duration of interest is cwbit_pts/2, the approximate time for
1545 // the separation between the 3 dB points of a Morse code dot.
1546 // Search for correlations using a step size of cwbit_pts/2;
1547 corr_step=0.5*(cwbit_pts+1);
1548 ja=baseb_px/corr_step;
1549 baseb_tmp[ja]=0;
1550 ia=ja*corr_step;
1551 corr[1].val=0;
1552 corr[1].pos=-1;
1553 getcorr_ia:;
1554 ia+=corr_step;
1555 ja++;
1556 if(ia > baseband_mask)
1557   {
1558   ia=0;
1559   ja=0;
1560   }
1561 k=(best_corr_ia-ia-corr_len+baseband_size)&baseband_mask;
1562 if(k<baseband_neg)
1563   {
1564   dt2=0;
1565   j=best_corr_ia;
1566   k=ia;
1567   while(j != best_corr_ib)
1568     {
1569     dt2+=baseb[2*j]*baseb[2*k];
1570     j=(j+1)&baseband_mask;
1571     k=(k+1)&baseband_mask;
1572     }
1573   t2=dt2*OVFL_PROTECT;
1574   if(corr[1].val < t2)
1575     {
1576     corr[1].pos=ja;
1577     corr[1].val=t2;
1578     }
1579   baseb_tmp[ja]=t2;
1580   goto getcorr_ia;
1581   }
1582 jb=best_corr_ib/corr_step;
1583 m=baseband_mask/corr_step;
1584 while(ja != jb)
1585   {
1586   baseb_tmp[ja]=0;
1587   ja++;
1588   if(ja > m)
1589     {
1590     ja=0;
1591     }
1592   }
1593 ib=jb*corr_step;
1594 getcorr_ib:;
1595 k=(baseb_pc-ib-corr_len+baseband_size)&baseband_mask;
1596 if(k<baseband_sizhalf)
1597   {
1598   dt2=0;
1599   j=best_corr_ia;
1600   k=ib;
1601   while(j != best_corr_ib)
1602     {
1603     dt2+=baseb[2*j]*baseb[2*k];
1604     j=(j+1)&baseband_mask;
1605     k=(k+1)&baseband_mask;
1606     }
1607   t2=dt2*OVFL_PROTECT;
1608   if(corr[1].val < t2)
1609     {
1610     corr[1].pos=jb;
1611     corr[1].val=t2;
1612     }
1613   baseb_tmp[jb]=t2;
1614   ib+=corr_step;
1615   jb++;
1616   if(ib > baseband_mask)
1617     {
1618     ib=0;
1619     jb=0;
1620     }
1621   goto getcorr_ib;
1622   }
1623 baseb_tmp[jb]=0;
1624 // If all the data is zero, return here.
1625 if(corr[1].pos ==-1)return;
1626 // Make sure that the very first point does not create a maximum
1627 // from either end.
1628 jb=jb-1;
1629 if(jb<0)jb=m;
1630 k=jb-1;
1631 if(k<0)k=m;
1632 while(baseb_tmp[k] !=0 && baseb_tmp[k] <= baseb_tmp[jb])
1633   {
1634   baseb_tmp[jb]=0;
1635   jb=k;
1636   k--;
1637   if(k<0)k=m;
1638   }
1639 last_corr=jb;
1640 ja=baseb_px/corr_step;
1641 ja++;
1642 if(ja>0)ja=0;
1643 k=ja+1;
1644 if(k>m)k=0;
1645 while(baseb_tmp[k] !=0 && baseb_tmp[k] <= baseb_tmp[ja])
1646   {
1647   baseb_tmp[ja]=0;
1648   ja=k;
1649   k++;
1650   if(k>m)k=0;
1651   }
1652 first_corr=ja;
1653 clrlen=1+corr_len/(4*corr_step);
1654 // Clear baseb_tmp in the surroundings of the current maximum.
1655 // Then search for the largest value in baseb_tmp.
1656 // This way corr[].pos and corr_val[] will contain correlation
1657 // maxima in descending order by corr_val.
1658 no_of_corr=1;
1659 while( no_of_corr < MAX_CORRSUM-1 && corr[no_of_corr].pos != -1)
1660   {
1661 // First just clear 2*clrlen points.
1662   i=corr[no_of_corr].pos-clrlen;
1663   if(i<0)i=m;
1664   k=corr[no_of_corr].pos+clrlen;
1665   if(k>m)k=0;
1666   j=i;
1667   while(i != k)
1668     {
1669     baseb_tmp[i]=0;
1670     i++;
1671     if(i>m)i=0;
1672     }
1673 // Clear points upwards to avoid that the first point becomes a maximum.
1674    i=k+1;
1675    if(i>m)i=0;
1676    while(baseb_tmp[i] !=0 && baseb_tmp[i] <= baseb_tmp[k])
1677     {
1678     baseb_tmp[k]=0;
1679     k=i;
1680     i++;
1681     if(i>m)i=0;
1682     }
1683   j--;
1684   if(j<0)j=m;
1685   k=j-1;
1686   if(k<0)k=m;
1687   while(baseb_tmp[k] !=0 && baseb_tmp[k] <= baseb_tmp[j])
1688     {
1689     baseb_tmp[j]=0;
1690     j=k;
1691     k--;
1692     if(k<0)k=m;
1693     }
1694   no_of_corr++;
1695   corr[no_of_corr].val=0;
1696   corr[no_of_corr].pos=-1;
1697   ia=first_corr;
1698   while(ia != last_corr)
1699     {
1700     if(baseb_tmp[ia] > corr[no_of_corr].val)
1701       {
1702       corr[no_of_corr].val=baseb_tmp[ia];
1703       corr[no_of_corr].pos=ia;
1704       }
1705     ia++;
1706     if(ia>m)ia=0;
1707     }
1708   if(corr[no_of_corr].val < 0.5*corr[1].val)corr[no_of_corr].pos=-1;
1709   }
1710 while(no_of_corr<MAX_CORRSUM-1)
1711   {
1712   no_of_corr++;
1713   corr[no_of_corr].pos=-1;
1714   corr[no_of_corr].val=0;
1715   }
1716 if(PR10 != 0)
1717   {
1718   for(i=1; i<MAX_CORRSUM; i++)
1719     {
1720     DEB"\nNo:%d  pos:%d val %f",i,corr[i].pos*corr_step,corr[i].val);
1721     }
1722   }
1723 // Now we know points where correlation has maxima,
1724 // but we know the points within corr_step points only.
1725 // Make a finer search so we get the optimum within a single point
1726 // and include the complex part this time.
1727 // Accumulate the summed baseband function in baseb_tmp.
1728 i=best_corr_ia;
1729 while(i != best_corr_ib)
1730   {
1731   baseb_tmp[2*i  ]=baseb[2*i  ];
1732   baseb_tmp[2*i+1]=baseb[2*i+1];
1733   i=(i+1)&baseband_mask;
1734   }
1735 // Make the best region itself region 0
1736 corr[0].pos=(best_corr_ia+(corr_step>>1))/corr_step;
1737 no_of_corr=0;
1738 corr[0].sep=0;
1739 maxval=0;
1740 accumulate_corr:;
1741 ia=((corr[no_of_corr].pos-1)*corr_step+baseband_mask)&baseband_mask;
1742 ib=((corr[no_of_corr].pos+1)*corr_step+2)&baseband_mask;
1743 corr[no_of_corr].val=0;
1744 while(ia!=ib)
1745   {
1746   dt2=0;
1747   i=best_corr_ia;
1748   k=ia;
1749 // Correlate to the summed function in baseb_tmp
1750   while(i != best_corr_ib)
1751     {
1752     dt2+=baseb_tmp[2*i]*baseb[2*k]+baseb_tmp[2*i+1]*baseb[2*k+1];
1753     i=(i+1)&baseband_mask;
1754     k=(k+1)&baseband_mask;
1755     }
1756   t2=dt2*OVFL_PROTECT;
1757   if(corr[no_of_corr].val < t2)
1758     {
1759     corr[no_of_corr].pos=ia;
1760     corr[no_of_corr].val=t2;
1761     }
1762   ia=(ia+1)&baseband_mask;
1763   }
1764 if(no_of_corr==0)
1765   {
1766 PRT10"\nCorr no:%d  pos:%d val %f  maxval %f",
1767             no_of_corr,corr[no_of_corr].pos,corr[no_of_corr].val,maxval);
1768   goto noadd;
1769   }
1770 if(no_of_corr==1)
1771   {
1772 PRT10"\nCorr no:%d  pos:%d val %f  maxval %f",
1773             no_of_corr,corr[no_of_corr].pos,corr[no_of_corr].val,maxval);
1774   corr[1].sep=(corr[1].pos-best_corr_ia+baseband_size)&baseband_mask;
1775   if(corr[1].sep>(baseband_size>>1))corr[1].sep=
1776                                (baseband_size-corr[1].sep)&baseband_mask;
1777 
1778 PRT10"  sep%d",corr[1].sep);
1779   }
1780 
1781 // Check if this point has an integer relation to previously esteblished
1782 // repeat separations.
1783 if(no_of_corr > 1)
1784   {
1785   corr[no_of_corr].val*=corr[0].val/maxval;
1786 PRT10"\nCorr no:%d  pos:%d val %f  maxval %f",
1787             no_of_corr,corr[no_of_corr].pos,corr[no_of_corr].val,maxval);
1788   corr[no_of_corr].sep=(corr[no_of_corr].pos-best_corr_ia
1789                                                +baseband_size)&baseband_mask;
1790   if(corr[no_of_corr].sep>(baseband_size>>1))corr[no_of_corr].sep=
1791                         (baseband_size-corr[no_of_corr].sep)&baseband_mask;
1792 PRT10"  sep%d", corr[no_of_corr].sep);
1793 
1794   t1=(float)(corr[no_of_corr].sep)/corr[1].sep;
1795 PRT10"\nt1=%f",t1);
1796   if(corr[no_of_corr].val < 0.4*corr[0].val)
1797     {
1798     PRT10"  skip for small corr_value.");
1799     goto skip_corr;
1800     }
1801   if(!(fabs(t1-1.0) < 0.015 ||
1802        fabs(t1-2.0) < 0.02 ||
1803        fabs(t1-3.0) < 0.03 ||
1804        fabs(t1-0.5) < 0.01 ||
1805        fabs(t1-1.5) < 0.015 ||
1806        fabs(t1-0.33333333) < 0.01 ||
1807        fabs(t1-0.66666666) < 0.015 ||
1808        fabs(t1-1.33333333) < 0.015 ||
1809        fabs(t1-1.66666666) < 0.015))
1810     {
1811 PRT10"  skip for non-integer ratio.");
1812 skip_corr:;
1813     i=no_of_corr+1;
1814     while(i<MAX_CORRSUM)
1815       {
1816       corr[i-1].pos=corr[i].pos;
1817       corr[i-1].val=corr[i].val;
1818       i++;
1819       }
1820     corr[MAX_CORRSUM-1].pos=-1;
1821     corr[MAX_CORRSUM-1].val=0;
1822     goto next_corr;
1823     }
1824   }
1825 i=best_corr_ia;
1826 k=corr[no_of_corr].pos;
1827 while(i!=best_corr_ib)
1828   {
1829   baseb_tmp[2*i  ]+=baseb[2*k  ];
1830   baseb_tmp[2*i+1]+=baseb[2*k+1];
1831   i=(i+1)&baseband_mask;
1832   k=(k+1)&baseband_mask;
1833   }
1834 noadd:;
1835 maxval+=corr[no_of_corr].val;
1836 no_of_corr++;
1837 next_corr:;
1838 if( corr[no_of_corr].pos != -1 && no_of_corr<MAX_CORRSUM) goto accumulate_corr;
1839 PRT10"\nNO_OF_CORR %d",no_of_corr);
1840 }
1841 
1842 
1843 
1844 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1845 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1846 // !!
1847 // !!                          WORK AREA
1848 // !!
1849 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1850 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1851 
1852 
1853 
correlate_undecoded_baseband(void)1854 void correlate_undecoded_baseband(void)
1855 {
1856 int region, region_flag;
1857 int i,j,k,ia,ib,ja,jb;
1858 int ka,kb,k1,k2,k3;
1859 int mix2_mask, sizhalf, carrfilter_pts;
1860 //float amp,t1,t2,t3,r1,r2;
1861 float amp,t1,t2,t3,r2;
1862 double dt1, dt2, dt3;
1863 sizhalf=mix2.size>>1;
1864 mix2_mask=mix2.size-1;
1865 // The standard procedure for detect has failed but there is
1866 // probably a signal present because we have decoded many dots
1867 // and dashes although not well enough to identify a single character.
1868 // First find a few particularly good regions, then compute
1869 // the auto-correlation function to see if the pattern repeats.
1870 compute_region_quality();
1871 best_corr_ampl=0;
1872 DEB"\n-----------  start correlate undecoded -------------");
1873 goto zzb;
1874 retry_correlation:;
1875 DEB"\n----------   retry correlate undecoded -------------");
1876 zzb:;
1877 if(find_best_region() == FALSE)return;
1878 find_good_regions();
1879 if(no_of_corr==0)goto retry_correlation;
1880 // The average waveform we now have in baseb_tmp would be correct
1881 // and it would have S/N better by a factor of no_of_corr compared to an
1882 // individual waveform if AND ONLY IF the phase of the carrier
1883 // were correct and the signal level were constant.
1884 //
1885 // Real signals typically suffer from multipath propagation and
1886 // as a result there is fading, QSB. When the amplitude goes
1887 // through a minimum, the phase may twist rapidly and the
1888 // carrier phase is very uncertain at such times. Whether a
1889 // 180 degree phase shift goes over 90 or 270 degrees may depend
1890 // on the noise only and the very weak signal close to the
1891 // minimum might come out from our coherent detection procedure
1892 // with the wrong phase. Actually with a random phase.
1893 //
1894 // Coherent averaging improves S/N for reasonably good signals,
1895 // good enough to give good S/N for the carrier, but the price
1896 // to pay is that poor signals average out to nothing.
1897 //
1898 // Here we have some good coherently averaged signals in baseb_tmp.
1899 // We will use them to improve the carrier phase.
1900 //
1901 // Compute the optimum position with decimals for each sequence
1902 // from the correlation with the summed curve. Store in corr_val[]
1903 j=0;
1904 while(j<no_of_corr)
1905   {
1906   ia=corr[j].pos;
1907   dt1=0;
1908   dt2=0;
1909   dt3=0;
1910   i=best_corr_ia;
1911   k1=(ia+baseband_mask)&baseband_mask;
1912   k2=ia;
1913   k3=(ia+1)&baseband_mask;
1914   while(i != best_corr_ib)
1915     {
1916     dt1+=baseb_tmp[2*i]*baseb[2*k1]+baseb_tmp[2*i+1]*baseb[2*k1+1];
1917     dt2+=baseb_tmp[2*i]*baseb[2*k2]+baseb_tmp[2*i+1]*baseb[2*k2+1];
1918     dt3+=baseb_tmp[2*i]*baseb[2*k3]+baseb_tmp[2*i+1]*baseb[2*k3+1];
1919     k1=k2;
1920     k2=k3;
1921     i=(i+1)&baseband_mask;
1922     k3=(k3+1)&baseband_mask;
1923     }
1924   t1=dt1*OVFL_PROTECT;
1925   t2=dt2*OVFL_PROTECT;
1926   t3=dt3*OVFL_PROTECT;
1927   if(t1 > t2 && t3 > t1)
1928     {
1929 // If the middle point is a local minimum, something is very wrong.
1930 // Then skip this waveform.
1931 skipit:;
1932     i=j;
1933     while(i < no_of_corr-1)
1934       {
1935       corr[i].pos=corr[i+1].pos;
1936       i++;
1937       }
1938     no_of_corr--;
1939     goto shiftfind_x;
1940     }
1941   if(t1 > t2)
1942     {
1943     t3=t2;
1944     t2=t1;
1945     ia=corr[j].pos;
1946     ia=(ia+baseband_mask)&baseband_mask;
1947     corr[j].pos=ia;
1948     dt1=0;
1949     i=best_corr_ia;
1950     k1=(ia+baseband_mask)&baseband_mask;
1951     while(i != best_corr_ib)
1952       {
1953       dt1+=baseb_tmp[2*i]*baseb[2*k1]+baseb_tmp[2*i+1]*baseb[2*k1+1];
1954       i=(i+1)&baseband_mask;
1955       k1=(k1+1)&baseband_mask;
1956       }
1957     t1=dt1*OVFL_PROTECT;
1958     if(t1>t2)goto skipit;
1959     }
1960   if(t3 > t2)
1961     {
1962     t1=t2;
1963     t2=t3;
1964     ia=corr[j].pos;
1965     ia=(ia+1)&baseband_mask;
1966     corr[j].pos=ia;
1967     dt3=0;
1968     i=best_corr_ia;
1969     k3=(ia+1)&baseband_mask;
1970     while(i != best_corr_ib)
1971       {
1972       dt3+=baseb_tmp[2*i]*baseb[2*k3]+baseb_tmp[2*i+1]*baseb[2*k3+1];
1973       i=(i+1)&baseband_mask;
1974       k3=(k3+1)&baseband_mask;
1975       }
1976     t3=dt3*OVFL_PROTECT;
1977     if(t3>t2)goto skipit;
1978     }
1979   parabolic_fit(&amp,&corr[j].fpos,t1*t1,t2*t2,t3*t3);
1980   corr[j].fpos+=ia;
1981   j++;
1982 shiftfind_x:;
1983   }
1984 if(no_of_corr < 2)goto retry_correlation;
1985 // Shift our pos references for corr[0].pos to become equal to best_corr_ia.
1986 // Then increase the separation between corr[].fpos and corr[].pos
1987 // by a factor no_of_corr/(no_of_corr-1) to compensate to some extent
1988 // for the fact that correlation contains a component of the
1989 // signal to itself.
1990 t1=corr[0].fpos-best_corr_ia;
1991 t3=(float)(no_of_corr)/(no_of_corr-1);
1992 for(i=0; i<no_of_corr; i++)
1993   {
1994   t2=corr[i].fpos-t1;
1995   if(t2 < 0)t2+=baseband_size;
1996   if(t2 > baseband_size)t2-=baseband_size;
1997   t2=corr[i].pos-t2;
1998   t2*=t3;
1999   corr[i].fpos=corr[i].pos-t2;
2000   if(corr[i].fpos < 0)corr[i].fpos+=baseband_size;
2001   if(corr[i].fpos > baseband_size)corr[i].fpos-=baseband_size;
2002   corr[i].pos=((int)(corr[i].fpos+0.5))&baseband_mask;
2003   corr[i].sep=(corr[i].pos-baseb_px+baseband_size)&baseband_mask;
2004   }
2005 // Reorder the regions from ascending order of .val (quality)
2006 // to .sep (now time = distance to baseb_px)
2007 for(i=0; i<no_of_corr-1; i++)
2008   {
2009   for(j=i; j<no_of_corr; j++)
2010     {
2011     if(corr[i].sep > corr[j].sep)
2012       {
2013       tmpcorr=corr[i];
2014       corr[i]=corr[j];
2015       corr[j]=tmpcorr;
2016       }
2017     }
2018   }
2019 // Make corr[].sep the distance between consecutive regions.
2020 corr[0].sep=0;
2021 for(i=1; i<no_of_corr; i++)
2022   {
2023   corr[i].sep=corr[i].fpos-corr[i-1].fpos+0.5;
2024   }
2025 // Find out what the real repeat separation might be.
2026 k=baseband_size;
2027 for(i=1; i<no_of_corr; i++)
2028   {
2029   if(k > corr[i].sep)
2030     {
2031     k=corr[i].sep;
2032     }
2033   }
2034 // k is now the smallest repeat separation.
2035 // Divide k by 2 or 3 (or 6) in case it is required to make
2036 // the longer separations multiples of k.
2037 i=0;
2038 while(i<no_of_corr)
2039   {
2040   t1=(float)(corr[i].sep)/k;
2041   if(fabs(t1-1.5) < 0.05||
2042      fabs(t1-2.5) < 0.05)
2043     {
2044     k/=2;
2045     i=no_of_corr;
2046     }
2047   else
2048     {
2049     i++;
2050     }
2051   }
2052 i=0;
2053 while(i<no_of_corr)
2054   {
2055   t1=(float)(corr[i].sep)/k;
2056   if(fabs(t1-1.3333333333) < 0.05 ||
2057      fabs(t1-1.6666666666) < 0.05 ||
2058      fabs(t1-2.3333333333) < 0.05 )
2059     {
2060     k=(k+1)/3;
2061     i=no_of_corr;
2062     }
2063   else
2064     {
2065     i++;
2066     }
2067   }
2068 // Change k from being the repeat interval to become the max
2069 // number of points by which we may increase corr_len at both sides, but
2070 // do not allow corr_len to increase by more than a factor of three.
2071 k=(k-corr_len)/2;
2072 if(k>corr_len)k=corr_len;
2073 // Shift the start pointers by k downwards.
2074 // make sure we do not go below baseb_px.
2075 ia=0;
2076 for(i=0; i<no_of_corr; i++)
2077   {
2078   corr[i].fpos-=k;
2079   if(corr[i].fpos < 0)corr[i].fpos+=baseband_size;
2080   j=corr[i].fpos-baseb_px+baseband_mask;
2081   j&=baseband_mask;
2082   if(j > baseband_sizhalf)
2083     {
2084     j=baseband_size-j;
2085     if(j>ia)ia=j;
2086     }
2087   }
2088 for(i=0; i<no_of_corr; i++)
2089   {
2090   corr[i].fpos+=ia;
2091   if(corr[i].fpos >= baseband_size)corr[i].fpos-=baseband_size;
2092   corr[i].pos=corr[i].fpos+0.5;
2093   corr[i].pos&=baseband_mask;
2094   }
2095 k=corr_len+2*k-ia;
2096 // Make sure the last point is not above baseb_pc
2097 ib=0;
2098 for(i=0; i<no_of_corr; i++)
2099   {
2100   j=corr[i].fpos+k+1;
2101   j=(baseb_pc-j+baseband_size)&baseband_mask;
2102   if(j > baseband_sizhalf)
2103     {
2104     j=baseband_size-j;
2105     if(j>ib)ib=j;
2106     }
2107   }
2108 corr_len=k-ib;
2109 for(i=0; i<no_of_corr; i++)
2110   {
2111   corr[i].pos=((int)(corr[i].fpos+0.5))&baseband_mask;
2112   }
2113 
2114 //  !!!!!!!!!!!!!!!!!!!!!  for debug purposes !!!!!!!!!!!!!!!
2115 //  ö
2116 for(i=0;i<baseband_size/2;i+=2)
2117   {
2118   baseb_tmp[4*i  ]=-1/(ZZ*ZZ);
2119   baseb_tmp[4*i+1]=1/(ZZ*ZZ);
2120   baseb_tmp[4*i+2]=1;
2121   baseb_tmp[4*i+3]=1;
2122   baseb_tmp[4*i+4]=0;
2123   baseb_tmp[4*i+5]=0;
2124   baseb_tmp[4*i+6]=0;
2125   baseb_tmp[4*i+7]=0;
2126   baseb_fit[4*i  ]=-1/(ZZ*ZZ);
2127   baseb_fit[4*i+1]=1/(ZZ*ZZ);
2128   baseb_fit[4*i+2]=1;
2129   baseb_fit[4*i+3]=1;
2130   baseb_fit[4*i+4]=0;
2131   baseb_fit[4*i+5]=0;
2132   baseb_fit[4*i+6]=0;
2133   baseb_fit[4*i+7]=0;
2134   }
2135 
2136 // Use the detect information from all regions to select the time
2137 // intervals when the key is likely to have been pressed. Use the
2138 // same pattern for all regions.
2139 // store the gated raw data in baseb_fit.
2140 for(region=0; region<no_of_corr; region++)
2141   {
2142   ia=corr[region].pos;
2143   ib=(ia+corr_len)&baseband_mask;
2144   while(ia!=ib)
2145     {
2146     baseb_fit[2*ia  ]=0;
2147     baseb_fit[2*ia+1]=0;
2148     ia=(ia+1)&baseband_mask;
2149     }
2150   }
2151 region=0;
2152 ia=corr[region].pos;
2153 for(i=0; i<no_of_cwdat; i++)
2154   {
2155   if( cw[i].type == CW_DASH || cw[i].type == CW_DOT)
2156     {
2157 gate_part:;
2158     k=((int)(cw[i].midpoint)-ia+baseband_size)&baseband_mask;
2159     if(k<baseband_neg)
2160       {
2161       if(k>corr_len)
2162         {
2163         region++;
2164         if(region > no_of_corr)goto gate_x;
2165         ia=corr[region].pos;
2166         goto gate_part;
2167         }
2168       for(j=0; j<no_of_corr; j++)
2169         {
2170         if( cw[i].type == CW_DASH)
2171           {
2172           t1=1.5;
2173           }
2174         else
2175           {
2176           t1=0.5;
2177           }
2178         ja=cw[i].midpoint-t1*cwbit_pts;
2179         jb=cw[i].midpoint+t1*cwbit_pts;
2180         ja=(ja+corr[j].pos-corr[region].pos+baseband_size)&baseband_mask;
2181         jb=(jb+corr[j].pos-corr[region].pos+baseband_size)&baseband_mask;
2182         while(ja != jb)
2183           {
2184           baseb_fit[2*ja  ]=baseb_wb_raw[2*ja  ];
2185           baseb_fit[2*ja+1]=baseb_wb_raw[2*ja+1];
2186           ja=(ja+1)&baseband_mask;
2187           }
2188         }
2189       }
2190     }
2191   }
2192 gate_x:;
2193 // We use a mix2.size fft to filter out the carrier in the
2194 // frequency domain with a filter of the same width as used
2195 // before when extracting the carrier.
2196 // In case the carrier clearly is narrower we use a narrower filter.
2197 // We will use a sine squared window with 50 % overlap for the transforms.
2198 carrfilter_pts=1+(bg_flatpoints+2*bg_curvpoints)/bg.coh_factor;
2199 k3=carrfilter_pts/2+1;
2200 for(region=0; region<no_of_corr; region++)
2201   {
2202   ka=corr[region].pos;
2203   kb=(ka+corr_len)&baseband_mask;
2204   for(i=0; i<2*sizhalf; i++)mix2_tmp[i]=0;
2205   ia=ka;
2206   ka=(ka-sizhalf+baseband_size)&baseband_mask;
2207   for(i=sizhalf; i<(int)mix2.size; i++)
2208     {
2209     mix2_tmp[2*i  ]=baseb_fit[2*ia  ]*cw_carrier_window[i];
2210     mix2_tmp[2*i+1]=baseb_fit[2*ia+1]*cw_carrier_window[i];
2211     ia=(ia+1)&baseband_mask;
2212     }
2213   region_flag=1;
2214 new_carrier:;
2215   fftforward(mix2.size, mix2.n, mix2_tmp,
2216                                mix2.table, mix2.permute, yieldflag_ndsp_mix2);
2217 // Compute the power spectrum and locate the carrier.
2218 // The carrier has to be close to frequency=0 so we search a limited
2219 // range only (4 times the carrier filter).
2220   t1=0;
2221   t2=4;
2222   if(t2>0.5*bg.coh_factor)t2=0.5*bg.coh_factor;
2223   i=1+t2*carrfilter_pts;
2224   k=mix2.size-i-1;
2225   k2=i+1;
2226   k1=k;
2227   ia=2*k3-1;
2228   ib=(k2-k1-ia+mix2.size)&mix2_mask;
2229   while(i>=0)
2230     {
2231     t2=mix2_tmp[2*i  ]*mix2_tmp[2*i  ]+
2232        mix2_tmp[2*i+1]*mix2_tmp[2*i+1];
2233     mix2_pwr[i]=t2;
2234     if(t2 > t1)
2235       {
2236       j=i;
2237       t1=t2;
2238       }
2239     t2=mix2_tmp[2*k  ]*mix2_tmp[2*k  ]+
2240        mix2_tmp[2*k+1]*mix2_tmp[2*k+1];
2241     mix2_pwr[k]=t2;
2242     if(t2 > t1)
2243       {
2244       j=k;
2245       t1=t2;
2246       }
2247     i--;
2248     k++;
2249     }
2250   i=j;
2251   if(i>sizhalf)i-=mix2.size;
2252   if(abs(i) > k3)goto fail;
2253   i=k1;
2254   //  r1=0;
2255   r2=0;
2256   while(i!=k2)
2257     {
2258     k=(i-j+mix2.size)&mix2_mask;
2259     if(k>sizhalf)k=mix2.size-k;
2260     if(k<k3)
2261       {
2262 	//      r1+=mix2_pwr[i];
2263       }
2264     else
2265       {
2266       r2+=mix2_pwr[i];
2267       }
2268     i=(i+1)&mix2_mask;
2269     }
2270   //  r1/=ia;
2271   r2/=ib;
2272   ia=(j-k3+mix2.size)&mix2_mask;
2273   ib=(j+k3)&mix2_mask;
2274   if( (r2 != 0 && t1/r2 < 4) || t1 == 0)
2275     {
2276 fail:;
2277     t1=0;
2278     ia=0;
2279     ib=0;
2280     mix2_tmp[0]=0.1;
2281     mix2_tmp[1]=0;
2282     }
2283   else
2284     {
2285 // Our passband is from ia to ib. It is centered on the maximum power bin.
2286 // Try to shift the passband up or down to see if we can get more signal.
2287     for(i=k3; i>0; i--)
2288       {
2289       t2=0;
2290       k1=(ia+mix2_mask)&mix2_mask;
2291       k2=ib;
2292       j=i;
2293       while(j!=0)
2294         {
2295         t2+=mix2_pwr[k1]-mix2_pwr[k2];
2296         k1=(k1+mix2_mask)&mix2_mask;
2297         k2=(k2+mix2_mask)&mix2_mask;
2298         j--;
2299         }
2300       t3=0;
2301       k1=ia;
2302       k2=(ib+1)&mix2_mask;
2303       j=i;
2304       while(j!=0)
2305         {
2306         t3+=mix2_pwr[k2]-mix2_pwr[k1];
2307         k1=(k1+1)&mix2_mask;
2308         k2=(k2+1)&mix2_mask;
2309         j--;
2310         }
2311       if(t2 > t3)
2312         {
2313         if(t2 > 0)
2314           {
2315           ia=(ia-i+mix2.size)&mix2_mask;
2316           ib=(ib-i+mix2.size)&mix2_mask;
2317           }
2318         }
2319       else
2320         {
2321         if(t3 > 0)
2322           {
2323           ia=(ia+i)&mix2_mask;
2324           ib=(ib+i)&mix2_mask;
2325           }
2326         }
2327       }
2328 // Now that we have the optimum position for the passband,
2329 // see if there is a good reason to increase the bandwidth slightly.
2330 // The noise floor is r2 and the max signal is t1.
2331 // Look at both sides for a signal that is 9 dB or more above the noise.
2332 // The signal must also be less than 15 dB below the main signal.
2333     t3=r2*4;
2334     if(t3 < t1/32)t3=t1/32;
2335     for(i=1; i<k3; i++)
2336       {
2337       k1=(ia-i+mix2.size)&mix2_mask;
2338       k2=(ib+i)&mix2_mask;
2339       if(mix2_pwr[k1]>t3)
2340         {
2341         ia=k1;
2342         }
2343       if(mix2_pwr[k2]>t3)
2344         {
2345         ib=k2;
2346         }
2347       }
2348 // Now, use a 3 dB lower threshold and see if we can make the
2349 // filter narrower.
2350     t3/=2;
2351     while(mix2_pwr[ia] < t3)ia=(ia+1)&mix2_mask;
2352     while(mix2_pwr[ib] < t3)ib=(ib+mix2_mask)&mix2_mask;
2353     }
2354 // Now that we decided to use the frequencies from ia to ib, clear all
2355 // other frequencies in our buffer.
2356   ib=(ib+1)&mix2_mask;
2357   while(ib != ia)
2358     {
2359     mix2_tmp[2*ib  ]=0;
2360     mix2_tmp[2*ib+1]=0;
2361     ib=(ib+1)&mix2_mask;
2362     }
2363 // Go back to the time domain to get the carrier.
2364   fftback(mix2.size, mix2.n, mix2_tmp, mix2.table, mix2.permute, yieldflag_ndsp_mix2);
2365   if(region_flag < 3)
2366     {
2367     ia=(ka+sizhalf)&baseband_mask;
2368     for(i=sizhalf; i<(int)mix2.size; i++)
2369       {
2370       baseb_tmp[2*ia  ]=mix2_tmp[2*i  ];
2371       baseb_tmp[2*ia+1]=mix2_tmp[2*i+1];
2372       ia=(ia+1)&baseband_mask;
2373       }
2374     }
2375   else
2376     {
2377     if(region_flag ==  3)
2378       {
2379       ia=(ka+sizhalf)&baseband_mask;
2380       i=sizhalf;
2381       while(i<(int)mix2.size && ia != kb)
2382         {
2383         baseb_tmp[2*ia  ]=mix2_tmp[2*i  ];
2384         baseb_tmp[2*ia+1]=mix2_tmp[2*i+1];
2385         ia=(ia+1)&baseband_mask;
2386         i++;
2387         }
2388       }
2389     }
2390 
2391   if(region_flag == 2 || region_flag == 3)
2392     {
2393     ia=ka;
2394     for(i=0; i<sizhalf; i++)
2395       {
2396       baseb_tmp[2*ia  ]+=mix2_tmp[2*i  ];
2397       baseb_tmp[2*ia+1]+=mix2_tmp[2*i+1];
2398       ia=(ia+1)&baseband_mask;
2399       }
2400     }
2401   else
2402     {
2403     if(region_flag == 4)
2404       {
2405       ia=ka;
2406       i=0;
2407       while(i<sizhalf && ia != kb)
2408         {
2409         baseb_tmp[2*ia  ]+=mix2_tmp[2*i  ];
2410         baseb_tmp[2*ia+1]+=mix2_tmp[2*i+1];
2411         ia=(ia+1)&baseband_mask;
2412         i++;
2413         }
2414       }
2415     }
2416 // Prepare for a new section of the current region.
2417   ka=(ka+sizhalf)&baseband_mask;
2418   if( ((kb-ka-(int)mix2.size+baseband_size)&baseband_mask)< baseband_sizhalf)
2419     {
2420     region_flag=2;
2421     }
2422   else
2423     {
2424     region_flag++;
2425     }
2426   if( ((kb-ka+baseband_size)&baseband_mask)< baseband_sizhalf)
2427     {
2428     ia=ka;
2429     i=0;
2430     while(i<(int)mix2.size && ia != kb)
2431       {
2432       mix2_tmp[2*i  ]=baseb_fit[2*ia  ]*cw_carrier_window[i];
2433       mix2_tmp[2*i+1]=baseb_fit[2*ia+1]*cw_carrier_window[i];
2434       ia=(ia+1)&baseband_mask;
2435       i++;
2436       }
2437     while(i<(int)mix2.size)
2438       {
2439       mix2_tmp[2*i  ]=0;
2440       mix2_tmp[2*i+1]=0;
2441       ia=(ia+1)&baseband_mask;
2442       i++;
2443       }
2444     goto new_carrier;
2445     }
2446   }
2447 goto debug_x;
2448 
2449 // Use the positons with decimals to form the summed baseband
2450 // function over a larger time interval, the new corr_len.
2451 
2452 
2453 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2454 ia=corr[0].pos;
2455 ib=(ia+corr_len)&baseband_mask;
2456 while(ia!=ib)
2457   {
2458   baseb_tmp[2*ia  ]=0;
2459   baseb_tmp[2*ia+1]=0;
2460   ia=(ia+1)&baseband_mask;
2461   }
2462 for(i=0; i<no_of_corr; i++)
2463   {
2464   ia=corr[0].pos;
2465   ka=corr[i].pos;
2466   kb=(ka+1)&baseband_mask;
2467   t1=corr[i].fpos-ka;
2468   t2=1-t1;
2469   while(ia!=ib)
2470     {
2471     baseb_tmp[2*ia  ]+=t2*baseb[2*ka  ]+t1*baseb[2*kb  ];
2472     baseb_tmp[2*ia+1]+=t2*baseb[2*ka+1]+t1*baseb[2*kb+1];
2473     ia=(ia+1)&baseband_mask;
2474     ka=kb;
2475     kb=(kb+1)&baseband_mask;
2476     }
2477   }
2478 
2479 
2480 
2481 goto debug_x; //ö
2482 
2483 
2484 
2485 
2486 
2487 debug_x:;
2488 make_baseb_sho1();
2489 make_baseb_sho2();
2490 if(no_of_corr > 2)
2491   {
2492   cw_detect_flag=CWDETECT_DEBUG_STOP;//öö
2493   XZ("STOP!!");
2494   }
2495 return;//öööööööööööööööööööööööööööööööööööööööööööööööööööö
2496 
2497 
2498 
2499 
2500 // Use the carrier now present in baseb_tmp[] to compute a new
2501 // and hopefully more accurate coherently detected signal in baseb_fit[]
2502 // Accumulate the average waveform in baseb_envelope[].
2503 
2504 //  !!!!!!!!!!!!!!!!!!!!!  for debug purposes !!!!!!!!!!!!!!!
2505 //  ö  ö  ö
2506 for(i=0;i<baseband_size/2;i+=2)
2507   {
2508   baseb_envelope[4*i  ]=-1/(ZZ*ZZ);
2509   baseb_envelope[4*i+1]=1/(ZZ*ZZ);
2510   baseb_envelope[4*i+2]=1;
2511   baseb_envelope[4*i+3]=1;
2512   baseb_envelope[4*i+4]=0;
2513   baseb_envelope[4*i+5]=0;
2514   baseb_envelope[4*i+6]=0;
2515   baseb_envelope[4*i+7]=0;
2516   }
2517 // """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2518 
2519 ia=corr[0].pos;
2520 ib=(ia+corr_len)&baseband_mask;
2521 while(ia != ib)
2522   {
2523   baseb_envelope[2*ia  ]=0;
2524   baseb_envelope[2*ia+1]=0;
2525   ia=(ia+1)&baseband_mask;
2526   }
2527 for(region=0; region<no_of_corr; region++)
2528   {
2529   ia=corr[0].pos;
2530   ka=corr[region].pos;
2531 
2532 DEB"\nfinal:[%d] %d",region,ka);
2533 
2534   kb=(ka+corr_len)&baseband_mask;
2535   while(ka != kb)
2536     {
2537     t1=sqrt(baseb_tmp[2*ka  ]*baseb_tmp[2*ka  ]+
2538             baseb_tmp[2*ka+1]*baseb_tmp[2*ka+1]);
2539     if(t1!=0)
2540       {
2541       t2=baseb_tmp[2*ka  ]/t1;
2542       t3=baseb_tmp[2*ka+1]/t1;
2543       baseb_fit[2*ka  ]=t2*baseb_raw[2*ka  ]+t3*baseb_raw[2*ka+1];
2544       baseb_fit[2*ka+1]=t2*baseb_raw[2*ka+1]-t3*baseb_raw[2*ka  ];
2545       }
2546     else
2547       {
2548       baseb_fit[2*ka  ]=0;
2549       baseb_fit[2*ka+1]=0;
2550       }
2551     baseb_envelope[2*ia  ]+=0.3*baseb_fit[2*ka  ];
2552     baseb_envelope[2*ia+1]+=0.3*baseb_fit[2*ka+1];
2553     ka=(ka+1)&baseband_mask;
2554     ia=(ia+1)&baseband_mask;
2555     }
2556   }
2557 correlated_detect();
2558 
2559 
2560 show_cw("correlate end");
2561 
2562 
2563 
2564 
2565 
2566 
2567 return;
2568 goto retry_correlation;
2569 // set cw_detect_flag >40 if sucessful
2570 }
2571 
show_cw(char * caller)2572 void show_cw(char *caller)
2573 {
2574 int i;
2575 char s[80];
2576 DEB"\n**** show_cw: (%s) *****",caller);
2577 DEB"\n           N    [mid]      sep   l  unk  tmp           coh             raw");
2578 for(i=0; i<no_of_cwdat; i++)
2579   {
2580   switch (cw[i].type)
2581     {
2582     case CW_DASH:
2583     sprintf(s,"dash   ");
2584     break;
2585 
2586     case CW_DOT:
2587     sprintf(s,"dot    ");
2588     break;
2589 
2590     case CW_SPACE:
2591     sprintf(s,"space  ");
2592     break;
2593 
2594     case CW_WORDSEP:
2595     sprintf(s,"wordsep");
2596     break;
2597 
2598     default:
2599     sprintf(s,"{%3d} %c",cw[i].type,cw[i].type);
2600     break;
2601     }
2602   DEB"\n%s %5d [%8.2f]%8.2f %2d %3d %.4f  (%7.1f,%7.1f)  (%7.1f,%7.1f)  ",
2603                      s,i,cw[i].midpoint,cw[i].sep,cw[i].len,cw[i].unkn,
2604                 0.00001*ZZ*cw[i].tmp, ZZ*cw[i].coh_re,ZZ*cw[i].coh_im,
2605                           ZZ*cw[i].raw_re,ZZ*cw[i].raw_im);
2606   }
2607 DEB"\n");
2608 }
2609 
insert_item(int type)2610 void insert_item(int type)
2611 {
2612 int i, ja, jb, k, m;
2613 float t1,t2,r1,r2;
2614 check_cw(4001,1);
2615 if(kill_all_flag)return;
2616 r2=0;
2617 if(cw_ptr==0)
2618   {
2619   ja=0;
2620   r1=cg_wave_midpoint-baseb_px;
2621   }
2622 else
2623   {
2624   ja=cw[cw_ptr-1].len;
2625   r1=cg_wave_midpoint-cw[cw_ptr-1].midpoint;
2626   }
2627 if(r1 < 0)r1+=baseband_size;
2628 i=no_of_cwdat;
2629 while(i > cw_ptr)
2630   {
2631   cw[i]=cw[i-1];
2632   i--;
2633   }
2634 if(cw_ptr != no_of_cwdat)
2635   {
2636   r2=cw[cw_ptr].midpoint-cg_wave_midpoint;
2637   if(r2 < 0)r2+=baseband_size;
2638   cw[cw_ptr+1].sep=r2;
2639   jb=(cw[cw_ptr+1].len+cw[cw_ptr].len)/2;
2640   r2/=cwbit_pts;
2641   r2-=jb;
2642   if(r2 < 0)r2=0;
2643   k=(int)(r2)&0xfffffffe;
2644   if(r2-k > 1)k+=2;
2645   cw[cw_ptr+1].unkn=k;
2646   }
2647 cw[cw_ptr].midpoint=cg_wave_midpoint;
2648 cw[cw_ptr].type=type;
2649 cw[cw_ptr].coh_re=cg_wave_coh_re;
2650 cw[cw_ptr].coh_im=cg_wave_coh_im;
2651 if(cg_wave_raw_re == 0 && cg_wave_raw_im == 0)
2652   {
2653   m=cg_wave_midpoint+0.5;
2654   t1=baseb_carrier[2*m  ];
2655   t2=baseb_carrier[2*m+1];
2656   cg_wave_raw_re=cg_wave_coh_re*t1+cg_wave_coh_im*t2;
2657   cg_wave_raw_im=cg_wave_coh_im*t1-cg_wave_coh_re*t2;
2658   }
2659 cw[cw_ptr].raw_re=cg_wave_raw_re;
2660 cw[cw_ptr].raw_im=cg_wave_raw_im;
2661 cw[cw_ptr].len=cw_item_len[255-type];
2662 ja=(ja+cw[cw_ptr].len)/2;
2663 cw[cw_ptr].sep=r1;
2664 r1/=cwbit_pts;
2665 r1-=ja;
2666 k=(int)(r1)&0xfffffffe;
2667 if(r1-k > 1)k+=2;
2668 cw[cw_ptr].unkn=k;
2669 DEB"\ninsert[%f] type %s  len %d   sep[i] %.0f sep[i+1] %.0f",
2670          cg_wave_midpoint,cw_item_text[255-type],cw_item_len[255-type],r1,r2);
2671 no_of_cwdat++;
2672 if(no_of_cwdat > max_cwdat)lirerr(1189);
2673 check_cw(40011,1);
2674 }
2675 
2676 
second_detect(void)2677 void second_detect(void)
2678 {
2679 int k;
2680 float r1;
2681 // *****************************************************
2682 // *****************************************************
2683 // *****  Fit key up or key down patterns to short *****
2684 // *****  regions that are surrounded by dashes    *****
2685 // *****************************************************
2686 // *****************************************************
2687 // Look for the following cases:
2688 //  -_-_          2
2689 //  ---_-         3
2690 //  -_---         3
2691 //  -___-         4
2692 //  ---___-       5
2693 //  -___---       5
2694 //  -_____-       7
2695 //
2696 //    Code       Sep
2697 //  ---_---       4
2698 //  ---_-_---     6
2699 //  ---___---     6
2700 //  ---_-_-_---   8
2701 //  ---_---_---   8
2702 //  ---___-_---   8
2703 //  ---_-___---   8
2704 //  ---_____---   8
2705 //  ---_---_?_---   10
2706 //  ---_?_---_---   10
2707 //  ---_---_????....  default
2708 //  ....????_---_---  default
2709 
2710 // Look for the following cases:
2711 //    Code       Unkn
2712 //  |__|          2
2713 //  |-_|          2
2714 //  |____|        4
2715 //  |-___|        4
2716 //  |__-_|        4
2717 //  |-_-_|        4
2718 //  |---_|        4
2719 //  |______|      6
2720 //  |-_____|      6
2721 //  |__-___|      6
2722 //show_cw("second_detect enter");
2723 
2724 
2725 PRT02"\nsecond_detect: CWBIT PTS %f x",cwbit_pts);
2726 // Store the most probable signal in each case.
2727 //   name     data    length
2728 // CW_DASH    |---_|     4
2729 // CW_DOT     |-_|       2
2730 // CW_SPACE   |__|       2
2731 // CW_WORDSEP |____|     4
2732 // The item starts (length/2 + 0.5) below cw[].midpoint because
2733 // midpoint is the center of a key down period while the item
2734 // midpoint is 0.5 above that because one space is always
2735 // included in an item.
2736   PRT02"\n0 PRT02(2)>     [%7.1f] ", cw[0].midpoint);
2737 cw_ptr=1;
2738 
2739 while(cw_ptr < no_of_cwdat &&
2740       cw[cw_ptr].type==CW_DASH &&
2741       cw[cw_ptr-1].type==CW_DASH)
2742   {
2743   r1=cw[cw_ptr].sep/cwbit_pts;
2744   if( (cw[cw_ptr].type==CW_DASH && cw[cw_ptr-1].type==CW_DASH)||
2745       (cw[cw_ptr].type==CW_DOT && cw[cw_ptr-1].type==CW_DOT) )
2746     {
2747     k=(int)(r1)&0xfffffffe;
2748     if(r1-k > 1)k+=2;
2749     }
2750   else
2751     {
2752     if( (cw[cw_ptr].type==CW_DASH && cw[cw_ptr-1].type==CW_DOT)||
2753       (cw[cw_ptr].type==CW_DOT && cw[cw_ptr-1].type==CW_DASH) )
2754       {
2755       k=(int)(r1+1)&0xfffffffe;
2756       if(r1+1-k > 1)k+=2;
2757       k--;
2758 
2759 
2760 
2761 goto skip; // !!!!!  REMOVE !!!!!
2762 
2763 
2764       }
2765     else
2766       {
2767       goto skip;
2768       }
2769     }
2770   PRT02"\n%d PRT02(2)>k=%3d [%7.1f][%7.1f]",cw_ptr,k,cw[cw_ptr-1].midpoint,
2771                                                   cw[cw_ptr].midpoint);
2772   switch (k)
2773     {
2774     case 2:
2775     case 4:
2776 // We have two close spaced dashes.
2777 // There can be nothing in between.
2778     break;
2779 
2780     case 6:
2781 //  ---_-_---     6
2782 //  ---___---     6
2783 if(kill_all_flag)return;
2784     break;
2785 
2786     case 8:
2787 //  ---_-_-_---   8  ity=4
2788 //  ---_---_---   8  ity=1
2789 //  ---___-_---   8  ity=3
2790 //  ---_-___---   8  ity=2
2791 //  ---_____---   8  ity=5
2792 /*
2793       cg_wave_midpoint=dashpos1+t2*dashpos1_err;
2794       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
2795       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
2796       ia=cg_wave_midpoint;
2797       cg_wave_coh_re=t3*dash1_re+t2*baseb_envelope[2*ia  ];
2798       cg_wave_coh_im=t3*dash1_im+t2*baseb_envelope[2*ia+1];
2799       PRT04"\nstore_dash %f",cg_wave_midpoint);
2800       insert_item(CW_DASH);
2801 if(kill_all_flag)return;
2802       cw_ptr++;
2803 
2804       break;
2805 
2806       case 2:
2807 // Store dot1 and space
2808 //  ---_-___---   8  ity=2
2809 //  ---___-_---   8  ity=3
2810 //  ---_____---   8  ity=5
2811 //  ---_-_-_---   8  ity=4
2812       t3=0;
2813       if(dot_fit1 > DOT_DETECT_LIMIT && fabs(dotpos1_err) < 0.25*cwbit_pts)
2814         {
2815         if(dot1_chk < 0.25)
2816           {
2817           t3=0.75;
2818           }
2819         else
2820           {
2821           t3=0.5;
2822           }
2823         }
2824       t2=1-t3;
2825       cg_wave_midpoint=dotpos1+t2*dotpos1_err;
2826       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
2827       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
2828       ia=cg_wave_midpoint;
2829       cg_wave_coh_re=t3*dot1_re+t2*baseb_envelope[2*ia  ];
2830       cg_wave_coh_im=t3*dot1_im+t2*baseb_envelope[2*ia+1];
2831       PRT04"\nstore dot %f",cg_wave_midpoint);
2832       insert_item(CW_DOT);
2833 if(kill_all_flag)return;
2834       cw_ptr++;
2835       cg_wave_midpoint=dotpos2_nom;
2836       PRT04"\nstore_space %f",cg_wave_midpoint);
2837       insert_item(CW_SPACE);
2838 if(kill_all_flag)return;
2839       cw_ptr++;
2840       break;
2841 
2842       case 3:
2843 // Store space and dot2
2844 //  ---___-_---   8  ity=3
2845       cg_wave_midpoint=dotpos1_nom;
2846       PRT04"\nstore_space %f",cg_wave_midpoint);
2847       insert_item(CW_SPACE);
2848 if(kill_all_flag)return;
2849       cw_ptr++;
2850       t3=0;
2851       if(dot_fit2 > DOT_DETECT_LIMIT && fabs(dotpos2_err) < 0.25*cwbit_pts)
2852         {
2853         if(dot2_chk < 0.25)
2854           {
2855           t3=0.75;
2856           }
2857         else
2858           {
2859           t3=0.5;
2860           }
2861         }
2862       t2=1-t3;
2863       cg_wave_midpoint=dotpos2+t2*dotpos2_err;
2864       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
2865       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
2866       ia=cg_wave_midpoint;
2867       cg_wave_coh_re=t3*dot2_re+t2*baseb_envelope[2*ia  ];
2868       cg_wave_coh_im=t3*dot2_im+t2*baseb_envelope[2*ia+1];
2869       PRT04"\nstore dot %f",cg_wave_midpoint);
2870       insert_item(CW_DOT);
2871 if(kill_all_flag)return;
2872       cw_ptr++;
2873       break;
2874 
2875       case 4:
2876 // Store dot1 and dot2
2877 //  ---_-_-_---   8  ity=4
2878       t3=0;
2879       if(dot_fit1 > DOT_DETECT_LIMIT && fabs(dotpos1_err) < 0.25*cwbit_pts)
2880         {
2881         if(dot1_chk < 0.25)
2882           {
2883           t3=0.75;
2884           }
2885         else
2886           {
2887           t3=0.5;
2888           }
2889         }
2890       t2=1-t3;
2891       cg_wave_midpoint=dotpos1+t2*dotpos1_err;
2892       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
2893       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
2894       ia=cg_wave_midpoint;
2895       cg_wave_coh_re=t3*dot1_re+t2*baseb_envelope[2*ia  ];
2896       cg_wave_coh_im=t3*dot1_im+t2*baseb_envelope[2*ia+1];
2897       PRT04"\nstore dot %f",cg_wave_midpoint);
2898       insert_item(CW_DOT);
2899 if(kill_all_flag)return;
2900       cw_ptr++;
2901       t3=0;
2902       if(dot_fit2 > DOT_DETECT_LIMIT && fabs(dotpos2_err) < 0.25*cwbit_pts)
2903         {
2904         if(dot2_chk < 0.25)
2905           {
2906           t3=0.75;
2907           }
2908         else
2909           {
2910           t3=0.5;
2911           }
2912         }
2913       t2=1-t3;
2914       cg_wave_midpoint=dotpos2+t2*dotpos2_err;
2915       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
2916       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
2917       ia=cg_wave_midpoint;
2918       cg_wave_coh_re=t3*dot2_re+t2*baseb_envelope[2*ia  ];
2919       cg_wave_coh_im=t3*dot2_im+t2*baseb_envelope[2*ia+1];
2920       PRT04"\nstore dot %f",cg_wave_midpoint);
2921       insert_item(CW_DOT);
2922 if(kill_all_flag)return;
2923       cw_ptr++;
2924       break;
2925 
2926       case 5:
2927 // Store word separator
2928 //  ---_____---   8  ity=5
2929       cg_wave_midpoint=dashpos1_nom;
2930       PRT04"\nstore word sep %f",cg_wave_midpoint);
2931       insert_item(CW_WORDSEP);
2932 if(kill_all_flag)return;
2933       cw_ptr++;
2934       break;
2935       }
2936 */
2937     break;
2938 
2939 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2940 //  ööAug 2004
2941 //
2942     default:
2943   /*
2944     if(k==10)
2945       {
2946       set_region_envelope();
2947       }
2948     else
2949       {
2950       set_long_region_envelope();
2951       }
2952 // See if a dash will fit in the first position.
2953     dashpos1_nom=cw[cw_ptr-1].midpoint+4*cwbit_pts;
2954     if(dashpos1_nom >= baseband_size)dashpos1_nom-=baseband_size;
2955     dash1_chk=check_dash(dashpos1_nom);
2956     cg_wave_start=dashpos1_nom-(dash_pts>>1)+baseband_size;
2957     cg_wave_start&=baseband_mask;
2958     fit_dash();
2959     dash1_re=cg_wave_coh_re;
2960     dash1_im=cg_wave_coh_im;
2961     dashpos1=cg_wave_midpoint;
2962     dashpos1_err=dashpos1_nom-cg_wave_midpoint;
2963     if(dashpos1_err < -sizhalf)dashpos1_err+=baseband_size;
2964     dash_fit1=cg_wave_fit;
2965     PRT05"\n{def.l(2)}CHK DASH %f fit= %f  (%f) [%f]",
2966                             dash1_chk,dash_fit1,dashpos1_nom,cg_wave_midpoint);
2967 // See if a dot will fit in the first position
2968     dotpos1_nom=dashpos1_nom-cwbit_pts;
2969     if(dotpos1_nom < 0)dotpos1_nom+=baseband_size;
2970     dot1_chk=check_dot(dotpos1_nom);
2971     cg_wave_start=dotpos1_nom-(dot_pts>>1)+baseband_size;
2972     cg_wave_start&=baseband_mask;
2973     fit_dot();
2974     dot1_re=cg_wave_coh_re;
2975     dot1_im=cg_wave_coh_im;
2976     dotpos1=cg_wave_midpoint;
2977     dotpos1_err=dotpos1_nom-cg_wave_midpoint;
2978     if(dotpos1_err < -sizhalf)dotpos1_err+=baseband_size;
2979     dot_fit1=cg_wave_fit;
2980     PRT05"\n{def.l(2)}CHK DOT1 %f fit=%f  (%f)  [%f]",
2981                           dot1_chk,dot_fit1,dotpos1_nom,cg_wave_midpoint);
2982     ity=0;
2983     if(  (dash_fit1 > DASH_DETECT_LIMIT &&
2984           fabs(dashpos1_err) < 0.7*cwbit_pts &&
2985           dash1_chk > 0)    ||
2986                (dash_fit1 > DASH_MISFIT_LIMIT &&
2987                 fabs(dashpos1_err) < 0.5*cwbit_pts &&
2988                 dash1_chk > 0.5)  )
2989       {
2990 // A dash fits reasonably well in the lower position.
2991       ity=1;
2992 // Check how well dots would fit at the beginning or end of the dash position.
2993       if(fabs(dotpos1_err) < 0.7 * cwbit_pts &&
2994          dash_fit1 < dot_fit1+0.05 &&
2995          dot1_chk > 0)
2996         {
2997         PRT05"\ndot1.l good(2). Skip dash for now.");
2998         ity=0;
2999         if( dot_fit1 > DOT_DETECT_LIMIT ||
3000                (dot_fit1 > DOT_MISFIT_LIMIT &&
3001                 fabs(dotpos1_err) < 0.5*cwbit_pts &&
3002                 dash_fit1 < dot_fit1 &&
3003                 dot1_chk > 0.5)  )
3004           {
3005           goto store_dot1;
3006           }
3007         }
3008       else
3009         {
3010         dotpos2_nom=dashpos1_nom+cwbit_pts;
3011         if(dotpos2_nom >= baseband_size)dotpos2_nom-=baseband_size;
3012         dot2_chk=check_dot(dotpos2_nom);
3013         cg_wave_start=dotpos2_nom-(dot_pts>>1)+baseband_size;
3014         cg_wave_start&=baseband_mask;
3015         fit_dot();
3016         dotpos2=cg_wave_midpoint;
3017         dotpos2_err=dotpos2_nom-cg_wave_midpoint;
3018         if(dotpos2_err < -sizhalf)dotpos2_err+=baseband_size;
3019         dot_fit2=cg_wave_fit;
3020         PRT05"\n{def.l}CHK DOT2 %f fit=%f  (%f)  [%f]",
3021                           dot2_chk,cg_wave_fit,dotpos2_nom,cg_wave_midpoint);
3022         if(fabs(dotpos2_err) < 0.5 * cwbit_pts &&
3023            dash_fit1 < dot_fit2+0.05 &&
3024            dot2_chk > 0.25)
3025           {
3026           PRT05"\ndot2.h good, skip dash for now.");
3027           ity=0;
3028           }
3029         }
3030       }
3031     else
3032       {
3033 // A dash did not fit in the first position.
3034 // See if a dot does.
3035     if(  (dot_fit1 > DOT_DETECT_LIMIT &&
3036           fabs(dotpos1_err) < 0.7*cwbit_pts &&
3037           dot1_chk > 0)    ||
3038                (dot_fit1 > DOT_MISFIT_LIMIT &&
3039                 fabs(dotpos1_err) < 0.5*cwbit_pts &&
3040                 dot1_chk > 0.5)  )
3041         {
3042         PRT05"\ndash1 bad, dot1 good.");
3043 store_dot1:;
3044         cg_wave_midpoint=dotpos1+0.5*dotpos1_err;
3045         if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3046         if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3047         ia=cg_wave_midpoint;
3048         cg_wave_coh_re=0.5*dot1_re+0.5*baseb_envelope[2*ia  ];
3049         cg_wave_coh_im=0.5*dot1_im+0.5*baseb_envelope[2*ia+1];
3050         PRT05"\nstore dot1.l  %f",cg_wave_midpoint);
3051         insert_item(CW_DOT);
3052 if(kill_all_flag)return;
3053         cw_ptr++;
3054         }
3055       }
3056 // See if a dash will fit in the upper position.
3057     dashpos2_nom=cw[cw_ptr].midpoint-4*cwbit_pts;
3058     if(dashpos2_nom < 0)dashpos2_nom+=baseband_size;
3059     dash2_chk=check_dash(dashpos2_nom);
3060     cg_wave_start=dashpos2_nom-(dash_pts>>1)+baseband_size;
3061     cg_wave_start&=baseband_mask;
3062     fit_dash();
3063     dash2_re=cg_wave_coh_re;
3064     dash2_im=cg_wave_coh_im;
3065     dashpos2=cg_wave_midpoint;
3066     dashpos2_err=dashpos2_nom-cg_wave_midpoint;
3067     if(dashpos2_err < -sizhalf)dashpos2_err+=baseband_size;
3068     dash_fit2=cg_wave_fit;
3069     PRT05"\n{def.h(2)}CHK DASH %f fit= %f  (%f) [%f]",
3070                          dash2_chk,dash_fit2,dashpos2_nom,cg_wave_midpoint);
3071     dotpos4_nom=dashpos2_nom+cwbit_pts;
3072     if(dotpos4_nom >= baseband_size)dotpos4_nom-=baseband_size;
3073     dot4_chk=check_dot(dotpos4_nom);
3074     cg_wave_start=dotpos4_nom-(dot_pts>>1)+baseband_size;
3075     cg_wave_start&=baseband_mask;
3076     fit_dot();
3077     dot4_re=cg_wave_coh_re;
3078     dot4_im=cg_wave_coh_im;
3079     dotpos4=cg_wave_midpoint;
3080     dotpos4_err=dotpos4_nom-cg_wave_midpoint;
3081     if(dotpos4_err < -sizhalf)dotpos4_err+=baseband_size;
3082     dot_fit4=cg_wave_fit;
3083     PRT05"\n{def.h(2)}CHK DOT4 %f fit=%f  (%f)  [%f]",
3084                           dot4_chk,dot_fit4,dotpos4_nom,cg_wave_midpoint);
3085 
3086     if(  (dash_fit2 > DASH_DETECT_LIMIT &&
3087           fabs(dashpos2_err) < 0.7*cwbit_pts &&
3088           dash2_chk > 0)  ||
3089                 (dash_fit2 > DASH_MISFIT_LIMIT &&
3090                  fabs(dashpos2_err) < 0.5*cwbit_pts &&
3091                  dash2_chk > 0.5)  )
3092       {
3093 // A dash fits reasonably well in the upper position.
3094       ity|=2;
3095 // Check how well dots would fit at the beginning or end of the dash position.
3096       if( fabs(dotpos4_err) < 0.7 * cwbit_pts &&
3097           dash_fit2 < dot_fit4+0.05 &&
3098           dot4_chk > 0)
3099         {
3100         PRT05"\ndot4.h good(2), skip dash for now.");
3101         ity&=1;
3102         if( dot_fit4 > DOT_DETECT_LIMIT ||
3103                (dot_fit4 > DOT_MISFIT_LIMIT &&
3104                 fabs(dotpos4_err) < 0.5*cwbit_pts &&
3105                 dash_fit2 < dot_fit4 &&
3106                 dot4_chk > 0.5)  )
3107           {
3108           goto store_dot4;
3109           }
3110         }
3111       else
3112         {
3113         dotpos3_nom=dashpos2_nom-cwbit_pts;
3114         if(dotpos3_nom < 0)dotpos3_nom+=baseband_size;
3115         dot3_chk=check_dot(dotpos3_nom);
3116         cg_wave_start=dotpos3_nom-(dot_pts>>1)+baseband_size;
3117         cg_wave_start&=baseband_mask;
3118         fit_dot();
3119         dotpos3=cg_wave_midpoint;
3120         dotpos3_err=dotpos3_nom-cg_wave_midpoint;
3121         if(dotpos3_err < -sizhalf)dotpos3_err+=baseband_size;
3122         dot_fit3=cg_wave_fit;
3123         PRT05"\n{def.h}CHK DOT3 %f fit=%f  (%f)  [%f]",
3124                           dot3_chk,cg_wave_fit,dotpos3_nom,cg_wave_midpoint);
3125         if(fabs(dotpos3_err) < 0.5 * cwbit_pts &&
3126            dash_fit2 < dot_fit3+0.05 &&
3127            dot3_chk > 0.25)
3128           {
3129           PRT05"\ndot3.h good, skip dash for now.");
3130           ity&=1;
3131           }
3132         }
3133       if( (ity & 3) == 3 && k < 12)
3134         {
3135 // We can not have one dash at each side in a short region.
3136 // choose the best one.
3137         if( fabs(dash_fit1-dash_fit2) > 0.05)
3138           {
3139           if(dash_fit1 > dash_fit2)
3140             {
3141             ity=1;
3142             }
3143           else
3144             {
3145             ity=2;
3146             }
3147           }
3148         else
3149           {
3150           t1=2*dash_fit1-dot_fit1-dot_fit2-2*dash_fit2+dot_fit3+dot_fit4;
3151           if(fabs(t1) < 0.05)
3152             {
3153             ity=0;
3154             }
3155           else
3156             {
3157             if(t1>0)ity=1; else ity=2;
3158             }
3159           }
3160         }
3161       }
3162     else
3163       {
3164 // A dash did not fit in the upper position.
3165 // See if a dot does.
3166     if(  (dot_fit4 > DOT_DETECT_LIMIT &&
3167           fabs(dotpos4_err) < 0.7*cwbit_pts &&
3168           dot4_chk > 0)    ||
3169                (dot_fit4 > DOT_MISFIT_LIMIT &&
3170                 fabs(dotpos4_err) < 0.5*cwbit_pts &&
3171                 dot4_chk > 0.5)  )
3172         {
3173         PRT05"\ndash2 bad, dot4 good.");
3174 store_dot4:;
3175         ity|=4;
3176         }
3177       }
3178     if( (ity & 3) == 3 && k < 12)
3179       {
3180 // We can not have one dash at each side in a short region.
3181 // choose the best one.
3182       if( fabs(dash_fit1-dash_fit2) > 0.05)
3183         {
3184         if(dash_fit1 > dash_fit2)
3185           {
3186           ity=1;
3187           }
3188         else
3189           {
3190           ity=2;
3191           }
3192         }
3193       else
3194         {
3195         t1=2*dash_fit1-dot_fit1-dot_fit2-2*dash_fit2+dot_fit3+dot_fit4;
3196         if(fabs(t1) < 0.05)
3197           {
3198           ity=0;
3199           }
3200         else
3201           {
3202           if(t1>0)ity=1; else ity=2;
3203           }
3204         }
3205       }
3206     if( (ity&1) != 0)
3207       {
3208       cg_wave_midpoint=dashpos1+0.5*dashpos1_err;
3209       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3210       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3211       ia=cg_wave_midpoint;
3212       cg_wave_coh_re=0.5*dash1_re+0.5*baseb_envelope[2*ia  ];
3213       cg_wave_coh_im=0.5*dash1_im+0.5*baseb_envelope[2*ia+1];
3214       PRT05"\nstore_dash.l  %f",cg_wave_midpoint);
3215       insert_item(CW_DASH);
3216 if(kill_all_flag)return;
3217       cw_ptr++;
3218       }
3219     if( (ity&2) != 0)
3220       {
3221       cg_wave_midpoint=dashpos2+0.5*dashpos2_err;
3222       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3223       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3224       ia=cg_wave_midpoint;
3225       cg_wave_coh_re=0.5*dash2_re+0.5*baseb_envelope[2*ia  ];
3226       cg_wave_coh_im=0.5*dash2_im+0.5*baseb_envelope[2*ia+1];
3227       PRT05"\nstore_dash.h  %f",cg_wave_midpoint);
3228       insert_item(CW_DASH);
3229 if(kill_all_flag)return;
3230       cw_ptr++;
3231       }
3232     if( (ity&4) != 0)
3233       {
3234       cg_wave_midpoint=dotpos4+0.5*dotpos4_err;
3235       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3236       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3237       ia=cg_wave_midpoint;
3238       cg_wave_coh_re=0.5*dot4_re+0.5*baseb_envelope[2*ia  ];
3239       cg_wave_coh_im=0.5*dot4_im+0.5*baseb_envelope[2*ia+1];
3240       PRT05"\nstore dot4.h(2)  %f",cg_wave_midpoint);
3241       insert_item(CW_DOT);
3242 if(kill_all_flag)return;
3243       cw_ptr++;
3244       }
3245 */
3246     break;
3247     }
3248 skip:;
3249   cw_ptr++;
3250   }
3251 //show_cw("second_detect exit");
3252 }
3253 
3254 
get_old_dashes(void)3255 void get_old_dashes(void)
3256 {
3257 int i;
3258 int ia, ib;
3259 // Speed and wave forms are known.
3260 // Look for new dashes, in the range cw[0].midpoint
3261 // to baseb_px.
3262 ia=baseb_px;
3263 while(baseb_ramp[ia] < 0)ia=(ia+1)&baseband_mask;
3264 while(baseb_ramp[ia] > 0)ia=(ia+1)&baseband_mask;
3265 while(baseb_ramp[ia] < 0)ia=(ia+1)&baseband_mask;
3266 ia=(ia+baseband_mask)&baseband_mask;
3267 ib=cw[0].midpoint;
3268 ib=(ib-abs(baseb_ramp[ib])+baseband_size)&baseband_mask;
3269 if(baseb_ramp[ib] > 0)ib=(ib-baseb_ramp[ib]+baseband_size)&baseband_mask;
3270 if(no_of_cwdat < 1)lirerr(876231);
3271 i=((int)(cw[no_of_cwdat-1].midpoint)-ib+baseband_size)&baseband_mask;
3272 if( i+((ib-ia+baseband_size)&baseband_mask) > baseband_neg)return;
3273 find_good_dashes(ia, ib, 14);
3274 check_cw(30035,1);
3275 }
3276 
get_recent_dashes(void)3277 void get_recent_dashes(void)
3278 {
3279 int ia;
3280 // Speed and wave forms are known.
3281 // Look for new dashes, in the range cw[no_of_cwdat-1].midpoint
3282 // to baseb_pc.
3283 ia=cw[no_of_cwdat-1].midpoint;
3284 while(baseb_ramp[ia] > 0)ia=(ia+1)&baseband_mask;
3285 while(baseb_ramp[ia] < 0)ia=(ia+1)&baseband_mask;
3286 ia=(ia+baseband_mask)&baseband_mask;
3287 // ia now points to the last point of the first negative ramp
3288 // after the most recent cw[].midpoint.
3289 if( ((baseb_pc-ia+baseband_size)&baseband_mask) > baseband_neg)return;
3290 find_good_dashes(ia, baseb_pc, 14);
3291 check_cw(30030,1);
3292 }
3293 
3294 
3295 
first_detect(int first_item)3296 void first_detect(int first_item)
3297 {
3298 mailbox[0]=first_item;
3299 cw_detect_flag=CWDETECT_DEBUG_STOP;
3300 return;
3301 lirerr(888922);
3302 /*
3303 
3304 int sizhalf;
3305 int k, ia;
3306 int ity, item;
3307 float dotpos1_nom, dotpos2_nom, dotpos3_nom, dotpos4_nom;
3308 float dashpos1_nom, dashpos2_nom;
3309 float dot1_chk, dot2_chk, dot3_chk, dot4_chk, dash1_chk, dash2_chk;
3310 float dashpos1, dashpos2, dotpos1, dotpos2, dotpos3, dotpos4;
3311 float dashpos1_err, dashpos2_err;
3312 float dotpos1_err, dotpos2_err, dotpos3_err, dotpos4_err;
3313 float dash_fit1, dash_fit2, dot_fit1, dot_fit2, dot_fit3, dot_fit4;
3314 float r1, t1, t2, t3;
3315 float dash1_re, dash1_im, dash2_re, dash2_im;
3316 float dot1_re, dot1_im, dot2_re, dot2_im;
3317 // **************************************************************
3318 // **************************************************************
3319 // ****    This routine is called to initiate a recently     ****
3320 // ***     collected data area for which dashes have been    ****
3321 // **** fitted but for which nothing else has yet been done. ****
3322 // **************************************************************
3323 // **************************************************************
3324 sizhalf=baseband_size>>1;
3325 // Initiate with stupid values. This avoids compiler complaints.
3326 dot1_chk=-BIG;
3327 dotpos1=BIG;
3328 dotpos1_err=BIG;
3329 dot1_re=BIG;
3330 dot1_im=BIG;
3331 dot_fit1=-BIG;
3332 dot2_chk=-BIG;
3333 dotpos2=BIG;
3334 dotpos2_err=BIG;
3335 dot2_re=BIG;
3336 dot2_im=BIG;
3337 dot_fit2=-BIG;
3338 dotpos1_nom=BIG;
3339 dotpos2_nom=BIG;
3340 dash_fit2=-BIG;
3341 dot_fit4=-BIG;
3342 // *****************************************************
3343 // *****************************************************
3344 // *****  Fit key up or key down patterns to short *****
3345 // *****  regions that are surrounded by dashes    *****
3346 // *****************************************************
3347 // *****************************************************
3348 // Look for the following cases:
3349 //    Code       Sep
3350 //  ---_---       4
3351 //  ---_-_---     6
3352 //  ---___---     6
3353 //  ---_-_-_---   8
3354 //  ---_---_---   8
3355 //  ---___-_---   8
3356 //  ---_-___---   8
3357 //  ---_____---   8
3358 //  ---_---_?_---   10
3359 //  ---_?_---_---   10
3360 //  ---_---_????....  default
3361 //  ....????_---_---  default
3362 #if PR02 == 1
3363 show_cw("first_detect enter");
3364 PRT02"\nfirst_detect: CWBIT PTS %f",cwbit_pts);
3365 #endif
3366 // Store the most probable signal in each case.
3367 //   name     data    length
3368 // CW_DASH    |---_|     4
3369 // CW_DOT     |-_|       2
3370 // CW_SPACE   |__|       2
3371 // CW_WORDSEP |____|     4
3372 // The item starts (length/2 + 0.5) below cw[].midpoint because
3373 // midpoint is the center of a key down period while the item
3374 // midpoint is 0.5 above that because one space is always
3375 // included in an item.
3376 cw_ptr=first_item;
3377 while(cw_ptr < no_of_cwdat)
3378   {
3379   r1=cw[cw_ptr].sep/cwbit_pts;
3380   k=(int)(r1)&0xfffffffe;
3381   if(r1-k > 1)k+=2;
3382   PRT02"\n%d PRT02(1)> k=%d  %f  [%f][%f]",cw_ptr,k,
3383                           r1,cw[cw_ptr-1].midpoint,cw[cw_ptr].midpoint);
3384 check_cw(467501,1);
3385 if(kill_all_flag)return;
3386 
3387   switch (k)
3388     {
3389     case 2:
3390     case 4:
3391 // We have two close spaced dashes.
3392 // There can be nothing in between.
3393     break;
3394 
3395     case 6:
3396 //  ---_-_---     6
3397 //  ---___---     6
3398 // Base the decision on the probability that there is a dot
3399 // right between the two dashes.
3400     set_region_envelope();
3401     dotpos1_nom=cw[cw_ptr].midpoint-0.5*cw[cw_ptr].sep;
3402     if(dotpos1_nom < 0)dotpos1_nom+=baseband_size;
3403     dot1_chk=check_dot(dotpos1_nom);
3404     PRT03"\n{6}CHK DOT %f (%f)",dot1_chk,dotpos1_nom);
3405 // If dot1_chk in negative, the fit is better for a space than for a dot.
3406 // Be careful and check if a dot would fit even for dot1_chk a little below zero.
3407     if(dot1_chk > -0.25)
3408       {
3409       cg_wave_start=dotpos1_nom-(dot_pts>>1)+baseband_size;
3410       cg_wave_start&=baseband_mask;
3411       fit_dot();
3412       PRT03" [%f]", cg_wave_midpoint);
3413       dotpos1_err=dotpos1_nom-cg_wave_midpoint;
3414       if(dotpos1_err < -sizhalf)dotpos1_err+=baseband_size;
3415       PRT03"  poserr %f  fit %f",dotpos1_err/cwbit_pts,cg_wave_fit);
3416       t3=-1;
3417 // Use t3 as an indicator.
3418 // t3 < 0 => store space.
3419 // t3 > 0 => store dot using t3 as the weight on fit_dot data.
3420       if(cg_wave_fit > DOT_DETECT_LIMIT && fabs(dotpos1_err) < 0.25*cwbit_pts)
3421         {
3422         if(dot1_chk < 0.25)
3423           {
3424           t3=0.75;
3425           }
3426         else
3427           {
3428           t3=0.5;
3429           }
3430         }
3431       if(cg_wave_fit > DOT_MISFIT_LIMIT &&
3432                        fabs(dotpos1_err) < 0.5*cwbit_pts && dot1_chk > 0.5)t3=0.5;
3433       if(t3 >= 0)
3434         {
3435         t2=1-t3;
3436         cg_wave_midpoint+=t2*dotpos1_err;
3437         if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3438         if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3439         ia=cg_wave_midpoint;
3440         cg_wave_coh_re=t3*cg_wave_coh_re+t2*baseb_envelope[2*ia  ];
3441         cg_wave_coh_im=t3*cg_wave_coh_im+t2*baseb_envelope[2*ia+1];
3442         clear_region();
3443         PRT03"\nstore dot %f",cg_wave_midpoint);
3444         item=CW_DOT;
3445         }
3446       else
3447         {
3448         if( dot1_chk > 0)
3449           {
3450           item=0;
3451           }
3452         else
3453           {
3454           cg_wave_midpoint=dotpos1_nom;
3455           clear_region();
3456           PRT03"\nstore space %f",cg_wave_midpoint);
3457           item=CW_SPACE;
3458           }
3459         }
3460       }
3461     else
3462       {
3463       cg_wave_midpoint=dotpos1_nom;
3464       clear_region();
3465       PRT03"\nstore space %f",cg_wave_midpoint);
3466       item=CW_SPACE;
3467       }
3468     if(item!=0)insert_item(item);
3469 if(kill_all_flag)return;
3470     break;
3471 
3472     case 8:
3473 //  ---_-_-_---   8  ity=4
3474 //  ---_---_---   8  ity=1
3475 //  ---___-_---   8  ity=3
3476 //  ---_-___---   8  ity=2
3477 //  ---_____---   8  ity=5
3478     set_region_envelope();
3479     ity=0;
3480 // See if a dash will fit well.
3481     dashpos1_nom=cw[cw_ptr].midpoint-0.5*cw[cw_ptr].sep;
3482     if(dashpos1_nom < 0)dashpos1_nom+=baseband_size;
3483     dash1_chk=check_dash(dashpos1_nom);
3484     cg_wave_start=dashpos1_nom-(dash_pts>>1)+baseband_size;
3485     cg_wave_start&=baseband_mask;
3486     fit_dash();
3487     dash1_re=cg_wave_coh_re;
3488     dash1_im=cg_wave_coh_im;
3489     dashpos1=cg_wave_midpoint;
3490     dashpos1_err=dashpos1_nom-cg_wave_midpoint;
3491     if(dashpos1_err < -sizhalf)dashpos1_err+=baseband_size;
3492     dash_fit1=cg_wave_fit;
3493     if( dash_fit1 > DASH_DETECT_LIMIT &&
3494                    dash1_chk > 0.5 &&  fabs(dashpos1_err) < 0.5*cwbit_pts)
3495       {
3496       ity=1;
3497       PRT04"\n{8}GOOD DASH %f fit= %f  (%f) [%f]",
3498                         dash1_chk,cg_wave_fit,dashpos1_nom,cg_wave_midpoint);
3499       goto store8;
3500       }
3501     PRT04"\n{8}CHK DASH %f fit= %f  (%f) [%f]",
3502                          dash1_chk,cg_wave_fit,dashpos1_nom,cg_wave_midpoint);
3503     dotpos1_nom=cw[cw_ptr].midpoint-0.625*cw[cw_ptr].sep;
3504     if(dotpos1_nom < 0)dotpos1_nom+=baseband_size;
3505     dot1_chk=check_dot(dotpos1_nom);
3506     dotpos2_nom=cw[cw_ptr].midpoint-0.375*cw[cw_ptr].sep;
3507     if(dotpos2_nom < 0)dotpos2_nom+=baseband_size;
3508     dot2_chk=check_dot(dotpos2_nom);
3509     if(dash1_chk < -0.25 && dot1_chk < -0.25 && dot2_chk < -0.25)
3510       {
3511       PRT04"\nALL chk NEG (< -0.25)");
3512       ity=5;
3513       goto store8;
3514       }
3515     cg_wave_start=dotpos1_nom-(dot_pts>>1)+baseband_size;
3516     cg_wave_start&=baseband_mask;
3517     fit_dot();
3518     dot1_re=cg_wave_coh_re;
3519     dot1_im=cg_wave_coh_im;
3520     dotpos1=cg_wave_midpoint;
3521     dotpos1_err=dotpos1_nom-cg_wave_midpoint;
3522     if(dotpos1_err < -sizhalf)dotpos1_err+=baseband_size;
3523     dot_fit1=cg_wave_fit;
3524     PRT04"\n{8}CHK DOT1 %f fit=%f  (%f)  [%f]",
3525                           dot1_chk,cg_wave_fit,dotpos1_nom,cg_wave_midpoint);
3526     cg_wave_start=dotpos2_nom-(dot_pts>>1)+baseband_size;
3527     cg_wave_start&=baseband_mask;
3528     fit_dot();
3529     dot2_re=cg_wave_coh_re;
3530     dot2_im=cg_wave_coh_im;
3531     dotpos2=cg_wave_midpoint;
3532     dotpos2_err=dotpos2_nom-cg_wave_midpoint;
3533     if(dotpos2_err < -sizhalf)dotpos2_err+=baseband_size;
3534     dot_fit2=cg_wave_fit;
3535     PRT04"\n{8}CHK DOT2 %f fit=%f  (%f)  [%f]",
3536                          dot2_chk,cg_wave_fit,dotpos2_nom,cg_wave_midpoint);
3537     if( dash_fit1 < DASH_MISFIT_LIMIT ||
3538              ( (dash1_chk < -0.25 && fabs(dashpos1_err) < 0.5*cwbit_pts) ||
3539                 ( dash1_chk < 0.25 && fabs(dashpos1_err) < cwbit_pts ) ) )
3540       {
3541 // The fit to a dash is very poor.
3542 // Set ity to 5 (word separator), then check whether dot or space will fit.
3543       ity=5;
3544       PRT04"\nset ity=5");
3545       PRT04"\ndot1 fit %f    chk %f    poserr %f ",dot_fit1,dot1_chk,dotpos1_err);
3546       if( dot_fit1 > DOT_MISFIT_LIMIT &&
3547                       dot1_chk > 0.25 && fabs(dotpos1_err) < 0.5*cwbit_pts )
3548         {
3549         ity=2;
3550         PRT04"\nset ity=2");
3551         }
3552       PRT04"\ndot2 fit %f    chk %f    poserr %f ",dot_fit2,dot2_chk,dotpos2_err);
3553       if( dot_fit2 > DOT_MISFIT_LIMIT &&
3554                       dot2_chk > 0.25 && fabs(dotpos2_err) < 0.5*cwbit_pts )
3555         {
3556         if(ity == 2)
3557           {
3558           ity=4;
3559           PRT04"\nset ity=4");
3560           }
3561         else
3562           {
3563           ity=3;
3564           PRT04"\nset ity=3");
3565           }
3566         }
3567       goto store8;
3568       }
3569     PRT04"\nUnclear");
3570 // The situation is unclear. Nothing fits well...........
3571     if(dash1_chk < 0 && dot1_chk < 0 && dot2_chk < 0)
3572       {
3573       ity=5;
3574       PRT04"\nset ity=5  (all neg)");
3575       goto store8;
3576       }
3577     t1=dot1_chk*dot2_chk;
3578     if( fabs(t1) > dash1_chk*fabs(dash1_chk) )
3579       {
3580 // The fit to a dash is worse than dots and/or spaces.
3581       PRT04"\nset ity=5  (dash worse than dots)");
3582       ity=5;
3583       if( dot_fit1 > DOT_MISFIT_LIMIT &&
3584                          dot1_chk > 0 && fabs(dotpos1_err) < 0.7*cwbit_pts )
3585         {
3586         ity=2;
3587         PRT04"\nset ity=2");
3588         }
3589       if( dot_fit2 > DOT_MISFIT_LIMIT &&
3590                             dot2_chk > 0 && fabs(dotpos2_err) < 0.7*cwbit_pts )
3591         {
3592         if(ity == 2)
3593           {
3594           ity=4;
3595           PRT04"\nset ity=4");
3596           }
3597         else
3598           {
3599           ity=3;
3600           PRT04"\nset ity=3");
3601           }
3602         }
3603       goto store8;
3604       }
3605     if( dash_fit1 > DASH_MISFIT_LIMIT &&
3606                 (dash1_chk > 0 || fabs(dashpos1_err) < cwbit_pts ) )
3607       {
3608       ity=1;
3609       PRT04"\nset ity=1");
3610       }
3611 store8:;
3612     clear_region();
3613     PRT04"\nity=%d",ity);
3614     switch (ity)
3615       {
3616       case 1:
3617 // Store a dash
3618 //  ---_---_---   8  ity=1
3619       t3=0;
3620       if(dash_fit1 > DASH_DETECT_LIMIT && fabs(dashpos1_err) < 0.25*cwbit_pts)
3621         {
3622         if(dash1_chk < 0.25)
3623           {
3624           t3=0.75;
3625           }
3626         else
3627           {
3628           t3=0.5;
3629           }
3630         }
3631       t2=1-t3;
3632       cg_wave_midpoint=dashpos1+t2*dashpos1_err;
3633       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3634       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3635       ia=cg_wave_midpoint;
3636       cg_wave_coh_re=t3*dash1_re+t2*baseb_envelope[2*ia  ];
3637       cg_wave_coh_im=t3*dash1_im+t2*baseb_envelope[2*ia+1];
3638       PRT04"\nstore_dash %f",cg_wave_midpoint);
3639       insert_item(CW_DASH);
3640 if(kill_all_flag)return;
3641       cw_ptr++;
3642       break;
3643 
3644       case 2:
3645 // Store dot1 and space
3646 //  ---_-___---   8  ity=2
3647 //  ---___-_---   8  ity=3
3648 //  ---_____---   8  ity=5
3649 //  ---_-_-_---   8  ity=4
3650       t3=0;
3651       if(dot_fit1 > DOT_DETECT_LIMIT && fabs(dotpos1_err) < 0.25*cwbit_pts)
3652         {
3653         if(dot1_chk < 0.25)
3654           {
3655           t3=0.75;
3656           }
3657         else
3658           {
3659           t3=0.5;
3660           }
3661         }
3662       t2=1-t3;
3663       cg_wave_midpoint=dotpos1+t2*dotpos1_err;
3664       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3665       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3666       ia=cg_wave_midpoint;
3667       cg_wave_coh_re=t3*dot1_re+t2*baseb_envelope[2*ia  ];
3668       cg_wave_coh_im=t3*dot1_im+t2*baseb_envelope[2*ia+1];
3669       PRT04"\nstore dot %f",cg_wave_midpoint);
3670       insert_item(CW_DOT);
3671 if(kill_all_flag)return;
3672       cw_ptr++;
3673       cg_wave_midpoint=dotpos2_nom;
3674       PRT04"\nstore_space %f",cg_wave_midpoint);
3675       insert_item(CW_SPACE);
3676 if(kill_all_flag)return;
3677       cw_ptr++;
3678       break;
3679 
3680       case 3:
3681 // Store space and dot2
3682 //  ---___-_---   8  ity=3
3683       cg_wave_midpoint=dotpos1_nom;
3684       PRT04"\nstore_space %f",cg_wave_midpoint);
3685       insert_item(CW_SPACE);
3686 if(kill_all_flag)return;
3687       cw_ptr++;
3688       t3=0;
3689       if(dot_fit2 > DOT_DETECT_LIMIT && fabs(dotpos2_err) < 0.25*cwbit_pts)
3690         {
3691         if(dot2_chk < 0.25)
3692           {
3693           t3=0.75;
3694           }
3695         else
3696           {
3697           t3=0.5;
3698           }
3699         }
3700       t2=1-t3;
3701       cg_wave_midpoint=dotpos2+t2*dotpos2_err;
3702       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3703       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3704       ia=cg_wave_midpoint;
3705       cg_wave_coh_re=t3*dot2_re+t2*baseb_envelope[2*ia  ];
3706       cg_wave_coh_im=t3*dot2_im+t2*baseb_envelope[2*ia+1];
3707       PRT04"\nstore dot %f",cg_wave_midpoint);
3708       insert_item(CW_DOT);
3709 if(kill_all_flag)return;
3710       cw_ptr++;
3711       break;
3712 
3713       case 4:
3714 // Store dot1 and dot2
3715 //  ---_-_-_---   8  ity=4
3716       t3=0;
3717       if(dot_fit1 > DOT_DETECT_LIMIT && fabs(dotpos1_err) < 0.25*cwbit_pts)
3718         {
3719         if(dot1_chk < 0.25)
3720           {
3721           t3=0.75;
3722           }
3723         else
3724           {
3725           t3=0.5;
3726           }
3727         }
3728       t2=1-t3;
3729       cg_wave_midpoint=dotpos1+t2*dotpos1_err;
3730       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3731       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3732       ia=cg_wave_midpoint;
3733       cg_wave_coh_re=t3*dot1_re+t2*baseb_envelope[2*ia  ];
3734       cg_wave_coh_im=t3*dot1_im+t2*baseb_envelope[2*ia+1];
3735       PRT04"\nstore dot %f",cg_wave_midpoint);
3736       insert_item(CW_DOT);
3737 if(kill_all_flag)return;
3738       cw_ptr++;
3739       t3=0;
3740       if(dot_fit2 > DOT_DETECT_LIMIT && fabs(dotpos2_err) < 0.25*cwbit_pts)
3741         {
3742         if(dot2_chk < 0.25)
3743           {
3744           t3=0.75;
3745           }
3746         else
3747           {
3748           t3=0.5;
3749           }
3750         }
3751       t2=1-t3;
3752       cg_wave_midpoint=dotpos2+t2*dotpos2_err;
3753       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3754       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3755       ia=cg_wave_midpoint;
3756       cg_wave_coh_re=t3*dot2_re+t2*baseb_envelope[2*ia  ];
3757       cg_wave_coh_im=t3*dot2_im+t2*baseb_envelope[2*ia+1];
3758       PRT04"\nstore dot %f",cg_wave_midpoint);
3759       insert_item(CW_DOT);
3760 if(kill_all_flag)return;
3761       cw_ptr++;
3762       break;
3763 
3764 
3765       case 5:
3766 // Store word separator
3767 //  ---_____---   8  ity=5
3768       cg_wave_midpoint=dashpos1_nom;
3769       PRT04"\nstore word sep %f",cg_wave_midpoint);
3770       insert_item(CW_WORDSEP);
3771 if(kill_all_flag)return;
3772       cw_ptr++;
3773       break;
3774       }
3775     break;
3776 
3777 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3778 
3779     default:
3780     if(k==10)
3781       {
3782       set_region_envelope();
3783       }
3784     else
3785       {
3786       set_long_region_envelope();
3787       }
3788 // See if a dash will fit in the first position.
3789     dashpos1_nom=cw[cw_ptr-1].midpoint+4*cwbit_pts;
3790     if(dashpos1_nom >= baseband_size)dashpos1_nom-=baseband_size;
3791     dash1_chk=check_dash(dashpos1_nom);
3792     cg_wave_start=dashpos1_nom-(dash_pts>>1)+baseband_size;
3793     cg_wave_start&=baseband_mask;
3794     fit_dash();
3795     dash1_re=cg_wave_coh_re;
3796     dash1_im=cg_wave_coh_im;
3797     dashpos1=cg_wave_midpoint;
3798     dashpos1_err=dashpos1_nom-cg_wave_midpoint;
3799     if(dashpos1_err < -sizhalf)dashpos1_err+=baseband_size;
3800     dash_fit1=cg_wave_fit;
3801     PRT05"\n{def.l}CHK DASH %f fit= %f  (%f) [%f]",
3802                             dash1_chk,cg_wave_fit,dashpos1_nom,cg_wave_midpoint);
3803     ity=0;
3804     if(  (dash_fit1 > DASH_DETECT_LIMIT &&
3805           fabs(dashpos1_err) < 0.7*cwbit_pts &&
3806           dash1_chk > 0)    ||
3807                (dash_fit1 > DASH_MISFIT_LIMIT &&
3808                 fabs(dashpos1_err) < 0.5*cwbit_pts &&
3809                 dash1_chk > 0.5)  )
3810       {
3811 // A dash fits reasonably well in the lower position.
3812       ity=1;
3813 // Check how well dots would fit at the beginning or end of the dash position.
3814       dotpos1_nom=dashpos1_nom-cwbit_pts;
3815       if(dotpos1_nom < 0)dotpos1_nom+=baseband_size;
3816       dot1_chk=check_dot(dotpos1_nom);
3817       cg_wave_start=dotpos1_nom-(dot_pts>>1)+baseband_size;
3818       cg_wave_start&=baseband_mask;
3819       fit_dot();
3820       dotpos1=cg_wave_midpoint;
3821       dotpos1_err=dotpos1_nom-cg_wave_midpoint;
3822       if(dotpos1_err < -sizhalf)dotpos1_err+=baseband_size;
3823       dot_fit1=cg_wave_fit;
3824       PRT05"\n{def.l}CHK DOT1 %f fit=%f  (%f)  [%f]",
3825                           dot1_chk,cg_wave_fit,dotpos1_nom,cg_wave_midpoint);
3826       if(fabs(dotpos1_err) < 0.5 * cwbit_pts &&
3827          dash_fit1 < dot_fit1+0.05 &&
3828          dot1_chk > 0.25)
3829         {
3830         PRT05"\ndot1.l good, skip dash for now.");
3831         ity=0;
3832         }
3833       else
3834         {
3835         dotpos2_nom=dashpos1_nom+cwbit_pts;
3836         if(dotpos2_nom >= baseband_size)dotpos2_nom-=baseband_size;
3837         dot2_chk=check_dot(dotpos2_nom);
3838         cg_wave_start=dotpos2_nom-(dot_pts>>1)+baseband_size;
3839         cg_wave_start&=baseband_mask;
3840         fit_dot();
3841         dotpos2=cg_wave_midpoint;
3842         dotpos2_err=dotpos2_nom-cg_wave_midpoint;
3843         if(dotpos2_err < -sizhalf)dotpos2_err+=baseband_size;
3844         dot_fit2=cg_wave_fit;
3845         PRT05"\n{def.l}CHK DOT2 %f fit=%f  (%f)  [%f]",
3846                           dot2_chk,cg_wave_fit,dotpos2_nom,cg_wave_midpoint);
3847         if(fabs(dotpos2_err) < 0.5 * cwbit_pts &&
3848            dash_fit1 < dot_fit2+0.05 &&
3849            dot2_chk > 0.25)
3850           {
3851           PRT05"\ndot2.h good, skip dash for now.");
3852           ity=0;
3853           }
3854         }
3855       }
3856 // See if a dash will fit in the upper position.
3857     dashpos2_nom=cw[cw_ptr].midpoint-4*cwbit_pts;
3858     if(dashpos2_nom < 0)dashpos2_nom+=baseband_size;
3859     dash2_chk=check_dash(dashpos2_nom);
3860     cg_wave_start=dashpos2_nom-(dash_pts>>1)+baseband_size;
3861     cg_wave_start&=baseband_mask;
3862     fit_dash();
3863     dash2_re=cg_wave_coh_re;
3864     dash2_im=cg_wave_coh_im;
3865     dashpos2=cg_wave_midpoint;
3866     dashpos2_err=dashpos2_nom-cg_wave_midpoint;
3867     if(dashpos2_err < -sizhalf)dashpos2_err+=baseband_size;
3868     dash_fit2=cg_wave_fit;
3869     PRT05"\n{def.u}CHK DASH %f fit= %f  (%f) [%f]",
3870                          dash2_chk,cg_wave_fit,dashpos2_nom,cg_wave_midpoint);
3871     if(  (dash_fit2 > DASH_DETECT_LIMIT &&
3872           fabs(dashpos2_err) < 0.7*cwbit_pts &&
3873           dash2_chk > 0)  ||
3874                 (dash_fit2 > DASH_MISFIT_LIMIT &&
3875                  fabs(dashpos2_err) < 0.5*cwbit_pts &&
3876                  dash2_chk > 0.5)  )
3877       {
3878 // A dash fits reasonably well in the upper position.
3879       ity|=2;
3880 // Check how well dots would fit at the beginning or end of the dash position.
3881       dotpos3_nom=dashpos2_nom-cwbit_pts;
3882       if(dotpos3_nom < 0)dotpos3_nom+=baseband_size;
3883       dot3_chk=check_dot(dotpos3_nom);
3884       cg_wave_start=dotpos3_nom-(dot_pts>>1)+baseband_size;
3885       cg_wave_start&=baseband_mask;
3886       fit_dot();
3887       dotpos3=cg_wave_midpoint;
3888       dotpos3_err=dotpos3_nom-cg_wave_midpoint;
3889       if(dotpos3_err < -sizhalf)dotpos3_err+=baseband_size;
3890       dot_fit3=cg_wave_fit;
3891       PRT05"\n{def.h}CHK DOT3 %f fit=%f  (%f)  [%f]",
3892                           dot3_chk,cg_wave_fit,dotpos3_nom,cg_wave_midpoint);
3893 
3894       if(fabs(dotpos3_err) < 0.5 * cwbit_pts &&
3895          dash_fit2 < dot_fit3+0.05 &&
3896          dot3_chk > 0.25)
3897         {
3898         PRT05"\ndot3.h good, skip dash for now.");
3899         ity&=1;
3900         }
3901       else
3902         {
3903         dotpos4_nom=dashpos2_nom+cwbit_pts;
3904         if(dotpos4_nom >= baseband_size)dotpos4_nom-=baseband_size;
3905         dot4_chk=check_dot(dotpos4_nom);
3906         cg_wave_start=dotpos4_nom-(dot_pts>>1)+baseband_size;
3907         cg_wave_start&=baseband_mask;
3908         fit_dot();
3909         dotpos4=cg_wave_midpoint;
3910         dotpos4_err=dotpos4_nom-cg_wave_midpoint;
3911         if(dotpos4_err < -sizhalf)dotpos4_err+=baseband_size;
3912         dot_fit4=cg_wave_fit;
3913         PRT05"\n{def.h}CHK DOT4 %f fit=%f  (%f)  [%f]",
3914                           dot4_chk,cg_wave_fit,dotpos4_nom,cg_wave_midpoint);
3915         if(fabs(dotpos4_err) < 0.5 * cwbit_pts &&
3916            dash_fit2 < dot_fit4+0.05 &&
3917            dot4_chk > 0.25)
3918           {
3919           PRT05"\ndot2.h good, skip dash for now.");
3920           ity&=1;
3921           }
3922 
3923         }
3924       if( (ity & 3) == 3 && k < 12)
3925         {
3926 // We can not have one dash at each side in a short region.
3927 // choose the best one.
3928         if( fabs(dash_fit1-dash_fit2) > 0.05)
3929           {
3930           if(dash_fit1 > dash_fit2)
3931             {
3932             ity=1;
3933             }
3934           else
3935             {
3936             ity=2;
3937             }
3938           }
3939         else
3940           {
3941           t1=2*dash_fit1-dot_fit1-dot_fit2-2*dash_fit2+dot_fit3+dot_fit4;
3942           if(fabs(t1) < 0.05)
3943             {
3944             ity=0;
3945             }
3946           else
3947             {
3948             if(t1>0)ity=1; else ity=2;
3949             }
3950           }
3951         }
3952       }
3953     if( (ity&1) != 0)
3954       {
3955       cg_wave_midpoint=dashpos1+0.5*dashpos1_err;
3956       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3957       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3958       ia=cg_wave_midpoint;
3959       cg_wave_coh_re=0.5*dash1_re+0.5*baseb_envelope[2*ia  ];
3960       cg_wave_coh_im=0.5*dash1_im+0.5*baseb_envelope[2*ia+1];
3961       PRT05"\nstore_dash.l  %f",cg_wave_midpoint);
3962       insert_item(CW_DASH);
3963 if(kill_all_flag)return;
3964       cw_ptr++;
3965       }
3966     if( (ity&2) != 0)
3967       {
3968       cg_wave_midpoint=dashpos2+0.5*dashpos2_err;
3969       if(cg_wave_midpoint < 0)cg_wave_midpoint+=baseband_size;
3970       if(cg_wave_midpoint >= baseband_size)cg_wave_midpoint-=baseband_size;
3971       ia=cg_wave_midpoint;
3972       cg_wave_coh_re=0.5*dash2_re+0.5*baseb_envelope[2*ia  ];
3973       cg_wave_coh_im=0.5*dash2_im+0.5*baseb_envelope[2*ia+1];
3974       PRT05"\nstore_dash.h  %f",cg_wave_midpoint);
3975       insert_item(CW_DASH);
3976 if(kill_all_flag)return;
3977       cw_ptr++;
3978       }
3979     break;
3980     }
3981   cw_ptr++;
3982   }
3983 if(PR05 != 0)show_cw("first_detect exit");
3984 */
3985 }
3986 
3987 typedef struct{
3988 float pos;
3989 float s;
3990 float n;
3991 float ston;
3992 float s_avg;
3993 float n_avg;
3994 int cwptr;
3995 }STONDATA;
3996 
improve_cwspeed(void)3997 void improve_cwspeed(void)
3998 {
3999 int i, k, n, dashno;
4000 int repeat_flag;
4001 float r1, r3, t1, t2, t3;
4002 //double s_sum;
4003 //, n_sum;
4004 STONDATA *stondt;
4005 stondt=(STONDATA*)(fftn_tmp);
4006 // Collect the average waveform again.
4007 // We probably have some more dashes now and their positions are better
4008 // known as compared to the previous speed determination.
4009 check_cw(362003,1);
4010 if(kill_all_flag)return;
4011 repeat_flag=0;
4012 repeat:;
4013 check_cw(342003,1);
4014 if(kill_all_flag)return;
4015 seldash_cwspeed(0, no_of_cwdat);
4016 cw_ptr=0;
4017 check_cw(2003,1);
4018 if(kill_all_flag)return;
4019 dashno=0;
4020 t3=0;
4021 //s_sum=0;
4022 //n_sum=0;
4023 check_cw(22001,1);
4024 if(kill_all_flag)return;
4025 while(cw_ptr<no_of_cwdat)
4026   {
4027   t3+=cw[cw_ptr].sep;
4028   if(cw[cw_ptr].type == CW_DASH)
4029     {
4030     cg_wave_start=cw[cw_ptr].midpoint-0.5*dash_pts+baseband_size;
4031     cg_wave_start&=baseband_mask;
4032     fit_dash();
4033     PRT01"\n%3d %8.3f improve cwspeed [%8.3f] %8.3f fit=%8.5f",cw_ptr,t3,
4034                        cw[cw_ptr].midpoint, cg_wave_midpoint, cg_wave_fit);
4035     if(cg_wave_fit < DASH_MISFIT_LIMIT)
4036       {
4037       PRT01" removed");
4038       remove_dash();
4039       }
4040     else
4041       {
4042 check_cw(22002,1);
4043 if(kill_all_flag)return;
4044       cw[cw_ptr].coh_re=cg_wave_coh_re;
4045       cw[cw_ptr].coh_im=cg_wave_coh_im;
4046       cw[cw_ptr].midpoint=cg_wave_midpoint;
4047       if(cw_ptr > 0)
4048         {
4049         cw[cw_ptr].sep=cg_wave_midpoint-cw[cw_ptr-1].midpoint;
4050         if(cw[cw_ptr].sep < 0)cw[cw_ptr].sep+=baseband_size;
4051         }
4052       if(cw_ptr+1 < no_of_cwdat)
4053         {
4054         cw[cw_ptr+1].sep=cw[cw_ptr+1].midpoint-cg_wave_midpoint;
4055         if(cw[cw_ptr+1].sep < 0)cw[cw_ptr+1].sep+=baseband_size;
4056         }
4057       //      s_sum+=cg_wave_dat;
4058       //      n_sum+=cg_wave_err;
4059       stondt[dashno].s=cg_wave_dat;
4060       stondt[dashno].n=cg_wave_err;
4061       stondt[dashno].cwptr=cw_ptr;
4062       stondt[dashno].pos=t3;
4063       dashno++;
4064 check_cw(22003,1);
4065 if(kill_all_flag)return;
4066       }
4067     }
4068   cw_ptr++;
4069   }
4070 check_cw(22009,1);
4071 if(kill_all_flag)return;
4072 
4073 if(dashno <= MIN_DASHNO)return;
4074 stondt[dashno].pos=t3;
4075 check_cw(200591,1);
4076 if(kill_all_flag)return;
4077 // Use the data in stondt and to decide if the new data
4078 // has worsened the S/N ratio significantly.
4079 // If it has, the cw speed has changed or the
4080 // signal has degraded or disappeared.
4081 // Average S and N over 3 points.
4082 t1=stondt[0].s;
4083 r1=stondt[0].n;
4084 for(i=1; i<3; i++)
4085   {
4086   t1+=stondt[i].s;
4087   r1+=stondt[i].n;
4088   }
4089 stondt[0].s_avg=t1/3;
4090 stondt[0].n_avg=r1/3;
4091 stondt[0].ston=t1/r1;
4092 k=dashno-2;
4093 for(i=1; i<k; i++)
4094   {
4095   stondt[i].s_avg=t1/3;
4096   stondt[i].n_avg=r1/3;
4097   stondt[i].ston=t1/r1;
4098   t1+=stondt[i+2].s;
4099   r1+=stondt[i+2].n;
4100   t1-=stondt[i-1].s;
4101   r1-=stondt[i-1].n;
4102   }
4103 while(k<dashno)
4104   {
4105   stondt[k].s_avg=t1/3;
4106   stondt[k].n_avg=r1/3;
4107   stondt[k].ston=t1/r1;
4108   k++;
4109   }
4110 // Get the center of gravity of S/N assuming S/N is constant
4111 // in each interval (not very clever, but good enough for
4112 // our purpose. We use smoothed data points due to the averaging just done.)
4113 t1=stondt[0].pos;
4114 t3=0;
4115 k=dashno-1;
4116 r3=0;
4117 n=k/10;
4118 if(n<MIN_DASHNO/2)n=MIN_DASHNO/2;
4119 if(k-n < MIN_DASHNO)goto use_everything;
4120 for(i=n; i<k; i++)
4121   {
4122   t2=t1;
4123   t1=stondt[i].pos;
4124   r1=stondt[i-1].ston;
4125   if(r1>stondt[i+1].ston)r1=stondt[i+1].ston;
4126   t3+=(t1-t2)*r1*(t1+t2);
4127   r3+=(t1-t2)*r1;
4128   }
4129 t3/=r3;
4130 // t3 is now twice the center of gravity for the S/N function.
4131 // If it is much smaller than the total interval, the signal
4132 // has degraded significantly.
4133 if(t3 < 0.8*stondt[k].pos)
4134   {
4135 // The signal seems to have degraded.
4136 // Get the average S/N over the interval from 0 to t3 (weighted by S)
4137   PRT01"\nSignal seems to have degraded. %f  %f",t3,0.8*stondt[k].pos);
4138   i=0;
4139   t1=0;
4140   t2=0;
4141   while(stondt[i].pos<t3)
4142     {
4143     t1+=stondt[i].s*stondt[i].s/stondt[i].n;
4144     t2+=stondt[i].s;
4145     i++;
4146     }
4147   t1/=t2;
4148   PRT01"\nAvg S/N for good pts= %f  ",t1);
4149 // Step backwards until we find the first dash with S/N above the average.
4150   i=dashno-1;
4151   while( stondt[i].ston < t1)i--;
4152   t1=stondt[i].pos/stondt[dashno-1].pos;
4153   PRT01"  Good time is %6.2f%%",100*t1);
4154   if(t1 < 0.8)
4155     {
4156 // The signal has degraded for long enough so we better evaluate
4157 // the region up to the point in time defined by t1 before we
4158 // try to proceed with newer data.
4159 check_cw(322003,1);
4160 if(kill_all_flag)return;
4161     no_of_cwdat=stondt[i].cwptr+1;
4162     repeat_flag++;
4163 check_cw(332003,1);
4164 if(kill_all_flag)return;
4165     if( repeat_flag < 3)goto repeat;
4166     }
4167   }
4168 use_everything:;
4169 if(repeat_flag != 0)
4170   {
4171 // Treat old data first. Trying to improve the cw speed by including newer
4172 // data may make us try to fit the morse code to two different stations
4173 // that have different dash waveforms.
4174 // Change baseb_pc to reflect this decision.
4175   baseb_pc=cw[no_of_cwdat-1].midpoint;
4176   while(baseb_ramp[baseb_pc] > 0)baseb_pc =(baseb_pc+1)&baseband_mask;
4177   while(baseb_ramp[baseb_pc] < 0)baseb_pc =(baseb_pc+1)&baseband_mask;
4178   baseb_pc =(baseb_pc+baseband_mask)&baseband_mask;
4179   baseb_pe=baseb_pc;
4180   baseb_pd=baseb_pc;
4181   cw_detect_flag=CWDETECT_LIMITS_FOUND;
4182   PRT01"\n***   SET cw_detect_flag=CWDETECT_LIMITS_FOUND   ***");
4183   return;
4184   }
4185 t1=cw_stoninv;
4186 get_wb_average_dashes();
4187 guess_wb_average_dots();
4188 t2=collect_wb_ston();
4189 PRT01"\ncw_stoninv %f   old=%f",cw_stoninv,t1);
4190 for(i=0; i<dashno; i++)
4191   {
4192   PRT01"\n%2d [%7.2f]  S=%f   (S/N) %f   %d",i,stondt[i].pos,
4193                0.001*ZZ*stondt[i].s,
4194                 stondt[i].s/stondt[i].n,stondt[i].cwptr);
4195   }
4196 check_cw(2007,1);
4197 if(kill_all_flag)return;
4198 if(collect_wb_ston() < CW_WAVEFORM_MINSTON)
4199   {
4200   lirerr(8877266);
4201   }
4202 cw_detect_flag=CWDETECT_REGION_WAVEFORM_OK;
4203 PRT01"\n***   SET cw_detect_flag=CWDETECT_REGION_WAVEFORM_OK   ***");
4204 }
4205 
4206 
first_find_parts(void)4207 void first_find_parts(void)
4208 {
4209 int addno;
4210 // When we arrive here the keying speed and the waveforms are well known.
4211 // We have detected no_of_cwdat waveforms, many of them fit to a dash.
4212 // First look for recent dashes.
4213 check_cw(547203,1);
4214 if(kill_all_flag)return;
4215 if(PR02 == 1)show_cw("first_find_parts 1");
4216 get_recent_dashes();
4217 if(kill_all_flag)return;
4218 if(PR02 == 1)show_cw("first_find_parts 2");
4219 // Then collect old ones (if there are any)
4220 check_cw(552002,1);
4221 if(kill_all_flag)return;
4222 get_old_dashes();
4223 if(kill_all_flag)return;
4224 if(PR02 == 1)show_cw("first_find_parts 3");
4225 // Check S/N and place a pointer at the end of the current
4226 // transmission in case S/N is severely degraded.
4227 check_cw(552001,1);
4228 if(kill_all_flag)return;
4229 improve_cwspeed();
4230 if(kill_all_flag)return;
4231 // **********************************************************
4232 // **********************************************************
4233 // ******  Use the (hopefully) improved waveforms and *******
4234 // ******  search the entire region for good matches  *******
4235 // **********************************************************
4236 // **********************************************************
4237 more:;
4238 addno=short_region_guesses(0);
4239 check_cw(2010,1);
4240 if(kill_all_flag)return;
4241 if(PR02 == 1)show_cw("first_find_parts 4");
4242 if(addno > 0)
4243   {
4244   get_wb_average_dashes();
4245   guess_wb_average_dots();
4246   goto more;
4247   }
4248 addno=character_guesses();
4249 addno+=short_region_guesses(0);
4250 if(addno > 0)goto more;
4251 fprintf( dmp,"\nA cwbit_pts %f",cwbit_pts);
4252 decoded_cwspeed();
4253 fprintf( dmp,"\nB cwbit_pts %f",cwbit_pts);
4254 if(PR02 == 1)show_cw("first_find_parts 5");
4255 get_wb_average_dashes();
4256 get_wb_average_dots();
4257 short_region_guesses(0);
4258 mailbox[0]=9;
4259 short_region_guesses(1);
4260 
4261 addno=part_guesses();
4262 
4263 
4264 if(cw_detect_flag >= CWDETECT_LIMITS_FOUND)
4265   {
4266   return;
4267   }
4268 cw_detect_flag=CWDETECT_SOME_PARTS_FITTED;
4269 PRT08"\n***   SET cw_detect_flag=CWDETECT_SOME_PARTS_FITTED   ***");
4270 baseb_pe=baseb_pc;
4271 baseb_pd=baseb_pc;
4272 }
4273 
set_baseb_pc(void)4274 void set_baseb_pc(void)
4275 {
4276 int ia,ib;
4277 // Make a first decision key up/key down based on signal power.
4278 // This is the conventional approach, a matched filter (the operator
4279 // has to select the optimum bandwidth) followed by a squarelaw detector.
4280 // The threshold is conventionally kept at a fixed level but here it is
4281 // very close to the noise when no signal is present. while it is at
4282 // half the peak amplitude for strong signals.
4283 // Store the result in baseb_ramp as ramps.
4284 // Positive values indicate key down while negative values
4285 // indicate key up (or signal too weak)
4286 ia=baseb_pc;
4287 ib=(ia+baseband_mask)&baseband_mask;
4288 while( ia != baseb_pb )
4289   {
4290   if(baseb_totpwr[ia] > baseb_threshold[ia])
4291     {
4292     if(baseb_ramp[ib]>0)
4293       {
4294       baseb_ramp[ia]=baseb_ramp[ib]+1;
4295       }
4296     else
4297       {
4298       baseb_ramp[ia]=1;
4299       }
4300     }
4301   else
4302     {
4303     if(baseb_ramp[ib]<0)
4304       {
4305       baseb_ramp[ia]=baseb_ramp[ib]-1;
4306       }
4307     else
4308       {
4309       baseb_ramp[ia]=-1;
4310       }
4311     }
4312   ib=ia;
4313   ia=(ia+1)&baseband_mask;
4314   }
4315 if(baseb_ramp[ib]>0)ib=(ib-baseb_ramp[ib]+baseband_size)&baseband_mask;
4316 baseb_pc=ib;
4317 }
4318 
second_find_parts(void)4319 void second_find_parts(void)
4320 {
4321 int  old_no_of_dashes;
4322 // When we arrive here the keying speed and the waveforms are well known.
4323 // We have detected no_of_cwdat waveforms, most of them dashes, but
4324 // maybe also some dots and spaces.
4325 // First look for recent dashes.
4326 old_no_of_dashes=no_of_cwdat;
4327 set_baseb_pc();
4328 check_cw(252501,1);
4329 if(kill_all_flag)return;
4330 get_recent_dashes();
4331 if(kill_all_flag)return;
4332 // Fit dashes and dots in short gaps and next to
4333 // dashes in the new region.
4334 check_cw(251502,1);
4335 if(kill_all_flag)return;
4336 first_detect(old_no_of_dashes-1);
4337 if(kill_all_flag)return;
4338 if(old_no_of_dashes != no_of_cwdat)
4339   {
4340   improve_cwspeed();
4341 if(kill_all_flag)return;
4342   if(cw_detect_flag >= CWDETECT_LIMITS_FOUND)
4343     {
4344     second_detect();
4345     if(PR08 != 0)
4346       {
4347       char s[80];
4348       sprintf(s,"second_find_parts (flag=%d)",cw_detect_flag);
4349       show_cw(s);
4350       }
4351     return;
4352     }
4353   old_no_of_dashes=no_of_cwdat;
4354   }
4355 // Try to fit more dots and dashes in the whole region from 0 to no_of_cwdat.
4356 second_detect();
4357 if(PR08 != 0)show_cw("second_find_parts (flag unchanged)");
4358 baseb_pe=baseb_pc;
4359 baseb_pd=baseb_pc;
4360 }
4361 
4362 
4363 
4364 
cw_decode(void)4365 void cw_decode(void)
4366 {
4367 /*
4368 XZ("------      cw_decode      ---------");
4369 if(PR09 != 0)show_cw("cw_decode A");
4370 second_find_parts();
4371 if(PR09 != 0)show_cw("cw_decode B");
4372 decoded_cwspeed();
4373 if(PR09 != 0)show_cw("cw_decode C");
4374 continued_morse_decode();
4375 */
4376 
4377 }
4378 
cw_decode_region(void)4379 void cw_decode_region(void)
4380 {
4381 XZ("cw_decode_region(do nothing)");
4382 }
4383 
4384 
4385 
init_cw_decode(void)4386 void init_cw_decode(void)
4387 {
4388 // We decode because S/N is already good enough to perhaps allow it.
4389 // Some more information may have arrived.
4390 // Process it first and return if flag says the signal disappeared.
4391 cw_detect_flag=CWDETECT_DEBUG_STOP;
4392 return;
4393 
4394 second_find_parts();
4395 if(cw_detect_flag != CWDETECT_REGION_WAVEFORM_OK)
4396   {
4397   XZ("\nEND OF REGION!!!");
4398   return;
4399   }
4400 decoded_cwspeed();
4401 check_cw(256702,1);
4402 if(kill_all_flag)return;
4403 // Try to find complete characters
4404 if(PR09 != 0)show_cw("init_cw_decode 1");
4405 first_morse_decode();
4406 if(kill_all_flag)return;
4407 if(PR09 != 0)show_cw("init_cw_decode 2");
4408 check_cw(256703,1);
4409 if(kill_all_flag)return;
4410 if(cw_decoded_chars != 0)
4411   {
4412   cw_detect_flag=CWDETECT_SOME_ASCII_FITTED;
4413   XZ("\nOKOKOKOKOKOKOK");
4414 //show_cw("Set detect_flag to CWDETECT_SOME_ASCII_FITTED");
4415   }
4416 else
4417   {
4418 fprintf( dmp,"\nno_of_cwdat %d  no_of_cwdat-correlate_no_of_cwdat %d",
4419      no_of_cwdat, no_of_cwdat-correlate_no_of_cwdat);
4420 fprintf( dmp,"\n pa %d  pb %d  pc %d  pd %d  pe %d",
4421            baseb_pa, baseb_pb, baseb_pc, baseb_pd, baseb_pe);
4422 
4423 
4424 
4425 
4426   if(no_of_cwdat > 25 && no_of_cwdat-correlate_no_of_cwdat > 2)
4427     {
4428     correlate_undecoded_baseband();
4429     correlate_no_of_cwdat=no_of_cwdat;
4430 
4431 // ö update baseb_px and other pointers as well as cw[] and no_of_cwdat
4432 // if correlate failed and data is becoming too old.
4433 
4434     }
4435   }
4436 }
4437 
init_cw_decode_region(void)4438 void init_cw_decode_region(void)
4439 {
4440 decoded_cwspeed();
4441 first_morse_decode();
4442 cw_detect_flag=CWDETECT_REGION_INITIATED;
4443 }
4444