| 1 | /* | 
| 2 | Copyright 2018 Google Inc. All Rights Reserved. | 
| 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 | // 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 |  | 
| 30 | namespace vraudio { | 
| 31 |  | 
| 32 | namespace { | 
| 33 |  | 
| 34 | template <typename InputType, typename OutputType> | 
| 35 | void 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 |  | 
| 88 | template <typename PlanarInputType, typename PlanarOutputType> | 
| 89 | void 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 |  | 
| 118 | template <typename PlanarInputType, typename InterleavedOutputType> | 
| 119 | void 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 |  | 
| 158 | void 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 |  | 
| 174 | void 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 |  | 
| 190 | void 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 |  | 
| 203 | void 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 |  | 
| 217 | void 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 |  | 
| 227 | void 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 |  | 
| 237 | void 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 |  | 
| 250 | void 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 |  | 
| 263 | void 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 |  | 
| 278 | void 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 |  | 
| 293 | void 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 |  | 
| 307 | void 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 |  | 
| 321 | void 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 |  | 
| 336 | void 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 |  | 
| 351 | void 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 |  | 
| 366 | void 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 |  | 
| 381 | void 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 |  | 
| 388 | void 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 |  | 
| 395 | void 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 |  | 
| 405 | void 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 |  | 
| 415 | void 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 |  | 
| 424 | void 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 |  | 
| 433 | void 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 |  | 
| 446 | void 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 |  | 
| 459 | void 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 |  | 
| 472 | void 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 |  | 
| 485 | void 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 |  | 
| 495 | void 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 |  |