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