@@ -215,7 +215,7 @@ void usage(void)
215215 "\t[-F fir_size (default: off)]\n"
216216 "\t enables low-leakage downsample filter\n"
217217 "\t size can be 0 or 9. 0 has bad roll off\n"
218- "\t[-A std/fast/lut choose atan math (default: std)]\n"
218+ "\t[-A std/fast/lut/ale choose atan math (default: std)]\n"
219219 //"\t[-C clip_path (default: off)\n"
220220 //"\t (create time stamped raw clips, requires squelch)\n"
221221 //"\t (path must have '\%s' and will expand to date_time_freq)\n"
@@ -515,6 +515,24 @@ int polar_disc_lut(int ar, int aj, int br, int bj)
515515 return 0 ;
516516}
517517
518+ int esbensen (int ar , int aj , int br , int bj )
519+ /*
520+ input signal: s(t) = a*exp(-i*w*t+p)
521+ a = amplitude, w = angular freq, p = phase difference
522+ solve w
523+ s' = -i(w)*a*exp(-i*w*t+p)
524+ s'*conj(s) = -i*w*a*a
525+ s'*conj(s) / |s|^2 = -i*w
526+ */
527+ {
528+ int cj , dr , dj ;
529+ int scaled_pi = 2608 ; /* 1<<14 / (2*pi) */
530+ dr = (br - ar ) * 2 ;
531+ dj = (bj - aj ) * 2 ;
532+ cj = bj * dr - br * dj ; /* imag(ds*conj(s)) */
533+ return (scaled_pi * cj / (ar * ar + aj * aj + 1 ));
534+ }
535+
518536void fm_demod (struct demod_state * fm )
519537{
520538 int i , pcm ;
@@ -536,6 +554,10 @@ void fm_demod(struct demod_state *fm)
536554 pcm = polar_disc_lut (lp [i ], lp [i + 1 ],
537555 lp [i - 2 ], lp [i - 1 ]);
538556 break ;
557+ case 3 :
558+ pcm = esbensen (lp [i ], lp [i + 1 ],
559+ lp [i - 2 ], lp [i - 1 ]);
560+ break ;
539561 }
540562 fm -> result [i /2 ] = (int16_t )pcm ;
541563 }
@@ -1122,6 +1144,8 @@ int main(int argc, char **argv)
11221144 if (strcmp ("lut" , optarg ) == 0 ) {
11231145 atan_lut_init ();
11241146 demod .custom_atan = 2 ;}
1147+ if (strcmp ("ale" , optarg ) == 0 ) {
1148+ demod .custom_atan = 3 ;}
11251149 break ;
11261150 case 'M' :
11271151 if (strcmp ("fm" , optarg ) == 0 ) {
0 commit comments