1 /********************************************************************
3 * THIS FILE IS PART OF THE OggGhost SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggGhost SOURCE CODE IS (C) COPYRIGHT 2007-2011 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: research-grade chirp estimation code
16 Provides a set of chirp estimation algorithm variants for comparison
17 and characterization. This is canned code meant for testing and
18 exploration of sinusoidal estimation. It's designed to be held still
19 and used for reference and comparison against later improvement.
20 Please, don't optimize this code. Test optimizations elsewhere in
21 code to be compared to this code. Roll new technique improvements
22 into this reference set only after they have been completed.
24 ********************************************************************/
34 static int cmp_descending_A(const void *p1
, const void *p2
){
35 chirp
*A
= (chirp
*)p1
;
36 chirp
*B
= (chirp
*)p2
;
38 return (A
->A
<B
->A
) - (B
->A
<A
->A
);
40 static int cmp_ascending_W(const void *p1
, const void *p2
){
41 chirp
*A
= (chirp
*)p1
;
42 chirp
*B
= (chirp
*)p2
;
44 return (B
->W
<A
->W
) - (A
->W
<B
->W
);
47 /* The stimators project a residue vecotr onto basis functions; the
48 results of the accumulation map directly to the parameters we're
49 interested in (A, P, W, dA, dW, ddA) and vice versa. The mapping
50 equations are broken out below. */
52 static float toA(float Ai
, float Bi
){
55 static float toP(float Ai
, float Bi
){
56 return -atan2f(Bi
, Ai
);
58 static float toW(float Ai
, float Bi
, float Ci
, float Di
){
59 return (Ai
*Ai
|| Bi
*Bi
) ? (Ci
*Bi
- Di
*Ai
)/(Ai
*Ai
+ Bi
*Bi
) : 0;
61 static float todA(float Ai
, float Bi
, float Ci
, float Di
){
62 return (Ai
*Ai
|| Bi
*Bi
) ? (Ci
*Ai
+ Di
*Bi
)/hypotf(Ai
,Bi
) : 0;
64 static float todW(float Ai
, float Bi
, float Ei
, float Fi
){
65 return (Ai
*Ai
|| Bi
*Bi
) ? (Ei
*Bi
- Fi
*Ai
)/(Ai
*Ai
+ Bi
*Bi
) : 0;
67 static float toddA(float Ai
, float Bi
, float Ei
, float Fi
){
68 return (Ai
*Ai
|| Bi
*Bi
) ? (Ei
*Ai
+ Fi
*Bi
)/hypotf(Ai
,Bi
) : 0;
71 static float toAi(float A
, float P
){
74 static float toBi(float A
, float P
){
78 static float WtoCi(float A
, float P
, float W
){
82 static float WtoDi(float A
, float P
, float W
){
86 static float dWtoEi(float A
, float P
, float dW
){
89 static float dWtoFi(float A
, float P
, float dW
){
93 static float dAtoCi(float P
, float dA
){
96 static float dAtoDi(float P
, float dA
){
99 static float ddAtoEi(float P
, float ddA
){
102 static float ddAtoFi(float P
, float ddA
){
106 /* fully nonlinear estimation iterator; it restarts the basis
107 functions (W and dW) and error vector for each chirp after each new
108 fit. Reconstruction (and thus error) are exact calculations. */
109 static int full_nonlinear_iterate(const float *x
,
137 /* Build a starting reconstruction based on the passed-in initial
139 memset(y
,0,sizeof(*y
)*len
);
142 double jj
= j
-len
*.5+.5;
143 float a
= cc
[i
].A
+ (cc
[i
].dA
+ cc
[i
].ddA
*jj
)*jj
;
144 y
[j
] += a
*cos((cc
[i
].W
+ cc
[i
].dW
*jj
)*jj
+ cc
[i
].P
);
148 /* outer fit iteration */
149 while(flag
&& iter_limit
>0){
152 /* precompute the portion of the projection/fit estimate shared by
153 the zero, first and second order fits. Subtracts the current
154 best fits from the input signal and windows the result. */
156 r
[j
]=(x
[j
]-y
[j
])*window
[j
];
157 memset(y
,0,sizeof(*y
)*len
);
159 /* Sort chirps by descending amplitude */
160 qsort(cc
, n
, sizeof(*cc
), cmp_descending_A
);
173 float aC
= cos(c
->P
);
174 float aS
= sin(c
->P
);
177 if(c
->A
==-1) continue;
181 /* no part of the nonlinear algorithm requires double
182 precision, however the largest source of noise will be from
183 a naive computation of the instantaneous basis or
184 reconstruction chirp phase. Because dW is usually very
185 small compared to W (especially c->W*jj), (W + dW*jj)*jj
186 quickly becomes noticably short of significant bits.
188 We can either calculate everything mod 2PI, use a double
189 for just this calculation (and passing the result to
190 sincos) or decide we don't care. In the production code we
191 will probably not care as most of the depth in the
192 estimator isn't needed. Here we'll take the easiest route
193 to have a deep reference and just use doubles. */
195 double jj
= j
-len
*.5+.5;
201 sincos((c
->W
+ c
->dW
*jj
)*jj
,&si
,&co
);
206 /* add the current estimate back to the residue vector */
207 r
[j
] += (aC
*co
-aS
*si
) * (c
->A
+ (c
->dA
+ c
->ddA
*jj
)*jj
);
212 /* zero order projection */
215 /* first order projection */
218 /* second order projection */
223 /* subtract zero order estimate from first */
226 /* subtract zero order estimate from second */
229 /* subtract first order estimate from second */
235 /* accumulate per-basis energy for normalization */
245 /* normalize, complete projections */
251 eP
= (eP
-aP
*eP2
-cP
*eP3
)*E2
;
252 fP
= (fP
-bP
*fP2
-dP
*fP3
)*E2
;
254 aP
= (aE
>1e-20f
?aP
/aE
:0.f
);
255 bP
= (bE
>1e-20f
?bP
/bE
:0.f
);
256 cP
= (cE
>1e-20f
?(cP
-aP
*cP2
)/cE
:0.f
);
257 dP
= (dE
>1e-20f
?(dP
-bP
*dP2
)/dE
:0.f
);
258 eP
= (eE
>1e-20f
?(eP
-aP
*eP2
-cP
*eP3
)/eE
:0.f
);
259 fP
= (fE
>1e-20f
?(fP
-bP
*fP2
-dP
*fP3
)/fE
:0.f
);
264 if(!fitdW
&& !fitddA
)
267 move
= aP
*aP
+ bP
*bP
;
269 /* we're fitting to the remaining error; add the fit to date
270 back in to relate our newest incremental results to the
271 global fit so far. Note that this does not include W (or dW
272 if it is also recentered), as they're already 'subtracted'
273 when the bases are recentered each iteration */
274 aP
+= toAi(c
->A
, c
->P
);
275 bP
+= toBi(c
->A
, c
->P
);
276 cP
+= dAtoCi(c
->P
,c
->dA
);
277 dP
+= dAtoDi(c
->P
,c
->dA
);
278 eP
+= ddAtoEi(c
->P
,c
->ddA
);
279 fP
+= ddAtoFi(c
->P
,c
->ddA
);
282 if((aP
*aP
+ bP
*bP
)>1e10
||
283 (cP
*cP
+ dP
*dP
)>1e10
||
284 (eP
*eP
+ fP
*fP
)>1e10
){
285 /* mark this chirp inactive */
295 /* save new estimate */
298 c
->W
+= fit_W_alpha
*(fitW
? toW(aP
,bP
,cP
,dP
) : 0);
299 c
->dA
= (fitdA
? todA(aP
,bP
,cP
,dP
) : 0);
300 c
->dW
+= fit_dW_alpha
*(fitdW
? todW(aP
,bP
,eP
,fP
) : 0);
301 c
->ddA
= (fitddA
? toddA(aP
,bP
,eP
,fP
) : 0);
303 /* base convergence on basis projection movement this
304 iteration, but only consider the contribution of terms we fit. */
307 float W
= c
->W
- old
.W
;
308 cc
+= WtoCi(c
->A
,c
->P
,W
);
309 dd
+= WtoDi(c
->A
,c
->P
,W
);
312 float dA
= c
->dA
- old
.dA
;
313 cc
+= dAtoCi(c
->P
,dA
);
314 dd
+= dAtoDi(c
->P
,dA
);
317 float dW
= c
->dW
- old
.dW
;
318 ee
+= dWtoEi(c
->A
,c
->P
,dW
);
319 ff
+= dWtoFi(c
->A
,c
->P
,dW
);
322 float ddA
= c
->ddA
- old
.ddA
;
323 ee
+= ddAtoEi(c
->P
,ddA
);
324 ff
+= ddAtoFi(c
->P
,ddA
);
326 move
= move
+ cc
*cc
+ dd
*dd
+ ee
*ee
+ ff
*ff
;
327 if(fit_limit
>0 && move
>fit_limit
*fit_limit
)flag
=1;
328 if(fit_limit
<0 && move
>1e-14)flag
=1;
332 /* do not allow negative or trans-Nyquist center frequencies */
334 c
->W
= 0; /* clamp frequency to 0 (DC) */
335 c
->dW
= 0; /* if W is 0, the chirp rate must also be 0 to
336 avoid negative frequencies */
339 c
->W
= M_PI
; /* clamp frequency to Nyquist */
340 c
->dW
= 0; /* if W is at Nyquist, the chirp rate must
341 also be 0 to avoid trans-Nyquist
344 /* Just like with the center frequency, don't allow the
345 chirp rate (dW) parameter to cross over to a negative
346 instantaneous frequency */
347 if(c
->W
+c
->dW
*len
< 0)
349 if(c
->W
-c
->dW
*len
< 0)
351 /* ...or exceed Nyquist */
352 if(c
->W
+ c
->dW
*len
> M_PI
)
353 c
->dW
= M_PI
/len
- c
->W
/len
;
354 if(c
->W
- c
->dW
*len
> M_PI
)
355 c
->dW
= c
->W
/len
- M_PI
/len
;
358 /* update the reconstruction/residue vectors with new fit */
361 double jj
= j
-len
*.5+.5;
362 float a
= c
->A
+ (c
->dA
+ c
->ddA
*jj
)*jj
;
363 float v
= a
*cos(c
->P
+ (c
->W
+ c
->dW
*jj
)*jj
);
369 if(flag
)iter_limit
--;
375 /* partial-nonlinear estimation iterator; it restarts the basis
376 functions (W only). Reconstruction and error are approximated from
377 basis (as done in the original paper). Basis function is not
378 chirped, regardless of initial dW estimate */
379 static int partial_nonlinear_iterate(const float *x
,
405 float *tcos_table
[n
];
406 float *tsin_table
[n
];
407 float *ttcos_table
[n
];
408 float *ttsin_table
[n
];
409 float cosE
[n
], sinE
[n
];
410 float tcosE
[n
], tsinE
[n
];
411 float ttcosE
[n
], ttsinE
[n
];
412 float tcosC2
[n
], tsinC2
[n
];
413 float ttcosC2
[n
], ttsinC2
[n
];
414 float ttcosC3
[n
], ttsinC3
[n
];
421 cos_table
[i
]=calloc(len
,sizeof(**cos_table
));
422 sin_table
[i
]=calloc(len
,sizeof(**sin_table
));
423 tcos_table
[i
]=calloc(len
,sizeof(**tcos_table
));
424 tsin_table
[i
]=calloc(len
,sizeof(**tsin_table
));
425 ttcos_table
[i
]=calloc(len
,sizeof(**ttcos_table
));
426 ttsin_table
[i
]=calloc(len
,sizeof(**ttsin_table
));
429 /* outer fit iteration */
430 while(flag
&& iter_limit
>0){
432 memset(y
,0,sizeof(y
));
434 /* Sort chirps by descending amplitude */
435 qsort(ch
, n
, sizeof(*ch
), cmp_descending_A
);
437 /* Calculate new basis functions */
451 if(ch
[i
].A
==-1) continue;
453 /* chirp param -> basis acc */
454 ai
[i
] = toAi(ch
[i
].A
, ch
[i
].P
);
455 bi
[i
] = toBi(ch
[i
].A
, ch
[i
].P
);
456 ci
[i
] = dAtoCi(ch
[i
].P
, ch
[i
].dA
);
457 di
[i
] = dAtoDi(ch
[i
].P
, ch
[i
].dA
);
458 ei
[i
] = ddAtoEi(ch
[i
].P
, ch
[i
].ddA
) + dWtoEi(ch
[i
].A
, ch
[i
].P
, ch
[i
].dW
);
459 fi
[i
] = ddAtoFi(ch
[i
].P
, ch
[i
].ddA
) + dWtoFi(ch
[i
].A
, ch
[i
].P
, ch
[i
].dW
);
462 double jj
= j
-len
/2.+.5;
464 sincos(ch
[i
].W
*jj
,&s
,&c
);
466 /* save basis funcs */
467 /* calc reconstruction vector */
469 ai
[i
]*(cos_table
[i
][j
] = c
) +
470 bi
[i
]*(sin_table
[i
][j
] = s
) +
471 ci
[i
]*(tcos_table
[i
][j
] = jj
*c
) +
472 di
[i
]*(tsin_table
[i
][j
] = jj
*s
) +
473 ei
[i
]*(ttcos_table
[i
][j
] = jj
*jj
*c
) +
474 fi
[i
]*(ttsin_table
[i
][j
] = jj
*jj
*s
);
476 /* The modulation terms */
477 tmpc
+= tcos_table
[i
][j
]*tcos_table
[i
][j
]*window
[j
]*window
[j
];
478 tmpd
+= tsin_table
[i
][j
]*tsin_table
[i
][j
]*window
[j
]*window
[j
];
481 /* The sinusoidal terms */
482 tmpa
+= cos_table
[i
][j
]*cos_table
[i
][j
]*window
[j
]*window
[j
];
483 tmpb
+= sin_table
[i
][j
]*sin_table
[i
][j
]*window
[j
]*window
[j
];
485 /* The second order modulations */
486 tmpe
+= ttcos_table
[i
][j
]*ttcos_table
[i
][j
]*window
[j
]*window
[j
];
487 tmpf
+= ttsin_table
[i
][j
]*ttsin_table
[i
][j
]*window
[j
]*window
[j
];
492 tmpc2
+= cos_table
[i
][j
]*tcos_table
[i
][j
]*window
[j
]*window
[j
];
493 tmpd2
+= sin_table
[i
][j
]*tsin_table
[i
][j
]*window
[j
]*window
[j
];
494 tmpe3
+= tcos_table
[i
][j
]*ttcos_table
[i
][j
]*window
[j
]*window
[j
];
495 tmpf3
+= tsin_table
[i
][j
]*ttsin_table
[i
][j
]*window
[j
]*window
[j
];
499 /* Set basis normalizations */
501 cosE
[i
] = sinE
[i
] = E0
;
502 tcosE
[i
] = tsinE
[i
] = E1
;
503 ttcosE
[i
] = ttsinE
[i
] = E2
;
505 cosE
[i
] = (tmpa
>1e-20f
? 1.f
/tmpa
: 0);
506 sinE
[i
] = (tmpb
>1e-20f
? 1.f
/tmpb
: 0);
507 tcosE
[i
] = (tmpc
>1e-20f
? 1.f
/tmpc
: 0);
508 tsinE
[i
] = (tmpd
>1e-20f
? 1.f
/tmpd
: 0);
509 ttcosE
[i
] = (tmpe
>1e-20f
? 1.f
/tmpe
: 0);
510 ttsinE
[i
] = (tmpf
>1e-20f
? 1.f
/tmpf
: 0);
514 /* set gs fit terms */
526 float tmpa
=0, tmpb
=0;
527 float tmpc
=0, tmpd
=0;
528 float tmpe
=0, tmpf
=0;
530 /* (Sort of) project the residual on the four basis functions */
532 float r
= (x
[j
]-y
[j
])*window
[j
]*window
[j
];
533 tmpa
+= r
*cos_table
[i
][j
];
534 tmpb
+= r
*sin_table
[i
][j
];
535 tmpc
+= r
*tcos_table
[i
][j
];
536 tmpd
+= r
*tsin_table
[i
][j
];
537 tmpe
+= r
*ttcos_table
[i
][j
];
538 tmpf
+= r
*ttsin_table
[i
][j
];
545 tmpc
-= tmpa
*tcosC2
[i
];
546 tmpd
-= tmpb
*tsinC2
[i
];
553 tmpe
-= tmpa
*ttcosC2
[i
] + tmpc
*ttcosC3
[i
];
554 tmpf
-= tmpb
*ttsinC2
[i
] + tmpd
*ttsinC3
[i
];
562 if(!fitdW
&& !fitddA
)
565 /* Update the signal approximation for the next iteration */
568 tmpa
*cos_table
[i
][j
]+
569 tmpb
*sin_table
[i
][j
]+
570 tmpc
*tcos_table
[i
][j
]+
571 tmpd
*tsin_table
[i
][j
]+
572 tmpe
*ttcos_table
[i
][j
]+
573 tmpf
*ttsin_table
[i
][j
];
584 if((ai
[i
]*ai
[i
] + bi
[i
]*bi
[i
])>1e10
||
585 (ci
[i
]*ci
[i
] + di
[i
]*di
[i
])>1e10
||
586 (ei
[i
]*ei
[i
] + fi
[i
]*fi
[i
])>1e10
){
589 ai
[i
]*cos_table
[i
][j
]+
590 bi
[i
]*sin_table
[i
][j
]+
591 ci
[i
]*tcos_table
[i
][j
]+
592 di
[i
]*tsin_table
[i
][j
]+
593 ei
[i
]*ttcos_table
[i
][j
]+
594 fi
[i
]*ttsin_table
[i
][j
];
600 /* save new estimate */
601 ch
[i
].A
= toA(ai
[i
],bi
[i
]);
602 ch
[i
].P
= toP(ai
[i
],bi
[i
]);
603 ch
[i
].W
+= fit_W_alpha
*(fitW
? toW(ai
[i
],bi
[i
],ci
[i
],di
[i
]) : 0);
604 ch
[i
].dA
= (fitdA
? todA(ai
[i
],bi
[i
],ci
[i
],di
[i
]) : 0);
605 ch
[i
].dW
= (fitdW
? todW(ai
[i
],bi
[i
],ei
[i
],fi
[i
]) : 0);
606 ch
[i
].ddA
= (fitddA
? toddA(ai
[i
],bi
[i
],ei
[i
],fi
[i
]) : 0);
608 /* base convergence on basis projection movement this
609 iteration, but only consider the contribution of terms we fit. */
615 float W
= toW(ai
[i
],bi
[i
],ci
[i
],di
[i
]);
616 cc
+= WtoCi(ch
[i
].A
,ch
[i
].P
,W
);
617 dd
+= WtoDi(ch
[i
].A
,ch
[i
].P
,W
);
620 float dA
= todA(ai
[i
],bi
[i
],tmpc
,tmpd
);
621 cc
+= dAtoCi(ch
[i
].P
,dA
);
622 dd
+= dAtoDi(ch
[i
].P
,dA
);
625 float dW
= todW(ai
[i
],bi
[i
],tmpe
,tmpf
);
626 ee
+= dWtoEi(ch
[i
].A
,ch
[i
].P
,dW
);
627 ff
+= dWtoFi(ch
[i
].A
,ch
[i
].P
,dW
);
630 float ddA
= toddA(ai
[i
],bi
[i
],tmpe
,tmpf
);
631 ee
+= ddAtoEi(ch
[i
].P
,ddA
);
632 ff
+= ddAtoFi(ch
[i
].P
,ddA
);
634 move
= tmpa
*tmpa
+ tmpb
*tmpb
+ cc
*cc
+ dd
*dd
+ ee
*ee
+ ff
*ff
;
635 if(fit_limit
>0 && move
>fit_limit
*fit_limit
)flag
=1;
636 if(fit_limit
<0 && move
>1e-14)flag
=1;
639 if(flag
)iter_limit
--;
647 free(ttcos_table
[i
]);
648 free(ttsin_table
[i
]);
654 /* linear estimation iterator; sets fixed basis functions for each
655 chirp according to the passed in initial estimates. This code
656 follows the paper as exactly as possible (reconstruction is
657 estimated from basis, basis is not chirped regardless of initial
659 static int linear_iterate(const float *x
,
680 float *tcos_table
[n
];
681 float *tsin_table
[n
];
682 float *ttcos_table
[n
];
683 float *ttsin_table
[n
];
684 float cosE
[n
], sinE
[n
];
685 float tcosE
[n
], tsinE
[n
];
686 float ttcosE
[n
], ttsinE
[n
];
687 float tcosC2
[n
], tsinC2
[n
];
688 float ttcosC2
[n
], ttsinC2
[n
];
689 float ttcosC3
[n
], ttsinC3
[n
];
698 memset(y
,0,sizeof(y
));
713 if(ch
[i
].A
==-1)continue;
715 /* seed the basis accumulators from our passed in estimated parameters */
716 /* Don't add in W; this is already included by the basis */
717 ai
[i
] = toAi(ch
[i
].A
, ch
[i
].P
);
718 bi
[i
] = toBi(ch
[i
].A
, ch
[i
].P
);
719 ci
[i
] = dAtoCi(ch
[i
].P
,ch
[i
].dA
);
720 di
[i
] = dAtoDi(ch
[i
].P
,ch
[i
].dA
);
721 ei
[i
] = ddAtoEi(ch
[i
].P
, ch
[i
].ddA
) + dWtoEi(ch
[i
].A
, ch
[i
].P
, ch
[i
].dW
);
722 fi
[i
] = ddAtoFi(ch
[i
].P
, ch
[i
].ddA
) + dWtoFi(ch
[i
].A
, ch
[i
].P
, ch
[i
].dW
);
724 /* Build a table for the basis functions at each frequency */
725 cos_table
[i
]=calloc(len
,sizeof(**cos_table
));
726 sin_table
[i
]=calloc(len
,sizeof(**sin_table
));
727 tcos_table
[i
]=calloc(len
,sizeof(**tcos_table
));
728 tsin_table
[i
]=calloc(len
,sizeof(**tsin_table
));
729 ttcos_table
[i
]=calloc(len
,sizeof(**ttcos_table
));
730 ttsin_table
[i
]=calloc(len
,sizeof(**ttsin_table
));
733 double jj
= j
-len
/2.+.5;
735 sincos(ch
[i
].W
*jj
,&s
,&c
);
737 /* save basis funcs */
738 /* initial reconstruction */
740 ai
[i
]*(cos_table
[i
][j
] = c
) +
741 bi
[i
]*(sin_table
[i
][j
] = s
) +
742 ci
[i
]*(tcos_table
[i
][j
] = jj
*c
) +
743 di
[i
]*(tsin_table
[i
][j
] = jj
*s
) +
744 ei
[i
]*(ttcos_table
[i
][j
] = jj
*jj
*c
) +
745 fi
[i
]*(ttsin_table
[i
][j
] = jj
*jj
*s
);
747 /* The sinusoidal terms */
748 tmpa
+= cos_table
[i
][j
]*cos_table
[i
][j
]*window
[j
]*window
[j
];
749 tmpb
+= sin_table
[i
][j
]*sin_table
[i
][j
]*window
[j
]*window
[j
];
751 /* The modulation terms */
752 tmpc
+= tcos_table
[i
][j
]*tcos_table
[i
][j
]*window
[j
]*window
[j
];
753 tmpd
+= tsin_table
[i
][j
]*tsin_table
[i
][j
]*window
[j
]*window
[j
];
755 /* The second order modulations */
756 tmpe
+= ttcos_table
[i
][j
]*ttcos_table
[i
][j
]*window
[j
]*window
[j
];
757 tmpf
+= ttsin_table
[i
][j
]*ttsin_table
[i
][j
]*window
[j
]*window
[j
];
760 tmpc2
+= cos_table
[i
][j
]*tcos_table
[i
][j
]*window
[j
]*window
[j
];
761 tmpd2
+= sin_table
[i
][j
]*tsin_table
[i
][j
]*window
[j
]*window
[j
];
762 tmpe3
+= tcos_table
[i
][j
]*ttcos_table
[i
][j
]*window
[j
]*window
[j
];
763 tmpf3
+= tsin_table
[i
][j
]*ttsin_table
[i
][j
]*window
[j
]*window
[j
];
767 /* Set basis normalizations */
769 cosE
[i
] = sinE
[i
] = E0
;
770 tcosE
[i
] = tsinE
[i
] = E1
;
771 ttcosE
[i
] = ttsinE
[i
] = E2
;
773 cosE
[i
] = (tmpa
>1e-20f
? 1.f
/tmpa
: 0);
774 sinE
[i
] = (tmpb
>1e-20f
? 1.f
/tmpb
: 0);
775 tcosE
[i
] = (tmpc
>1e-20f
? 1.f
/tmpc
: 0);
776 tsinE
[i
] = (tmpd
>1e-20f
? 1.f
/tmpd
: 0);
777 ttcosE
[i
] = (tmpe
>1e-20f
? 1.f
/tmpe
: 0);
778 ttsinE
[i
] = (tmpf
>1e-20f
? 1.f
/tmpf
: 0);
781 /* set gs fit terms */
791 while(flag
&& iter_limit
>0){
796 float tmpa
=0, tmpb
=0;
797 float tmpc
=0, tmpd
=0;
798 float tmpe
=0, tmpf
=0;
800 /* (Sort of) project the residual on the four basis functions */
802 float r
= (x
[j
]-y
[j
])*window
[j
]*window
[j
];
803 tmpa
+= r
*cos_table
[i
][j
];
804 tmpb
+= r
*sin_table
[i
][j
];
805 tmpc
+= r
*tcos_table
[i
][j
];
806 tmpd
+= r
*tsin_table
[i
][j
];
807 tmpe
+= r
*ttcos_table
[i
][j
];
808 tmpf
+= r
*ttsin_table
[i
][j
];
815 tmpc
-= tmpa
*tcosC2
[i
];
816 tmpd
-= tmpb
*tsinC2
[i
];
823 tmpe
-= tmpa
*ttcosC2
[i
] + tmpc
*ttcosC3
[i
];
824 tmpf
-= tmpb
*ttsinC2
[i
] + tmpd
*ttsinC3
[i
];
832 if(!fitdW
&& !fitddA
)
835 /* Update the signal approximation for the next iteration */
838 tmpa
*cos_table
[i
][j
]+
839 tmpb
*sin_table
[i
][j
]+
840 tmpc
*tcos_table
[i
][j
]+
841 tmpd
*tsin_table
[i
][j
]+
842 tmpe
*ttcos_table
[i
][j
]+
843 tmpf
*ttsin_table
[i
][j
];
854 if((ai
[i
]*ai
[i
] + bi
[i
]*bi
[i
])>1e10
||
855 (ci
[i
]*ci
[i
] + di
[i
]*di
[i
])>1e10
||
856 (ei
[i
]*ei
[i
] + fi
[i
]*fi
[i
])>1e10
){
859 ai
[i
]*cos_table
[i
][j
]+
860 bi
[i
]*sin_table
[i
][j
]+
861 ci
[i
]*tcos_table
[i
][j
]+
862 di
[i
]*tsin_table
[i
][j
]+
863 ei
[i
]*ttcos_table
[i
][j
]+
864 fi
[i
]*ttsin_table
[i
][j
];
870 /* base convergence on basis projection movement this
873 float move
= tmpa
*tmpa
+ tmpb
*tmpb
+tmpc
*tmpc
+ tmpd
*tmpd
+ tmpe
*tmpe
+ tmpf
*tmpf
;
875 if(fit_limit
>0 && move
>fit_limit
*fit_limit
)flag
=1;
876 if(fit_limit
<0 && move
>1e-14)flag
=1;
881 if(flag
)iter_limit
--;
886 ch
[i
].A
= toA(ai
[i
],bi
[i
]);
887 ch
[i
].P
= toP(ai
[i
],bi
[i
]);
888 ch
[i
].W
+= (fitW
? toW(ai
[i
],bi
[i
],ci
[i
],di
[i
]) : 0);
889 ch
[i
].dA
= (fitdA
? todA(ai
[i
],bi
[i
],ci
[i
],di
[i
]) : 0);
890 ch
[i
].dW
+= (fitdW
? todW(ai
[i
],bi
[i
],ei
[i
],fi
[i
]) : 0);
891 ch
[i
].ddA
= (fitddA
? toddA(ai
[i
],bi
[i
],ei
[i
],fi
[i
]) : 0);
893 memset(ch
+i
,0,sizeof(ch
[i
]));
901 free(ttcos_table
[i
]);
902 free(ttsin_table
[i
]);
908 /* Performs an iterative chirp estimation using the passed
909 in chirp paramters as an initial estimate.
911 x: input signal (unwindowed)
912 y: output reconstruction (unwindowed)
913 window: window to apply to input and bases during fitting process
914 len: length of x,y,r and window vectors
915 c: chirp initial estimation inputs, chirp fit outputs (sorted in frequency order)
917 iter_limit: maximum allowable number of iterations
918 fit_limit: desired fit quality limit
920 fitW : flag indicating that fitting should include the W parameter.
921 fitdA : flag indicating that fitting should include the dA parameter.
922 fitdW : flag indicating that fitting should include the dW parameter.
923 fitddA : flag indicating that fitting should include the ddA parameter.
928 Input estimates affect convergence region and speed and fit
929 quality; precise effects depend on the fit estimation algorithm
930 selected. Note that non-zero initial values for dA, dW or ddA are
931 ignored when fitdA, fitdW, fitddA are unset. An initial value for
932 W is always used even when W is left unfitted.
934 Fitting terminates when no fit parameter changes by more than
935 fit_limit in an iteration or when the fit loop reaches the
936 iteration limit. The fit parameters as checked are scaled over the
941 int estimate_chirps(const float *x
,
963 float E0
=0, E1
=0, E2
=0;
967 float jj
= i
-len
*.5+.5;
968 float w2
= window
[i
]*window
[i
];
969 float w2j2
= w2
*jj
*jj
;
970 float w2j4
= w2j2
*jj
*jj
;
980 /* zero out initial estimates for params we'll not fit */
982 if(!fitdA
) c
[i
].dA
=0.;
983 if(!fitdW
) c
[i
].dW
=0.;
984 if(!fitddA
) c
[i
].ddA
=0.;
989 iter_limit
= linear_iterate(x
,window
,len
,c
,n
,
990 fit_limit
,iter_limit
,fit_gs
,
991 fitW
,fitdA
,fitdW
,fitddA
,
995 iter_limit
= partial_nonlinear_iterate(x
,window
,len
,c
,n
,
996 fit_limit
,iter_limit
,fit_gs
,
997 fitW
,fitdA
,fitdW
,fitddA
,
1002 iter_limit
= full_nonlinear_iterate(x
,window
,len
,c
,n
,
1003 fit_limit
,iter_limit
,fit_gs
,
1004 fitW
,fitdA
,fitdW
,fitddA
,
1005 fit_W_alpha
,fit_dW_alpha
,
1011 /* Sort by ascending frequency */
1012 qsort(c
, n
, sizeof(*c
), cmp_ascending_W
);
1017 /* advances/extrapolates the passed in chirps so that the params are
1018 centered forward in time by len samples. */
1020 void advance_chirps(chirp
*c
, int n
, int len
){
1023 c
[i
].A
+= c
[i
].dA
*len
;
1024 c
[i
].P
+= (c
[i
].W
+c
[i
].dW
*len
)*len
;
1025 c
[i
].W
+= c
[i
].dW
*len
*2;
1029 /* dead, but leave it around; does a slow, brute force DCFT */
1030 void slow_dcft_row(float *x
, float *y
, int k
, int n
){
1032 for(i
=0;i
<n
/2+1;i
++){ /* frequency loop */
1033 float real
=0.,imag
=0.;
1034 for(j
=0;j
<n
;j
++){ /* multiply loop */
1036 float jj
= (j
-n
/2+.5)/n
;
1037 sincosf(2.*M_PI
*(i
+k
*jj
)*jj
,&s
,&c
);
1041 y
[i
] = hypot(real
,imag
);