1/*
2Copyright 2018 Google Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS-IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef RESONANCE_AUDIO_BASE_SIMD_UTILS_H_
18#define RESONANCE_AUDIO_BASE_SIMD_UTILS_H_
19
20#include <cstddef>
21#include <cstdint>
22
23namespace vraudio {
24
25// Checks if the pointer provided is correctly aligned for SIMD.
26//
27// @param pointer Pointer to check.
28// @return True if the pointer is correctly aligned.
29bool IsAligned(const float* pointer);
30bool IsAligned(const int16_t* pointer);
31
32// Rounds a number of frames up to the next aligned memory address
33// based on |memory_alignment_bytes|. This allows for aligning offset pointers
34// into a single chunk of allocated memory.
35//
36// @param length Number of samples before the desired offset pointer.
37// @param type_size_bytes Size of the type of each entry in the array.
38// @param memory_alignment_bytes Number of bytes to which an address is aligned.
39// @return Number of samples into the memory chunk to ensure aligned memory.
40size_t FindNextAlignedArrayIndex(size_t length, size_t type_size_bytes,
41 size_t memory_alignment_bytes);
42
43// Adds a float array |input_a| to another float array |input_b| and stores the
44// result in |output|.
45//
46// @param length Number of floats.
47// @param input_a Pointer to the first float in input_a array.
48// @param input_b Pointer to the first float in input_b array.
49// @param output Pointer to the first float in output array.
50void AddPointwise(size_t length, const float* input_a, const float* input_b,
51 float* output);
52
53// Subtracts a float array |input|, pointwise from another float array |output|.
54//
55// @param length Number of floats.
56// @param input Pointer to the first float in input_a array.
57// @param output Pointer to the first float in input_b array.
58// @param output Pointer to the first float in output array.
59void SubtractPointwise(size_t length, const float* input_a,
60 const float* input_b, float* output);
61
62// Pointwise multiplies a float array |input_a| with another float array
63// |input_b| and stores the result in |output|.
64//
65// @param length Number of floats.
66// @param input Pointer to the first float in input_a array.
67// @param input Pointer to the first float in input_b array.
68// @param output Pointer to the first float in output array.
69void MultiplyPointwise(size_t length, const float* input_a,
70 const float* input_b, float* output);
71
72// Pointwise multiplies a float array |input_a| with another float array
73// |input_b| and adds the result onto |accumulator|.
74//
75// @param length Number of floats.
76// @param input_a Pointer to the first float in input_a array.
77// @param input_b Pointer to the first float in input_b array.
78// @param accumulator Pointer to the first float in accumulator array.
79void MultiplyAndAccumulatePointwise(size_t length, const float* input_a,
80 const float* input_b, float* accumulator);
81
82// Multiplies a float array |input| by a scalar |gain| over |length| samples.
83//
84// @param length Number of floats.
85// @param gain Scalar value with which to multiply the input.
86// @param input Pointer to the first float in input array.
87// @param output Pointer to the first float in output array.
88void ScalarMultiply(size_t length, float gain, const float* input,
89 float* output);
90
91// Multiplies a float array |input| by a scalar |gain| over |length| samples and
92// adds the result onto |accumulator|.
93//
94// @param length Number of floats.
95// @param gain Scalar value with which to multiply the input.
96// @param input Pointer to the first float in input array.
97// @param output Pointer to the first float in accumulator array.
98void ScalarMultiplyAndAccumulate(size_t length, float gain, const float* input,
99 float* accumulator);
100
101// Calculates an approximmate reciprocal square root.
102//
103// @param length Number of floats.
104// @param input Pointer to the first float in input array.
105// @param output Pointer to the first float in output array.
106void ReciprocalSqrt(size_t length, const float* input, float* output);
107
108// Calculates an approximate square root.
109//
110// @param length Number of floats.
111// @param input Pointer to the first float in input array.
112// @param output Pointer to the first float in output array.
113void Sqrt(size_t length, const float* input, float* output);
114
115// Calculates the approximate magnitudes of interleaved complex numbers.
116//
117// @param length Number of complex numbers in the input array,
118// (i.e. half its length).
119// @param input Pointer to the first float in input array. Length: 2 * |length|.
120// @param output Pointer to the first float in output array, Length: |length|.
121void ApproxComplexMagnitude(size_t length, const float* input, float* output);
122
123// Calculates the complex values in interleaved format (real, imaginary), from a
124// vector of magnitudes and of sines and cosines of phase.
125//
126// @param length Number of total entries (real & imaginary) in the input array.
127// @param magnitude Pointer to the first float in the magnitude array, Length:
128// |length| / 2
129// @param cos_phase Pointer to the first float in the cosine phase array,
130// Length: |length| / 2
131// @param sin_phase Pointer to the first float in the sine phase array, Length:
132// |length| / 2
133// @param complex_interleaved_format_output Pointer to the first float in the
134// output array. Length: |length|.
135void ComplexInterleavedFormatFromMagnitudeAndSinCosPhase(
136 size_t length, const float* magnitude, const float* cos_phase,
137 const float* sin_phase, float* complex_interleaved_format_output);
138
139// Generates an identical left and right pair of stereo channels from a mono
140// input channel, where each channel is the mono channel times 1/sqrt(2).
141//
142// @param length Number of floats.
143// @param mono Pointer to the first float in an input mono array.
144// @param left Pointer to the first float in the left output array.
145// @param right Pointer to the first float in the right output array.
146void StereoFromMonoSimd(size_t length, const float* mono, float* left,
147 float* right);
148
149// Generates a mono downmix from a pair of stereo channels, where the output is
150// equal to the sum of the two inputs times 1/sqrt(2).
151//
152// @param length Number of floats.
153// @param left Pointer to the first float in the left input array.
154// @param right Pointer to the first float in the right input array.
155// @param mono Pointer to the first float in an output mono array.
156void MonoFromStereoSimd(size_t length, const float* left, const float* right,
157 float* mono);
158
159// Converts an array of 32 bit float input to clamped 16 bit int output.
160//
161// @param length Number of floats in the input array and int16_ts in the output.
162// @param input Float array.
163// @param output Int array.
164void Int16FromFloat(size_t length, const float* input, int16_t* output);
165
166// Converts an array of 16 bit int input to 32 bit float output.
167//
168// @param length Number of int16_ts in the input array and floats in the output.
169// @param input Int array.
170// @param output Float array.
171void FloatFromInt16(size_t length, const int16_t* input, float* output);
172
173// Interleaves a pair of mono buffers of int_16 data into a stereo buffer.
174//
175// @param length Number of frames per mono channel. The interleaved buffer must
176// be twice this size.
177// @param channel_0 Input buffer of mono data for the first channel.
178// @param channel_1 Input buffer of mono data for the second channel.
179// @param interleaved_buffer Output buffer of stereo interleaved data.
180void InterleaveStereo(size_t length, const int16_t* channel_0,
181 const int16_t* channel_1, int16_t* interleaved_buffer);
182
183// Interleaves a pair of mono buffers of float data into a stereo buffer.
184//
185// @param length Number of frames per mono channel. The interleaved buffer must
186// be twice this size.
187// @param channel_0 Input buffer of mono data for the first channel.
188// @param channel_1 Input buffer of mono data for the second channel.
189// @param interleaved_buffer Output buffer of stereo interleaved data.
190void InterleaveStereo(size_t length, const float* channel_0,
191 const float* channel_1, float* interleaved_buffer);
192
193// Interleaves a pair of mono buffers of float data into a stereo buffer of
194// int16_t data.
195//
196// @param length Number of frames per mono channel. The interleaved buffer must
197// be twice this size.
198// @param channel_0 Input buffer of mono data for the first channel (float).
199// @param channel_1 Input buffer of mono data for the second channel (float).
200// @param interleaved_buffer Output buffer of stereo interleaved data (int16_t).
201void InterleaveStereo(size_t length, const float* channel_0,
202 const float* channel_1, int16_t* interleaved_buffer);
203
204// Deinterleaves a stereo buffer of int16_t data into a pair of mono buffers.
205//
206// @param length Number of frames per mono channel. The interleaved buffer must
207// be twice this size.
208// @param interleaved_buffer Input buffer of stereo interleaved data.
209// @param channel_0 Output buffer of mono data for the first channel.
210// @param channel_1 Output buffer of mono data for the second channel.
211void DeinterleaveStereo(size_t length, const int16_t* interleaved_buffer,
212 int16_t* channel_0, int16_t* channel_1);
213
214// Deinterleaves a stereo buffer of float data into a pair of mono buffers.
215//
216// @param length Number of frames per mono channel. The interleaved buffer must
217// be twice this size.
218// @param interleaved_buffer Input buffer of stereo interleaved data.
219// @param channel_0 Output buffer of mono data for the first channel.
220// @param channel_1 Output buffer of mono data for the second channel.
221void DeinterleaveStereo(size_t length, const float* interleaved_buffer,
222 float* channel_0, float* channel_1);
223
224// Deinterleaves a stereo buffer of int16_t data into a pair of mono float
225// buffers, performing the int16 to floating point conversion.
226//
227// @param length Number of frames per mono channel. The interleaved buffer must
228// be twice this size.
229// @param interleaved_buffer Input buffer of stereo interleaved data (int16_t).
230// @param channel_0 Output buffer of mono data for the first channel (float).
231// @param channel_1 Output buffer of mono data for the second channel (float).
232void DeinterleaveStereo(size_t length, const int16_t* interleaved_buffer,
233 float* channel_0, float* channel_1);
234
235// Interleaves four mono buffers of int16_t data into a quad buffer.
236//
237// @param length Number of frames per mono channel. The interleaved buffer must
238// be four times this size and the workspace must be five times this size.
239// @param channel_0 Input buffer of mono data for the first channel.
240// @param channel_1 Input buffer of mono data for the second channel.
241// @param channel_2 Input buffer of mono data for the third channel.
242// @param channel_3 Input buffer of mono data for the fourth channel.
243// @param workspace Aligned buffer of 5 * |length| samples in length.
244// @param interleaved_buffer Output buffer of quad interleaved data.
245void InterleaveQuad(size_t length, const int16_t* channel_0,
246 const int16_t* channel_1, const int16_t* channel_2,
247 const int16_t* channel_3, int16_t* workspace,
248 int16_t* interleaved_buffer);
249
250// Interleaves four mono buffers of float data into a quad buffer.
251//
252// @param length Number of frames per mono channel. The interleaved buffer must
253// be four times this size and the workspace must be five times this size.
254// @param channel_0 Input buffer of mono data for the first channel.
255// @param channel_1 Input buffer of mono data for the second channel.
256// @param channel_2 Input buffer of mono data for the third channel.
257// @param channel_3 Input buffer of mono data for the fourth channel.
258// @param workspace Aligned buffer of 5 * |length| samples in length.
259// @param interleaved_buffer Output buffer of quad interleaved data.
260void InterleaveQuad(size_t length, const float* channel_0,
261 const float* channel_1, const float* channel_2,
262 const float* channel_3, float* workspace,
263 float* interleaved_buffer);
264
265// Deinterleaves a quad buffer of int16_t data into four mono buffers.
266//
267// @param length Number of frames per mono channel. The interleaved buffer must
268// be four times this size and the workspace must be five times this size.
269// @param interleaved_buffer Input buffer of quad interleaved data.
270// @param workspace Aligned buffer of 5 * |length| samples in length.
271// @param channel_0 Output buffer of mono data for the first channel.
272// @param channel_1 Output buffer of mono data for the second channel.
273// @param channel_2 Output buffer of mono data for the third channel.
274// @param channel_3 Output buffer of mono data for the fourth channel.
275void DeinterleaveQuad(size_t length, const int16_t* interleaved_buffer,
276 int16_t* workspace, int16_t* channel_0,
277 int16_t* channel_1, int16_t* channel_2,
278 int16_t* channel_3);
279
280// Deinterleaves a quad buffer of float data into four mono buffers.
281//
282// @param length Number of frames per mono channel. The interleaved buffer must
283// be four times this size and the workspace must be five times this size.
284// @param interleaved_buffer Input buffer of quad interleaved data.
285// @param workspace Aligned buffer of 5 * |length| samples in length.
286// @param channel_0 Output buffer of mono data for the first channel.
287// @param channel_1 Output buffer of mono data for the second channel.
288// @param channel_2 Output buffer of mono data for the third channel.
289// @param channel_3 Output buffer of mono data for the fourth channel.
290void DeinterleaveQuad(size_t length, const float* interleaved_buffer,
291 float* workspace, float* channel_0, float* channel_1,
292 float* channel_2, float* channel_3);
293
294} // namespace vraudio
295
296#endif // RESONANCE_AUDIO_BASE_SIMD_UTILS_H_
297

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/base/simd_utils.h