| @@ -22,6 +22,7 @@ · 21 unmodified lines |
| 22 | 22 | #undef SAMPLE_FORMAT |
| 23 | 23 | #undef SQRT |
| 24 | 24 | #undef ZERO |
| 25 | +#undef ONE |
| 25 | 26 | #if DEPTH == 32 |
| 26 | 27 | #define SAMPLE_FORMAT flt |
| 27 | 28 | #define SQRT sqrtf |
| @@ -29,6 +30,7 @@ · 1 unmodified line |
| 29 | 30 | #define FABS fabsf |
| 30 | 31 | #define ftype float |
| 31 | 32 | #define ZERO 0.f |
| 33 | +#define ONE 1.f |
| 32 | 34 | #else |
| 33 | 35 | #define SAMPLE_FORMAT dbl |
| 34 | 36 | #define SQRT sqrt |
| @@ -36,6 +38,7 @@ · 1 unmodified line |
| 36 | 38 | #define FABS fabs |
| 37 | 39 | #define ftype double |
| 38 | 40 | #define ZERO 0.0 |
| 41 | +#define ONE 1.0 |
| 39 | 42 | #endif |
| 40 | 43 | |
| 41 | 44 | #define fn3(a,b) a##_##b |
| @@ -111,6 +114,68 @@ static ftype fn(compute_avg)(ftype *cache, ftype sample, ftype wsample, · 69 unmodified lines |
| 111 | 114 | return r / window_size; |
| 112 | 115 | } |
| 113 | 116 | |
| 117 | +static ftype fn(compute_median)(ftype *peak, ftype sample, ftype wsample, |
| 118 | + int size, int *ffront, int *bback) |
| 119 | +{ |
| 120 | + ftype r, abs_sample = FABS(sample); |
| 121 | + int front = *ffront; |
| 122 | + int back = *bback; |
| 123 | + int empty = front == back && peak[front] == -ONE; |
| 124 | + int idx; |
| 125 | + |
| 126 | + if (!empty && FABS(wsample) == peak[front]) { |
| 127 | + peak[front] = -ONE; |
| 128 | + if (back != front) { |
| 129 | + front--; |
| 130 | + if (front < 0) |
| 131 | + front = size - 1; |
| 132 | + } |
| 133 | + empty = front == back; |
| 134 | + } |
| 135 | + |
| 136 | + if (!empty && abs_sample > peak[front]) { |
| 137 | + while (1) { |
| 138 | + peak[front] = -ONE; |
| 139 | + if (back == front) { |
| 140 | + empty = 1; |
| 141 | + break; |
| 142 | + } |
| 143 | + front--; |
| 144 | + if (front < 0) |
| 145 | + front = size - 1; |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + while (!empty && abs_sample > peak[back]) { |
| 150 | + peak[back] = -ONE; |
| 151 | + if (back == front) { |
| 152 | + empty = 1; |
| 153 | + break; |
| 154 | + } |
| 155 | + back++; |
| 156 | + if (back >= size) |
| 157 | + back = 0; |
| 158 | + } |
| 159 | + |
| 160 | + if (!empty) { |
| 161 | + back--; |
| 162 | + if (back < 0) |
| 163 | + back = size - 1; |
| 164 | + } |
| 165 | + |
| 166 | + peak[back] = abs_sample; |
| 167 | + idx = (back <= front) ? back + (front - back + 1) / 2 : back + (size + front - back + 1) / 2; |
| 168 | + if (idx >= size) |
| 169 | + idx -= size; |
| 170 | + av_assert2(idx >= 0 && idx < size); |
| 171 | + r = peak[idx]; |
| 172 | + |
| 173 | + *ffront = front; |
| 174 | + *bback = back; |
| 175 | + |
| 176 | + return r; |
| 177 | +} |
| 178 | + |
| 114 | 179 | static ftype fn(compute_peak)(ftype *peak, ftype sample, ftype wsample, |
| 115 | 180 | int size, int *ffront, int *bback) |
| 116 | 181 | { |
| @@ -216,7 +281,7 @@ static void fn(filter_start)(AVFilterContext *ctx, · 99 unmodified lines |
| 216 | 281 | if (s->start_found_periods < 0) |
| 217 | 282 | goto skip; |
| 218 | 283 | |
| 219 | | − if (s->detection != D_PEAK) |
| 284 | + if (s->detection != D_PEAK && s->detection != D_MEDIAN) |
| 220 | 285 | window_size = s->start_window_size; |
| 221 | 286 | |
| 222 | 287 | for (int ch = 0; ch < nb_channels; ch++) { |
| @@ -308,7 +373,7 @@ static void fn(filter_stop)(AVFilterContext *ctx, · 85 unmodified lines |
| 308 | 373 | stop_nb_samples, |
| 309 | 374 | stop_window_nb_samples); |
| 310 | 375 | |
| 311 | | − if (s->detection != D_PEAK) |
| 376 | + if (s->detection != D_PEAK && s->detection != D_MEDIAN) |
| 312 | 377 | window_size = s->stop_window_size; |
| 313 | 378 | |
| 314 | 379 | for (int ch = 0; ch < nb_channels; ch++) { |