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// Prevent Visual Studio from complaining about std::copy_n.
18#if defined(_WIN32)
19#define _SCL_SECURE_NO_WARNINGS
20#endif
21
22#include "utils/planar_interleaved_conversion.h"
23
24#include "base/constants_and_types.h"
25#include "base/logging.h"
26#include "base/simd_utils.h"
27
28#include "utils/sample_type_conversion.h"
29
30namespace vraudio {
31
32namespace {
33
34template <typename InputType, typename OutputType>
35void ConvertInterleavedToPlanarTemplated(
36 InputType interleaved_buffer, size_t num_input_frames,
37 size_t num_input_channels, size_t input_offset_frames,
38 const std::vector<size_t>* channel_map, OutputType output_buffer,
39 size_t num_output_frames, size_t num_output_channels,
40 size_t output_offset_frames, size_t num_frames_to_copy) {
41 DCHECK_GE(num_input_frames, input_offset_frames);
42 const size_t max_num_input_frames = num_input_frames - input_offset_frames;
43 DCHECK_GE(num_output_frames, output_offset_frames);
44 const size_t max_num_output_frames = num_output_frames - output_offset_frames;
45 DCHECK_GE(max_num_input_frames, num_frames_to_copy);
46 DCHECK_GE(max_num_output_frames, num_frames_to_copy);
47
48 if (channel_map == nullptr) {
49 DCHECK_EQ(num_input_channels, num_output_channels);
50 } else {
51 DCHECK_GE(channel_map->size(), num_output_channels);
52 }
53
54 InputType interleaved_buffer_with_offset =
55 interleaved_buffer + input_offset_frames * num_input_channels;
56
57 if (num_input_channels == kNumStereoChannels &&
58 num_output_channels == kNumStereoChannels) {
59 if (channel_map == nullptr) {
60 DeinterleaveStereo(num_frames_to_copy, interleaved_buffer_with_offset,
61 &output_buffer[0][output_offset_frames],
62 &output_buffer[1][output_offset_frames]);
63 } else {
64 DCHECK_LT((*channel_map)[0], kNumStereoChannels);
65 DCHECK_LT((*channel_map)[1], kNumStereoChannels);
66 DeinterleaveStereo(
67 num_input_frames, interleaved_buffer_with_offset,
68 &output_buffer[(*channel_map)[0]][output_offset_frames],
69 &output_buffer[(*channel_map)[1]][output_offset_frames]);
70 }
71 } else {
72 for (size_t channel_idx = 0; channel_idx < num_output_channels;
73 ++channel_idx) {
74 const size_t input_channel =
75 channel_map != nullptr ? (*channel_map)[channel_idx] : channel_idx;
76 DCHECK_LT(input_channel, num_input_channels);
77 InputType input_ptr = &interleaved_buffer_with_offset[input_channel];
78 float* output_ptr = &output_buffer[channel_idx][output_offset_frames];
79 for (size_t frame = 0; frame < num_frames_to_copy; ++frame) {
80 ConvertSampleToFloatFormat(*input_ptr, output_ptr);
81 input_ptr += num_input_channels;
82 ++output_ptr;
83 }
84 }
85 }
86}
87
88template <typename PlanarInputType, typename PlanarOutputType>
89void ConvertPlanarToPlanarTemplated(
90 PlanarInputType input, size_t num_input_frames, size_t num_input_channels,
91 size_t input_offset_frames, const std::vector<size_t>* channel_map,
92 PlanarOutputType planar_output_ptrs, size_t num_output_frames,
93 size_t num_output_channels, size_t output_offset_frames,
94 size_t num_frames_convert_and_copy) {
95 DCHECK_GE(num_input_frames, input_offset_frames);
96 const size_t max_num_input_frames = num_input_frames - input_offset_frames;
97 DCHECK_GE(num_output_frames, output_offset_frames);
98 const size_t max_num_output_frames = num_output_frames - output_offset_frames;
99 DCHECK_GE(max_num_input_frames, num_frames_convert_and_copy);
100 DCHECK_GE(max_num_output_frames, num_frames_convert_and_copy);
101
102 if (channel_map == nullptr) {
103 DCHECK_EQ(num_input_channels, num_output_channels);
104 } else {
105 DCHECK_GE(channel_map->size(), num_output_channels);
106 }
107
108 for (size_t channel = 0; channel < num_output_channels; ++channel) {
109 const size_t input_channel =
110 channel_map != nullptr ? (*channel_map)[channel] : channel;
111 DCHECK_LT(input_channel, num_input_channels);
112 ConvertPlanarSamples(num_frames_convert_and_copy,
113 &input[input_channel][input_offset_frames],
114 &planar_output_ptrs[channel][output_offset_frames]);
115 }
116}
117
118template <typename PlanarInputType, typename InterleavedOutputType>
119void ConvertPlanarToInterleavedTemplated(
120 PlanarInputType input, size_t num_input_frames, size_t num_input_channels,
121 size_t input_offset_frames, InterleavedOutputType interleaved_output_ptr,
122 size_t num_output_frames, size_t num_output_channels,
123 size_t output_offset_frames, size_t num_frames_convert_and_copy) {
124 DCHECK(interleaved_output_ptr);
125 DCHECK_GE(num_input_frames, input_offset_frames);
126 const size_t max_num_input_frames = num_input_frames - input_offset_frames;
127 DCHECK_GE(num_output_frames, output_offset_frames);
128 const size_t max_num_output_frames = num_output_frames - output_offset_frames;
129 DCHECK_GE(max_num_input_frames, num_frames_convert_and_copy);
130 DCHECK_GE(max_num_output_frames, num_frames_convert_and_copy);
131 DCHECK_EQ(num_input_channels, num_output_channels);
132
133 InterleavedOutputType interleaved_output_ptr_with_offset =
134 interleaved_output_ptr + output_offset_frames * num_output_channels;
135
136 if (num_input_channels == kNumStereoChannels &&
137 num_output_channels == kNumStereoChannels) {
138 const float* left_ptr = &input[0][input_offset_frames];
139 const float* right_ptr = &input[1][input_offset_frames];
140 InterleaveStereo(num_frames_convert_and_copy, left_ptr, right_ptr,
141 interleaved_output_ptr_with_offset);
142 } else {
143 for (size_t channel = 0; channel < num_output_channels; ++channel) {
144 const float* input_channel_ptr = &input[channel][input_offset_frames];
145 size_t interleaved_index = channel;
146 for (size_t frame = 0; frame < num_frames_convert_and_copy; ++frame) {
147 ConvertSampleFromFloatFormat(
148 input_channel_ptr[frame],
149 &interleaved_output_ptr_with_offset[interleaved_index]);
150 interleaved_index += num_output_channels;
151 }
152 }
153 }
154}
155
156} // namespace
157
158void PlanarFromInterleaved(const float* interleaved_buffer,
159 size_t num_input_frames, size_t num_input_channels,
160 const std::vector<float*>& planar_buffer_ptr,
161 size_t num_output_frames) {
162 DCHECK(interleaved_buffer);
163 DCHECK_GT(planar_buffer_ptr.size(), 0);
164
165 const size_t num_frames_to_copy =
166 std::min(a: num_input_frames, b: num_output_frames);
167 ConvertInterleavedToPlanarTemplated<const float*, float* const*>(
168 interleaved_buffer, num_input_frames, num_input_channels,
169 input_offset_frames: 0 /* input_offset_frames */, channel_map: nullptr /* channel_map*/,
170 output_buffer: planar_buffer_ptr.data(), num_output_frames, num_output_channels: planar_buffer_ptr.size(),
171 output_offset_frames: 0 /* output_offset_frames */, num_frames_to_copy);
172}
173
174void PlanarFromInterleaved(const int16* interleaved_buffer,
175 size_t num_input_frames, size_t num_input_channels,
176 const std::vector<float*>& planar_buffer_ptr,
177 size_t num_output_frames) {
178 DCHECK(interleaved_buffer);
179 DCHECK_GT(planar_buffer_ptr.size(), 0);
180
181 const size_t num_frames_to_copy =
182 std::min(a: num_input_frames, b: num_output_frames);
183 ConvertInterleavedToPlanarTemplated<const int16*, float* const*>(
184 interleaved_buffer, num_input_frames, num_input_channels,
185 input_offset_frames: 0 /* input_offset_frames */, channel_map: nullptr /* channel_map*/,
186 output_buffer: planar_buffer_ptr.data(), num_output_frames, num_output_channels: planar_buffer_ptr.size(),
187 output_offset_frames: 0 /* output_offset_frames */, num_frames_to_copy);
188}
189
190void FillAudioBuffer(const float* interleaved_buffer, size_t num_input_frames,
191 size_t num_input_channels, AudioBuffer* output) {
192 DCHECK(interleaved_buffer);
193 DCHECK(output);
194 const size_t num_frames_to_copy =
195 std::min(a: num_input_frames, b: output->num_frames());
196 ConvertInterleavedToPlanarTemplated<const float*, AudioBuffer&>(
197 interleaved_buffer, num_input_frames, num_input_channels,
198 input_offset_frames: 0 /* input_offset_frames */, channel_map: nullptr /* channel_map*/, output_buffer&: *output,
199 num_output_frames: output->num_frames(), num_output_channels: output->num_channels(),
200 output_offset_frames: 0 /* output_offset_frames */, num_frames_to_copy);
201}
202
203void FillAudioBuffer(const int16* interleaved_buffer, size_t num_input_frames,
204 size_t num_input_channels, AudioBuffer* output) {
205 DCHECK(interleaved_buffer);
206 DCHECK(output);
207 const size_t num_frames_to_copy =
208 std::min(a: num_input_frames, b: output->num_frames());
209
210 ConvertInterleavedToPlanarTemplated<const int16*, AudioBuffer&>(
211 interleaved_buffer, num_input_frames, num_input_channels,
212 input_offset_frames: 0 /* input_offset_frames */, channel_map: nullptr /* channel_map*/, output_buffer&: *output,
213 num_output_frames: output->num_frames(), num_output_channels: output->num_channels(),
214 output_offset_frames: 0 /* output_offset_frames */, num_frames_to_copy);
215}
216
217void FillAudioBuffer(const std::vector<float>& interleaved_buffer,
218 size_t num_input_channels, AudioBuffer* output) {
219 DCHECK(output);
220 DCHECK_EQ(interleaved_buffer.size() % num_input_channels, 0);
221 const size_t num_frames_to_copy = std::min(
222 a: interleaved_buffer.size() / num_input_channels, b: output->num_frames());
223 FillAudioBuffer(interleaved_buffer: &interleaved_buffer[0], num_input_frames: num_frames_to_copy,
224 num_input_channels, output);
225}
226
227void FillAudioBuffer(const std::vector<int16>& interleaved_buffer,
228 size_t num_input_channels, AudioBuffer* output) {
229 DCHECK(output);
230 DCHECK_EQ(interleaved_buffer.size() % num_input_channels, 0);
231 const size_t num_frames_to_copy = std::min(
232 a: interleaved_buffer.size() / num_input_channels, b: output->num_frames());
233 FillAudioBuffer(interleaved_buffer: &interleaved_buffer[0], num_input_frames: num_frames_to_copy,
234 num_input_channels, output);
235}
236
237void FillAudioBuffer(const float* const* planar_ptrs, size_t num_input_frames,
238 size_t num_input_channels, AudioBuffer* output) {
239 DCHECK(planar_ptrs);
240 DCHECK(output);
241 const size_t num_frames_to_copy =
242 std::min(a: num_input_frames, b: output->num_frames());
243 ConvertPlanarToPlanarTemplated<const float* const*, AudioBuffer&>(
244 input: planar_ptrs, num_input_frames, num_input_channels,
245 input_offset_frames: 0 /* input_offset_frames */, channel_map: nullptr /* channel_map*/, planar_output_ptrs&: *output,
246 num_output_frames: output->num_frames(), num_output_channels: output->num_channels(),
247 output_offset_frames: 0 /* output_offset_frames */, num_frames_convert_and_copy: num_frames_to_copy);
248}
249
250void FillAudioBuffer(const int16* const* planar_ptrs, size_t num_input_frames,
251 size_t num_input_channels, AudioBuffer* output) {
252 DCHECK(planar_ptrs);
253 DCHECK(output);
254 const size_t num_frames_to_copy =
255 std::min(a: num_input_frames, b: output->num_frames());
256 ConvertPlanarToPlanarTemplated<const int16* const*, AudioBuffer&>(
257 input: planar_ptrs, num_input_frames, num_input_channels,
258 input_offset_frames: 0 /* input_offset_frames */, channel_map: nullptr /* channel_map*/, planar_output_ptrs&: *output,
259 num_output_frames: output->num_frames(), num_output_channels: output->num_channels(),
260 output_offset_frames: 0 /* output_offset_frames */, num_frames_convert_and_copy: num_frames_to_copy);
261}
262
263void FillAudioBufferWithOffset(const float* interleaved_buffer,
264 size_t num_input_frames,
265 size_t num_input_channels,
266 size_t input_frame_offset,
267 size_t output_frame_offset,
268 size_t num_frames_to_copy, AudioBuffer* output) {
269 DCHECK(interleaved_buffer);
270 DCHECK(output);
271 ConvertInterleavedToPlanarTemplated<const float*, AudioBuffer&>(
272 interleaved_buffer, num_input_frames, num_input_channels,
273 input_offset_frames: input_frame_offset, channel_map: nullptr /* channel_map*/, output_buffer&: *output,
274 num_output_frames: output->num_frames(), num_output_channels: output->num_channels(), output_offset_frames: output_frame_offset,
275 num_frames_to_copy);
276}
277
278void FillAudioBufferWithOffset(const int16* interleaved_buffer,
279 size_t num_input_frames,
280 size_t num_input_channels,
281 size_t input_frame_offset,
282 size_t output_frame_offset,
283 size_t num_frames_to_copy, AudioBuffer* output) {
284 DCHECK(interleaved_buffer);
285 DCHECK(output);
286 ConvertInterleavedToPlanarTemplated<const int16*, AudioBuffer&>(
287 interleaved_buffer, num_input_frames, num_input_channels,
288 input_offset_frames: input_frame_offset, channel_map: nullptr /* channel_map*/, output_buffer&: *output,
289 num_output_frames: output->num_frames(), num_output_channels: output->num_channels(), output_offset_frames: output_frame_offset,
290 num_frames_to_copy);
291}
292
293void FillAudioBufferWithOffset(const float* const* planar_ptrs,
294 size_t num_input_frames,
295 size_t num_input_channels,
296 size_t input_frame_offset,
297 size_t output_frame_offset,
298 size_t num_frames_to_copy, AudioBuffer* output) {
299 DCHECK(planar_ptrs);
300 DCHECK(output);
301 ConvertPlanarToPlanarTemplated<const float* const*, AudioBuffer&>(
302 input: planar_ptrs, num_input_frames, num_input_channels, input_offset_frames: input_frame_offset,
303 channel_map: nullptr /* channel_map*/, planar_output_ptrs&: *output, num_output_frames: output->num_frames(),
304 num_output_channels: output->num_channels(), output_offset_frames: output_frame_offset, num_frames_convert_and_copy: num_frames_to_copy);
305}
306
307void FillAudioBufferWithOffset(const int16* const* planar_ptrs,
308 size_t num_input_frames,
309 size_t num_input_channels,
310 size_t input_frame_offset,
311 size_t output_frame_offset,
312 size_t num_frames_to_copy, AudioBuffer* output) {
313 DCHECK(planar_ptrs);
314 DCHECK(output);
315 ConvertPlanarToPlanarTemplated<const int16* const*, AudioBuffer&>(
316 input: planar_ptrs, num_input_frames, num_input_channels, input_offset_frames: input_frame_offset,
317 channel_map: nullptr /* channel_map*/, planar_output_ptrs&: *output, num_output_frames: output->num_frames(),
318 num_output_channels: output->num_channels(), output_offset_frames: output_frame_offset, num_frames_convert_and_copy: num_frames_to_copy);
319}
320
321void FillAudioBufferWithChannelRemapping(const int16* interleaved_buffer,
322 size_t num_input_frames,
323 size_t num_input_channels,
324 const std::vector<size_t>& channel_map,
325 AudioBuffer* output) {
326 DCHECK(interleaved_buffer);
327 DCHECK(output);
328 const size_t num_frames_to_copy =
329 std::min(a: num_input_frames, b: output->num_frames());
330 ConvertInterleavedToPlanarTemplated<const int16*, AudioBuffer&>(
331 interleaved_buffer, num_input_frames, num_input_channels,
332 input_offset_frames: 0 /*input_frame_offset*/, channel_map: &channel_map, output_buffer&: *output, num_output_frames: output->num_frames(),
333 num_output_channels: output->num_channels(), output_offset_frames: 0 /*output_frame_offset*/, num_frames_to_copy);
334}
335
336void FillAudioBufferWithChannelRemapping(const float* interleaved_buffer,
337 size_t num_input_frames,
338 size_t num_input_channels,
339 const std::vector<size_t>& channel_map,
340 AudioBuffer* output) {
341 DCHECK(interleaved_buffer);
342 DCHECK(output);
343 const size_t num_frames_to_copy =
344 std::min(a: num_input_frames, b: output->num_frames());
345 ConvertInterleavedToPlanarTemplated<const float*, AudioBuffer&>(
346 interleaved_buffer, num_input_frames, num_input_channels,
347 input_offset_frames: 0 /*input_frame_offset*/, channel_map: &channel_map, output_buffer&: *output, num_output_frames: output->num_frames(),
348 num_output_channels: output->num_channels(), output_offset_frames: 0 /*output_frame_offset*/, num_frames_to_copy);
349}
350
351void FillAudioBufferWithChannelRemapping(const float* const* planar_ptrs,
352 size_t num_input_frames,
353 size_t num_input_channels,
354 const std::vector<size_t>& channel_map,
355 AudioBuffer* output) {
356 DCHECK(planar_ptrs);
357 DCHECK(output);
358 const size_t num_frames_to_copy =
359 std::min(a: num_input_frames, b: output->num_frames());
360 ConvertPlanarToPlanarTemplated<const float* const*, AudioBuffer&>(
361 input: planar_ptrs, num_input_frames, num_input_channels,
362 input_offset_frames: 0 /*input_offset_frames*/, channel_map: &channel_map, planar_output_ptrs&: *output, num_output_frames: output->num_frames(),
363 num_output_channels: output->num_channels(), output_offset_frames: 0 /* output_offset_frames*/, num_frames_convert_and_copy: num_frames_to_copy);
364}
365
366void FillAudioBufferWithChannelRemapping(const int16* const* planar_ptr,
367 size_t num_input_frames,
368 size_t num_input_channels,
369 const std::vector<size_t>& channel_map,
370 AudioBuffer* output) {
371 DCHECK(planar_ptr);
372 DCHECK(output);
373 const size_t num_frames_to_copy =
374 std::min(a: num_input_frames, b: output->num_frames());
375 ConvertPlanarToPlanarTemplated<const int16* const*, AudioBuffer&>(
376 input: planar_ptr, num_input_frames, num_input_channels,
377 input_offset_frames: 0 /*input_offset_frames*/, channel_map: &channel_map, planar_output_ptrs&: *output, num_output_frames: output->num_frames(),
378 num_output_channels: output->num_channels(), output_offset_frames: 0 /* output_offset_frames*/, num_frames_convert_and_copy: num_frames_to_copy);
379}
380
381void FillExternalBuffer(const AudioBuffer& input, std::vector<float>* output) {
382 DCHECK(output);
383 output->resize(new_size: input.num_frames() * input.num_channels());
384 FillExternalBuffer(input, interleaved_output_buffer: output->data(), num_output_frames: input.num_frames(),
385 num_output_channels: input.num_channels());
386}
387
388void FillExternalBuffer(const AudioBuffer& input, std::vector<int16>* output) {
389 DCHECK(output);
390 output->resize(new_size: input.num_frames() * input.num_channels());
391 FillExternalBuffer(input, interleaved_output_buffer: output->data(), num_output_frames: input.num_frames(),
392 num_output_channels: input.num_channels());
393}
394
395void FillExternalBuffer(const AudioBuffer& input,
396 int16* const* planar_output_ptrs,
397 size_t num_output_frames, size_t num_output_channels) {
398 ConvertPlanarToPlanarTemplated<const AudioBuffer&, int16* const*>(
399 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(),
400 input_offset_frames: 0 /*input_offset_frames*/, channel_map: nullptr /* channel_map*/, planar_output_ptrs,
401 num_output_frames, num_output_channels, output_offset_frames: 0 /* output_offset_frames*/,
402 num_frames_convert_and_copy: num_output_frames);
403}
404
405void FillExternalBuffer(const AudioBuffer& input,
406 float* const* planar_output_ptrs,
407 size_t num_output_frames, size_t num_output_channels) {
408 ConvertPlanarToPlanarTemplated<const AudioBuffer&, float* const*>(
409 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(),
410 input_offset_frames: 0 /*input_offset_frames*/, channel_map: nullptr /* channel_map*/, planar_output_ptrs,
411 num_output_frames, num_output_channels, output_offset_frames: 0 /* output_offset_frames*/,
412 num_frames_convert_and_copy: num_output_frames);
413}
414
415void FillExternalBuffer(const AudioBuffer& input,
416 int16* interleaved_output_buffer,
417 size_t num_output_frames, size_t num_output_channels) {
418 ConvertPlanarToInterleavedTemplated<const AudioBuffer&, int16*>(
419 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(),
420 input_offset_frames: 0 /*input_offset_frames*/, interleaved_output_ptr: interleaved_output_buffer, num_output_frames,
421 num_output_channels, output_offset_frames: 0 /* output_offset_frames*/, num_frames_convert_and_copy: num_output_frames);
422}
423
424void FillExternalBuffer(const AudioBuffer& input,
425 float* interleaved_output_buffer,
426 size_t num_output_frames, size_t num_output_channels) {
427 ConvertPlanarToInterleavedTemplated<const AudioBuffer&, float*>(
428 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(),
429 input_offset_frames: 0 /*input_offset_frames*/, interleaved_output_ptr: interleaved_output_buffer, num_output_frames,
430 num_output_channels, output_offset_frames: 0 /* output_offset_frames*/, num_frames_convert_and_copy: num_output_frames);
431}
432
433void FillExternalBufferWithOffset(const AudioBuffer& input,
434 size_t input_offset_frames,
435 int16* const* planar_output_ptrs,
436 size_t num_output_frames,
437 size_t num_output_channels,
438 size_t output_offset_frames,
439 size_t num_frames_convert_and_copy) {
440 ConvertPlanarToPlanarTemplated<const AudioBuffer&, int16* const*>(
441 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(), input_offset_frames,
442 channel_map: nullptr /* channel_map */, planar_output_ptrs, num_output_frames,
443 num_output_channels, output_offset_frames, num_frames_convert_and_copy);
444}
445
446void FillExternalBufferWithOffset(const AudioBuffer& input,
447 size_t input_offset_frames,
448 float* const* planar_output_ptrs,
449 size_t num_output_frames,
450 size_t num_output_channels,
451 size_t output_offset_frames,
452 size_t num_frames_convert_and_copy) {
453 ConvertPlanarToPlanarTemplated<const AudioBuffer&, float* const*>(
454 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(), input_offset_frames,
455 channel_map: nullptr /* channel_map */, planar_output_ptrs, num_output_frames,
456 num_output_channels, output_offset_frames, num_frames_convert_and_copy);
457}
458
459void FillExternalBufferWithOffset(const AudioBuffer& input,
460 size_t input_offset_frames,
461 int16* interleaved_output_buffer,
462 size_t num_output_frames,
463 size_t num_output_channels,
464 size_t output_offset_frames,
465 size_t num_frames_convert_and_copy) {
466 ConvertPlanarToInterleavedTemplated<const AudioBuffer&, int16*>(
467 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(), input_offset_frames,
468 interleaved_output_ptr: interleaved_output_buffer, num_output_frames, num_output_channels,
469 output_offset_frames, num_frames_convert_and_copy);
470}
471
472void FillExternalBufferWithOffset(const AudioBuffer& input,
473 size_t input_offset_frames,
474 float* interleaved_output_buffer,
475 size_t num_output_frames,
476 size_t num_output_channels,
477 size_t output_offset_frames,
478 size_t num_frames_convert_and_copy) {
479 ConvertPlanarToInterleavedTemplated<const AudioBuffer&, float*>(
480 input, num_input_frames: input.num_frames(), num_input_channels: input.num_channels(), input_offset_frames,
481 interleaved_output_ptr: interleaved_output_buffer, num_output_frames, num_output_channels,
482 output_offset_frames, num_frames_convert_and_copy);
483}
484
485void GetRawChannelDataPointersFromAudioBuffer(
486 AudioBuffer* audio_buffer, std::vector<float*>* channel_ptr_vector) {
487 DCHECK(audio_buffer);
488 DCHECK(channel_ptr_vector);
489 DCHECK_EQ(audio_buffer->num_channels(), channel_ptr_vector->size());
490 for (size_t i = 0; i < audio_buffer->num_channels(); ++i) {
491 (*channel_ptr_vector)[i] = &(*audio_buffer)[i][0];
492 }
493}
494
495void GetRawChannelDataPointersFromAudioBuffer(
496 const AudioBuffer& audio_buffer,
497 std::vector<const float*>* channel_ptr_vector) {
498 DCHECK(channel_ptr_vector);
499 DCHECK_EQ(audio_buffer.num_channels(), channel_ptr_vector->size());
500 for (size_t i = 0; i < audio_buffer.num_channels(); ++i) {
501 (*channel_ptr_vector)[i] = &audio_buffer[i][0];
502 }
503}
504
505} // namespace vraudio
506

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/utils/planar_interleaved_conversion.cc