Stops adding invalid sinusoids in overlap-add mode.
Unified · Split
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #include "libavutil/audio_fifo.h" |
| 22 | 22 | #include "libavutil/opt.h" |
| 23 | +#include "libavutil/tx.h" | |
| 23 | 24 | #include "avfilter.h" |
| 24 | 25 | #include "audio.h" |
| 25 | 26 | #include "filters.h" |
| @@ -131,9 +132,66 @@ static int config_input(AVFilterLink *inlink) · 105 unmodified lines | ||
| 131 | 132 | s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut)); |
| 132 | 133 | if (!s->window_func_lut) |
| 133 | 134 | return AVERROR(ENOMEM); |
| 134 | − for (i = 0; i < s->window_size; i++) | |
| 135 | − s->window_func_lut[i] = sin(M_PI * i / s->window_size) * | |
| 136 | − (1. - (s->overlap / 100.)) * M_PI_2; | |
| 135 | + | |
| 136 | + { | |
| 137 | + double *tx_in[2], *tx_out[2]; | |
| 138 | + AVTXContext *tx, *itx; | |
| 139 | + av_tx_fn tx_fn, itx_fn; | |
| 140 | + int ret, tx_size; | |
| 141 | + double scale; | |
| 142 | + | |
| 143 | + tx_size = 1 << (32 - ff_clz(s->window_size)); | |
| 144 | + | |
| 145 | + scale = 1.0; | |
| 146 | + ret = av_tx_init(&tx, &tx_fn, AV_TX_DOUBLE_RDFT, 0, tx_size, &scale, 0); | |
| 147 | + if (ret < 0) | |
| 148 | + return ret; | |
| 149 | + | |
| 150 | + scale = 1.0 / tx_size; | |
| 151 | + ret = av_tx_init(&itx, &itx_fn, AV_TX_DOUBLE_RDFT, 1, tx_size, &scale, 0); | |
| 152 | + if (ret < 0) | |
| 153 | + return ret; | |
| 154 | + | |
| 155 | + tx_in[0] = av_calloc(tx_size + 2, sizeof(*tx_in[0])); | |
| 156 | + tx_in[1] = av_calloc(tx_size + 2, sizeof(*tx_in[1])); | |
| 157 | + tx_out[0] = av_calloc(tx_size + 2, sizeof(*tx_out[0])); | |
| 158 | + tx_out[1] = av_calloc(tx_size + 2, sizeof(*tx_out[1])); | |
| 159 | + if (!tx_in[0] || !tx_in[1] || !tx_out[0] || !tx_out[1]) | |
| 160 | + return AVERROR(ENOMEM); | |
| 161 | + | |
| 162 | + for (int n = 0; n < s->window_size - s->hop_size; n++) | |
| 163 | + tx_in[0][n] = 1.0; | |
| 164 | + | |
| 165 | + for (int n = 0; n < s->hop_size; n++) | |
| 166 | + tx_in[1][n] = 1.0; | |
| 167 | + | |
| 168 | + tx_fn(tx, tx_out[0], tx_in[0], sizeof(double)); | |
| 169 | + tx_fn(tx, tx_out[1], tx_in[1], sizeof(double)); | |
| 170 | + | |
| 171 | + for (int n = 0; n <= tx_size/2; n++) { | |
| 172 | + double re0 = tx_out[0][2*n]; | |
| 173 | + double im0 = tx_out[0][2*n+1]; | |
| 174 | + double re1 = tx_out[1][2*n]; | |
| 175 | + double im1 = tx_out[1][2*n+1]; | |
| 176 | + | |
| 177 | + tx_in[0][2*n] = re0 * re1 - im0 * im1; | |
| 178 | + tx_in[0][2*n+1] = re0 * im1 + re1 * im0; | |
| 179 | + } | |
| 180 | + | |
| 181 | + itx_fn(itx, tx_out[0], tx_in[0], sizeof(AVComplexDouble)); | |
| 182 | + | |
| 183 | + scale = 1.0 / (s->window_size - s->hop_size); | |
| 184 | + for (int n = 0; n < s->window_size; n++) | |
| 185 | + s->window_func_lut[n] = tx_out[0][n] * scale; | |
| 186 | + | |
| 187 | + av_tx_uninit(&tx); | |
| 188 | + av_tx_uninit(&itx); | |
| 189 | + | |
| 190 | + av_freep(&tx_in[0]); | |
| 191 | + av_freep(&tx_in[1]); | |
| 192 | + av_freep(&tx_out[0]); | |
| 193 | + av_freep(&tx_out[1]); | |
| 194 | + } | |
| 137 | 195 | |
| 138 | 196 | av_frame_free(&s->in); |
| 139 | 197 | av_frame_free(&s->out); |