- tlen = tlength * rate;
- s->fft_data[0].re = 0;
- s->fft_data[0].im = 0;
- s->fft_data[hlen].re = (1.0 + a1 + a2 + a3) * (1.0/tlen) * volume * (1.0/fft_len);
- s->fft_data[hlen].im = 0;
- sv_step = sv = sin(2.0*M_PI*freq*(1.0/rate));
- cv_step = cv = cos(2.0*M_PI*freq*(1.0/rate));
- /* also optimizing window func */
- sw_step = sw = sin(2.0*M_PI*(1.0/tlen));
- cw_step = cw = cos(2.0*M_PI*(1.0/tlen));
- for (x = 1; x < 0.5 * tlen; x++) {
- double cv_tmp, cw_tmp;
- double cw2, cw3, sw2;
-
- cw2 = cw * cw - sw * sw;
- sw2 = cw * sw + sw * cw;
- cw3 = cw * cw2 - sw * sw2;
- w = (1.0 + a1 * cw + a2 * cw2 + a3 * cw3) * (1.0/tlen) * volume * (1.0/fft_len);
- s->fft_data[hlen + x].re = w * cv;
- s->fft_data[hlen + x].im = w * sv;
- s->fft_data[hlen - x].re = s->fft_data[hlen + x].re;
- s->fft_data[hlen - x].im = -s->fft_data[hlen + x].im;
-
- cv_tmp = cv * cv_step - sv * sv_step;
- sv = sv * cv_step + cv * sv_step;
- cv = cv_tmp;
- cw_tmp = cw * cw_step - sw * sw_step;
- sw = sw * cw_step + cw * sw_step;
- cw = cw_tmp;
- }
- for (; x < hlen; x++) {
- s->fft_data[hlen + x].re = 0;
- s->fft_data[hlen + x].im = 0;
- s->fft_data[hlen - x].re = 0;
- s->fft_data[hlen - x].im = 0;
- }
- av_fft_permute(s->fft_context, s->fft_data);
- av_fft_calc(s->fft_context, s->fft_data);
-
- for (x = 0; x < fft_len; x++) {
- s->coeff_sort[x].index = x;
- s->coeff_sort[x].value = s->fft_data[x].re;
+ /* direct frequency domain windowing */
+ flen = 8.0 * fft_len / (tlength * rate);
+ center = freq * fft_len / rate;
+ start = FFMAX(0, ceil(center - 0.5 * flen));
+ end = FFMIN(fft_len, floor(center + 0.5 * flen));
+ s->coeffs[k].len = end - start + 1;
+ s->coeffs[k].start = start;
+ num_coeffs += s->coeffs[k].len;
+ s->coeffs[k].values = av_malloc_array(s->coeffs[k].len, sizeof(*s->coeffs[k].values));
+ if (!s->coeffs[k].values) {
+ ret = AVERROR(ENOMEM);
+ goto eval_error;