AudioResamplerFirOps.h revision 63238efb0d674758902918e3cdaac322126484b7
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ANDROID_AUDIO_RESAMPLER_FIR_OPS_H 18#define ANDROID_AUDIO_RESAMPLER_FIR_OPS_H 19 20namespace android { 21 22#if defined(__arm__) && !defined(__thumb__) 23#define USE_INLINE_ASSEMBLY (true) 24#else 25#define USE_INLINE_ASSEMBLY (false) 26#endif 27 28#if USE_INLINE_ASSEMBLY && defined(__ARM_NEON__) 29#define USE_NEON (true) 30#include <arm_neon.h> 31#else 32#define USE_NEON (false) 33#endif 34 35template<typename T, typename U> 36struct is_same 37{ 38 static const bool value = false; 39}; 40 41template<typename T> 42struct is_same<T, T> // partial specialization 43{ 44 static const bool value = true; 45}; 46 47static inline 48int32_t mulRL(int left, int32_t in, uint32_t vRL) 49{ 50#if USE_INLINE_ASSEMBLY 51 int32_t out; 52 if (left) { 53 asm( "smultb %[out], %[in], %[vRL] \n" 54 : [out]"=r"(out) 55 : [in]"%r"(in), [vRL]"r"(vRL) 56 : ); 57 } else { 58 asm( "smultt %[out], %[in], %[vRL] \n" 59 : [out]"=r"(out) 60 : [in]"%r"(in), [vRL]"r"(vRL) 61 : ); 62 } 63 return out; 64#else 65 int16_t v = left ? static_cast<int16_t>(vRL) : static_cast<int16_t>(vRL>>16); 66 return static_cast<int32_t>((static_cast<int64_t>(in) * v) >> 16); 67#endif 68} 69 70static inline 71int32_t mulAdd(int16_t in, int16_t v, int32_t a) 72{ 73#if USE_INLINE_ASSEMBLY 74 int32_t out; 75 asm( "smlabb %[out], %[v], %[in], %[a] \n" 76 : [out]"=r"(out) 77 : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 78 : ); 79 return out; 80#else 81 return a + v * in; 82#endif 83} 84 85static inline 86int32_t mulAdd(int16_t in, int32_t v, int32_t a) 87{ 88#if USE_INLINE_ASSEMBLY 89 int32_t out; 90 asm( "smlawb %[out], %[v], %[in], %[a] \n" 91 : [out]"=r"(out) 92 : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 93 : ); 94 return out; 95#else 96 return a + static_cast<int32_t>((static_cast<int64_t>(v) * in) >> 16); 97#endif 98} 99 100static inline 101int32_t mulAdd(int32_t in, int32_t v, int32_t a) 102{ 103#if USE_INLINE_ASSEMBLY 104 int32_t out; 105 asm( "smmla %[out], %[v], %[in], %[a] \n" 106 : [out]"=r"(out) 107 : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 108 : ); 109 return out; 110#else 111 return a + static_cast<int32_t>((static_cast<int64_t>(v) * in) >> 32); 112#endif 113} 114 115static inline 116int32_t mulAddRL(int left, uint32_t inRL, int16_t v, int32_t a) 117{ 118#if USE_INLINE_ASSEMBLY 119 int32_t out; 120 if (left) { 121 asm( "smlabb %[out], %[v], %[inRL], %[a] \n" 122 : [out]"=r"(out) 123 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 124 : ); 125 } else { 126 asm( "smlabt %[out], %[v], %[inRL], %[a] \n" 127 : [out]"=r"(out) 128 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 129 : ); 130 } 131 return out; 132#else 133 int16_t s = left ? static_cast<int16_t>(inRL) : static_cast<int16_t>(inRL>>16); 134 return a + v * s; 135#endif 136} 137 138static inline 139int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a) 140{ 141#if USE_INLINE_ASSEMBLY 142 int32_t out; 143 if (left) { 144 asm( "smlawb %[out], %[v], %[inRL], %[a] \n" 145 : [out]"=r"(out) 146 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 147 : ); 148 } else { 149 asm( "smlawt %[out], %[v], %[inRL], %[a] \n" 150 : [out]"=r"(out) 151 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 152 : ); 153 } 154 return out; 155#else 156 int16_t s = left ? static_cast<int16_t>(inRL) : static_cast<int16_t>(inRL>>16); 157 return a + static_cast<int32_t>((static_cast<int64_t>(v) * s) >> 16); 158#endif 159} 160 161} // namespace android 162 163#endif /*ANDROID_AUDIO_RESAMPLER_FIR_OPS_H*/ 164