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/buffer_unpartitioner.h"
23
24#include "utils/planar_interleaved_conversion.h"
25#include "utils/sample_type_conversion.h"
26
27namespace vraudio {
28
29BufferUnpartitioner::BufferUnpartitioner(size_t num_channels,
30 size_t frames_per_buffer,
31 GetBufferCallback buffer_callback)
32 : num_channels_(num_channels),
33 frames_per_buffer_(frames_per_buffer),
34 buffer_callback_(std::move(buffer_callback)),
35 current_input_buffer_(nullptr),
36 current_buffer_read_offset_frames_(0) {
37 DCHECK_GT(frames_per_buffer_, 0);
38 DCHECK_GT(num_channels, 0);
39}
40
41size_t BufferUnpartitioner::GetNumBuffersRequestedForNumInputFrames(
42 size_t num_output_frames) const {
43 if (num_output_frames == 0) {
44 return 0;
45 }
46 return (num_output_frames - GetNumFramesAvailableInBuffer() +
47 frames_per_buffer_ - 1) /
48 frames_per_buffer_;
49}
50
51size_t BufferUnpartitioner::GetBuffer(int16* output_buffer, size_t num_channels,
52 size_t num_frames) {
53 return GetBufferTemplated<int16*>(buffer: output_buffer, num_channels, num_frames);
54}
55
56size_t BufferUnpartitioner::GetBuffer(float* output_buffer, size_t num_channels,
57 size_t num_frames) {
58 return GetBufferTemplated<float*>(buffer: output_buffer, num_channels, num_frames);
59}
60
61size_t BufferUnpartitioner::GetBuffer(int16** output_buffer,
62 size_t num_channels, size_t num_frames) {
63 return GetBufferTemplated<int16**>(buffer: output_buffer, num_channels, num_frames);
64}
65
66size_t BufferUnpartitioner::GetBuffer(float** output_buffer,
67 size_t num_channels, size_t num_frames) {
68 return GetBufferTemplated<float**>(buffer: output_buffer, num_channels, num_frames);
69}
70
71size_t BufferUnpartitioner::GetNumBufferedFrames() const {
72 return current_buffer_read_offset_frames_;
73}
74
75size_t BufferUnpartitioner::GetNumFramesAvailableInBuffer() const {
76 if (current_input_buffer_ == nullptr) {
77 return 0;
78 }
79 DCHECK_GE(current_input_buffer_->num_frames(),
80 current_buffer_read_offset_frames_);
81 return current_input_buffer_->num_frames() -
82 current_buffer_read_offset_frames_;
83}
84
85void BufferUnpartitioner::Clear() {
86 current_input_buffer_ = nullptr;
87 current_buffer_read_offset_frames_ = 0;
88}
89
90template <typename BufferType>
91size_t BufferUnpartitioner::GetBufferTemplated(BufferType buffer,
92 size_t num_channels,
93 size_t num_frames) {
94 DCHECK_EQ(num_channels, num_channels_);
95
96 size_t num_copied_frames = 0;
97 while (num_copied_frames < num_frames) {
98 if (current_input_buffer_ == nullptr) {
99 current_input_buffer_ = buffer_callback_();
100 if (current_input_buffer_ == nullptr) {
101 // No more input |AudioBuffer|s are available.
102 return num_copied_frames;
103 }
104 DCHECK_EQ(frames_per_buffer_, current_input_buffer_->num_frames());
105 current_buffer_read_offset_frames_ = 0;
106 }
107 DCHECK_GE(frames_per_buffer_, current_buffer_read_offset_frames_);
108 const size_t remaining_frames_in_input_buffer =
109 num_frames - num_copied_frames;
110 DCHECK_GE(current_input_buffer_->num_frames(),
111 current_buffer_read_offset_frames_);
112 const size_t num_frames_to_process =
113 std::min(a: current_input_buffer_->num_frames() -
114 current_buffer_read_offset_frames_,
115 b: remaining_frames_in_input_buffer);
116
117 FillExternalBufferWithOffset(
118 *current_input_buffer_, current_buffer_read_offset_frames_, buffer,
119 num_frames, num_channels, num_copied_frames, num_frames_to_process);
120
121 num_copied_frames += num_frames_to_process;
122
123 current_buffer_read_offset_frames_ += num_frames_to_process;
124 if (current_buffer_read_offset_frames_ ==
125 current_input_buffer_->num_frames()) {
126 current_input_buffer_ = nullptr;
127 }
128 }
129 return num_copied_frames;
130}
131
132} // namespace vraudio
133

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