1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#include <stdint.h> 20 21#include "libavutil/attributes.h" 22#include "libavutil/common.h" 23#include "audiodsp.h" 24 25static inline uint32_t clipf_c_one(uint32_t a, uint32_t mini, 26 uint32_t maxi, uint32_t maxisign) 27{ 28 if (a > mini) 29 return mini; 30 else if ((a ^ (1U << 31)) > maxisign) 31 return maxi; 32 else 33 return a; 34} 35 36static void vector_clipf_c_opposite_sign(float *dst, const float *src, 37 float *min, float *max, int len) 38{ 39 int i; 40 uint32_t mini = *(uint32_t *) min; 41 uint32_t maxi = *(uint32_t *) max; 42 uint32_t maxisign = maxi ^ (1U << 31); 43 uint32_t *dsti = (uint32_t *) dst; 44 const uint32_t *srci = (const uint32_t *) src; 45 46 for (i = 0; i < len; i += 8) { 47 dsti[i + 0] = clipf_c_one(srci[i + 0], mini, maxi, maxisign); 48 dsti[i + 1] = clipf_c_one(srci[i + 1], mini, maxi, maxisign); 49 dsti[i + 2] = clipf_c_one(srci[i + 2], mini, maxi, maxisign); 50 dsti[i + 3] = clipf_c_one(srci[i + 3], mini, maxi, maxisign); 51 dsti[i + 4] = clipf_c_one(srci[i + 4], mini, maxi, maxisign); 52 dsti[i + 5] = clipf_c_one(srci[i + 5], mini, maxi, maxisign); 53 dsti[i + 6] = clipf_c_one(srci[i + 6], mini, maxi, maxisign); 54 dsti[i + 7] = clipf_c_one(srci[i + 7], mini, maxi, maxisign); 55 } 56} 57 58static void vector_clipf_c(float *dst, const float *src, int len, 59 float min, float max) 60{ 61 int i; 62 63 if (min < 0 && max > 0) { 64 vector_clipf_c_opposite_sign(dst, src, &min, &max, len); 65 } else { 66 for (i = 0; i < len; i += 8) { 67 dst[i] = av_clipf(src[i], min, max); 68 dst[i + 1] = av_clipf(src[i + 1], min, max); 69 dst[i + 2] = av_clipf(src[i + 2], min, max); 70 dst[i + 3] = av_clipf(src[i + 3], min, max); 71 dst[i + 4] = av_clipf(src[i + 4], min, max); 72 dst[i + 5] = av_clipf(src[i + 5], min, max); 73 dst[i + 6] = av_clipf(src[i + 6], min, max); 74 dst[i + 7] = av_clipf(src[i + 7], min, max); 75 } 76 } 77} 78 79static int32_t scalarproduct_int16_c(const int16_t *v1, const int16_t *v2, 80 int order) 81{ 82 unsigned res = 0; 83 84 while (order--) 85 res += *v1++ **v2++; 86 87 return res; 88} 89 90static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min, 91 int32_t max, unsigned int len) 92{ 93 do { 94 *dst++ = av_clip(*src++, min, max); 95 *dst++ = av_clip(*src++, min, max); 96 *dst++ = av_clip(*src++, min, max); 97 *dst++ = av_clip(*src++, min, max); 98 *dst++ = av_clip(*src++, min, max); 99 *dst++ = av_clip(*src++, min, max); 100 *dst++ = av_clip(*src++, min, max); 101 *dst++ = av_clip(*src++, min, max); 102 len -= 8; 103 } while (len > 0); 104} 105 106av_cold void ff_audiodsp_init(AudioDSPContext *c) 107{ 108 c->scalarproduct_int16 = scalarproduct_int16_c; 109 c->vector_clip_int32 = vector_clip_int32_c; 110 c->vector_clipf = vector_clipf_c; 111 112#if ARCH_ARM 113 ff_audiodsp_init_arm(c); 114#elif ARCH_PPC 115 ff_audiodsp_init_ppc(c); 116#elif ARCH_X86 117 ff_audiodsp_init_x86(c); 118#endif 119} 120