| /* |
| * This file is part of FFmpeg. |
| * |
| * FFmpeg is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * FFmpeg is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with FFmpeg; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| */ |
| |
| #include "config.h" |
| |
| #include <float.h> |
| #include <stdint.h> |
| |
| #include "libavfilter/af_afir.h" |
| #include "libavutil/internal.h" |
| #include "checkasm.h" |
| |
| #define LEN 256 |
| |
| #define randomize_buffer(buf) \ |
| do { \ |
| int i; \ |
| double bmg[2], stddev = 10.0, mean = 0.0; \ |
| \ |
| for (i = 0; i < LEN*2+8; i += 2) { \ |
| av_bmg_get(&checkasm_lfg, bmg); \ |
| buf[i] = bmg[0] * stddev + mean; \ |
| buf[i + 1] = bmg[1] * stddev + mean; \ |
| } \ |
| } while(0); |
| |
| static void test_fcmul_add(const float *src0, const float *src1, const float *src2) |
| { |
| LOCAL_ALIGNED_32(float, cdst, [LEN*2+8]); |
| LOCAL_ALIGNED_32(float, odst, [LEN*2+8]); |
| int i; |
| |
| declare_func(void, float *sum, const float *t, const float *c, |
| ptrdiff_t len); |
| |
| memcpy(cdst, src0, (LEN*2+8) * sizeof(float)); |
| memcpy(odst, src0, (LEN*2+8) * sizeof(float)); |
| call_ref(cdst, src1, src2, LEN); |
| call_new(odst, src1, src2, LEN); |
| for (i = 0; i <= LEN*2; i++) { |
| int idx = i & ~1; |
| float cre = src2[idx]; |
| float cim = src2[idx + 1]; |
| float tre = src1[idx]; |
| float tim = src1[idx + 1]; |
| double t = fabs(src0[i]) + |
| fabs(tre) + fabs(tim) + fabs(cre) + fabs(cim) + |
| fabs(tre * cre) + fabs(tim * cim) + |
| fabs(tre * cim) + fabs(tim * cre) + |
| fabs(tre * cre - tim * cim) + |
| fabs(tre * cim + tim * cre) + |
| fabs(cdst[i]) + 1.0; |
| if (!float_near_abs_eps(cdst[i], odst[i], t * 2 * FLT_EPSILON)) { |
| fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n", |
| i, cdst[i], odst[i], cdst[i] - odst[i]); |
| fail(); |
| break; |
| } |
| } |
| memcpy(odst, src0, (LEN*2+8) * sizeof(float)); |
| bench_new(odst, src1, src2, LEN); |
| } |
| |
| void checkasm_check_afir(void) |
| { |
| LOCAL_ALIGNED_32(float, src0, [LEN*2+8]); |
| LOCAL_ALIGNED_32(float, src1, [LEN*2+8]); |
| LOCAL_ALIGNED_32(float, src2, [LEN*2+8]); |
| AudioFIRDSPContext fir = { 0 }; |
| |
| ff_afir_init(&fir); |
| |
| randomize_buffer(src0); |
| randomize_buffer(src1); |
| randomize_buffer(src2); |
| |
| if (check_func(fir.fcmul_add, "fcmul_add")) |
| test_fcmul_add(src0, src1, src2); |
| report("fcmul_add"); |
| } |