Stops adding invalid sinusoids in overlap-add mode.
Unified · Split
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | #include "libavutil/audio_fifo.h" | 21 | #include "libavutil/audio_fifo.h" |
| 22 | #include "libavutil/opt.h" | 22 | #include "libavutil/opt.h" |
| 23 | #include "libavutil/tx.h" | ||
| 23 | #include "avfilter.h" | 24 | #include "avfilter.h" |
| 24 | #include "audio.h" | 25 | #include "audio.h" |
| 25 | #include "filters.h" | 26 | #include "filters.h" |
| @@ -131,9 +132,66 @@ static int config_input(AVFilterLink *inlink) · 105 unmodified lines | |||
| 131 | s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut)); | 132 | s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut)); |
| 132 | if (!s->window_func_lut) | 133 | if (!s->window_func_lut) |
| 133 | return AVERROR(ENOMEM); | 134 | return AVERROR(ENOMEM); |
| 134 | for (i = 0; i < s->window_size; i++) | 135 | |
| 135 | s->window_func_lut[i] = sin(M_PI * i / s->window_size) * | 136 | { |
| 136 | (1. - (s->overlap / 100.)) * M_PI_2; | 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 | av_frame_free(&s->in); | 196 | av_frame_free(&s->in); |
| 139 | av_frame_free(&s->out); | 197 | av_frame_free(&s->out); |