1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_MAC_VECTOR_MATH_MAC_H_
6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_MAC_VECTOR_MATH_MAC_H_
7 
8 #include <Accelerate/Accelerate.h>
9 
10 #include "build/build_config.h"
11 #include "third_party/blink/renderer/platform/audio/audio_array.h"
12 
13 namespace blink {
14 namespace vector_math {
15 namespace mac {
16 
17 // On the Mac we use the highly optimized versions in Accelerate.framework
18 // In 32-bit mode (__ppc__ or __i386__) <Accelerate/Accelerate.h> includes
19 // <vecLib/vDSP_translate.h> which defines macros of the same name as
20 // our namespaced function names, so we must handle this case differently. Other
21 // architectures (64bit, ARM, etc.) do not include this header file.
22 
Conv(const float * source_p,int source_stride,const float * filter_p,int filter_stride,float * dest_p,int dest_stride,uint32_t frames_to_process,size_t filter_size,const AudioFloatArray *)23 static ALWAYS_INLINE void Conv(const float* source_p,
24                                int source_stride,
25                                const float* filter_p,
26                                int filter_stride,
27                                float* dest_p,
28                                int dest_stride,
29                                uint32_t frames_to_process,
30                                size_t filter_size,
31                                const AudioFloatArray* /*prepared_filter*/) {
32 #if defined(ARCH_CPU_X86)
33   ::conv(source_p, source_stride, filter_p, filter_stride, dest_p, dest_stride,
34          frames_to_process, filter_size);
35 #else
36   vDSP_conv(source_p, source_stride, filter_p, filter_stride, dest_p,
37             dest_stride, frames_to_process, filter_size);
38 #endif
39 }
40 
Vadd(const float * source1p,int source_stride1,const float * source2p,int source_stride2,float * dest_p,int dest_stride,uint32_t frames_to_process)41 static ALWAYS_INLINE void Vadd(const float* source1p,
42                                int source_stride1,
43                                const float* source2p,
44                                int source_stride2,
45                                float* dest_p,
46                                int dest_stride,
47                                uint32_t frames_to_process) {
48 #if defined(ARCH_CPU_X86)
49   ::vadd(source1p, source_stride1, source2p, source_stride2, dest_p,
50          dest_stride, frames_to_process);
51 #else
52   vDSP_vadd(source1p, source_stride1, source2p, source_stride2, dest_p,
53             dest_stride, frames_to_process);
54 #endif
55 }
56 
Vsub(const float * source1p,int source_stride1,const float * source2p,int source_stride2,float * dest_p,int dest_stride,uint32_t frames_to_process)57 static ALWAYS_INLINE void Vsub(const float* source1p,
58                                int source_stride1,
59                                const float* source2p,
60                                int source_stride2,
61                                float* dest_p,
62                                int dest_stride,
63                                uint32_t frames_to_process) {
64   // NOTE: We define Vsub to be source1 - source2, The vDSP routines
65   // do source2 - source1, so swap the args when calling the vDSP
66   // routines.
67 #if defined(ARCH_CPU_X86)
68   ::vsub(source2p, source_stride2, source1p, source_stride1, dest_p,
69          dest_stride, frames_to_process);
70 #else
71   vDSP_vsub(source2p, source_stride2, source1p, source_stride1, dest_p,
72             dest_stride, frames_to_process);
73 #endif
74 }
75 
Vclip(const float * source_p,int source_stride,const float * low_threshold_p,const float * high_threshold_p,float * dest_p,int dest_stride,uint32_t frames_to_process)76 static ALWAYS_INLINE void Vclip(const float* source_p,
77                                 int source_stride,
78                                 const float* low_threshold_p,
79                                 const float* high_threshold_p,
80                                 float* dest_p,
81                                 int dest_stride,
82                                 uint32_t frames_to_process) {
83   vDSP_vclip(source_p, source_stride, low_threshold_p, high_threshold_p, dest_p,
84              dest_stride, frames_to_process);
85 }
86 
Vmaxmgv(const float * source_p,int source_stride,float * max_p,uint32_t frames_to_process)87 static ALWAYS_INLINE void Vmaxmgv(const float* source_p,
88                                   int source_stride,
89                                   float* max_p,
90                                   uint32_t frames_to_process) {
91   vDSP_maxmgv(source_p, source_stride, max_p, frames_to_process);
92 }
93 
Vmul(const float * source1p,int source_stride1,const float * source2p,int source_stride2,float * dest_p,int dest_stride,uint32_t frames_to_process)94 static ALWAYS_INLINE void Vmul(const float* source1p,
95                                int source_stride1,
96                                const float* source2p,
97                                int source_stride2,
98                                float* dest_p,
99                                int dest_stride,
100                                uint32_t frames_to_process) {
101 #if defined(ARCH_CPU_X86)
102   ::vmul(source1p, source_stride1, source2p, source_stride2, dest_p,
103          dest_stride, frames_to_process);
104 #else
105   vDSP_vmul(source1p, source_stride1, source2p, source_stride2, dest_p,
106             dest_stride, frames_to_process);
107 #endif
108 }
109 
Vsma(const float * source_p,int source_stride,const float * scale,float * dest_p,int dest_stride,uint32_t frames_to_process)110 static ALWAYS_INLINE void Vsma(const float* source_p,
111                                int source_stride,
112                                const float* scale,
113                                float* dest_p,
114                                int dest_stride,
115                                uint32_t frames_to_process) {
116   vDSP_vsma(source_p, source_stride, scale, dest_p, dest_stride, dest_p,
117             dest_stride, frames_to_process);
118 }
119 
Vsmul(const float * source_p,int source_stride,const float * scale,float * dest_p,int dest_stride,uint32_t frames_to_process)120 static ALWAYS_INLINE void Vsmul(const float* source_p,
121                                 int source_stride,
122                                 const float* scale,
123                                 float* dest_p,
124                                 int dest_stride,
125                                 uint32_t frames_to_process) {
126 #if defined(ARCH_CPU_X86)
127   ::vsmul(source_p, source_stride, scale, dest_p, dest_stride,
128           frames_to_process);
129 #else
130   vDSP_vsmul(source_p, source_stride, scale, dest_p, dest_stride,
131              frames_to_process);
132 #endif
133 }
134 
Vsadd(const float * source_p,int source_stride,const float * addend,float * dest_p,int dest_stride,uint32_t frames_to_process)135 static ALWAYS_INLINE void Vsadd(const float* source_p,
136                                 int source_stride,
137                                 const float* addend,
138                                 float* dest_p,
139                                 int dest_stride,
140                                 uint32_t frames_to_process) {
141 #if defined(ARCH_CPU_X86)
142   ::vsadd(source_p, source_stride, addend, dest_p, dest_stride,
143           frames_to_process);
144 #else
145   vDSP_vsadd(source_p, source_stride, addend, dest_p, dest_stride,
146              frames_to_process);
147 #endif
148 }
149 
Vsadd(const float * source_p,int source_stride,float addend,float * dest_p,int dest_stride,uint32_t frames_to_process)150 static ALWAYS_INLINE void Vsadd(const float* source_p,
151                                 int source_stride,
152                                 float addend,
153                                 float* dest_p,
154                                 int dest_stride,
155                                 uint32_t frames_to_process) {
156 #if defined(ARCH_CPU_X86)
157   ::vsadd(source_p, source_stride, &addend, dest_p, dest_stride,
158           frames_to_process);
159 #else
160   vDSP_vsadd(source_p, source_stride, &addend, dest_p, dest_stride,
161              frames_to_process);
162 #endif
163 }
164 
Vsvesq(const float * source_p,int source_stride,float * sum_p,uint32_t frames_to_process)165 static ALWAYS_INLINE void Vsvesq(const float* source_p,
166                                  int source_stride,
167                                  float* sum_p,
168                                  uint32_t frames_to_process) {
169   vDSP_svesq(source_p, source_stride, sum_p, frames_to_process);
170 }
171 
Zvmul(const float * real1p,const float * imag1p,const float * real2p,const float * imag2p,float * real_dest_p,float * imag_dest_p,uint32_t frames_to_process)172 static ALWAYS_INLINE void Zvmul(const float* real1p,
173                                 const float* imag1p,
174                                 const float* real2p,
175                                 const float* imag2p,
176                                 float* real_dest_p,
177                                 float* imag_dest_p,
178                                 uint32_t frames_to_process) {
179   DSPSplitComplex sc1;
180   DSPSplitComplex sc2;
181   DSPSplitComplex dest;
182   sc1.realp = const_cast<float*>(real1p);
183   sc1.imagp = const_cast<float*>(imag1p);
184   sc2.realp = const_cast<float*>(real2p);
185   sc2.imagp = const_cast<float*>(imag2p);
186   dest.realp = real_dest_p;
187   dest.imagp = imag_dest_p;
188 #if defined(ARCH_CPU_X86)
189   ::zvmul(&sc1, 1, &sc2, 1, &dest, 1, frames_to_process, 1);
190 #else
191   vDSP_zvmul(&sc1, 1, &sc2, 1, &dest, 1, frames_to_process, 1);
192 #endif
193 }
194 
195 }  // namespace mac
196 }  // namespace vector_math
197 }  // namespace blink
198 
199 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_MAC_VECTOR_MATH_MAC_H_
200