1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/audio_processing/audio_buffer.h"
12
13 #include <string.h>
14
15 #include <cstdint>
16
17 #include "common_audio/channel_buffer.h"
18 #include "common_audio/include/audio_util.h"
19 #include "common_audio/resampler/push_sinc_resampler.h"
20 #include "modules/audio_processing/splitting_filter.h"
21 #include "rtc_base/checks.h"
22
23 namespace webrtc {
24 namespace {
25
26 constexpr size_t kSamplesPer32kHzChannel = 320;
27 constexpr size_t kSamplesPer48kHzChannel = 480;
28 constexpr size_t kMaxSamplesPerChannel = AudioBuffer::kMaxSampleRate / 100;
29
NumBandsFromFramesPerChannel(size_t num_frames)30 size_t NumBandsFromFramesPerChannel(size_t num_frames) {
31 if (num_frames == kSamplesPer32kHzChannel) {
32 return 2;
33 }
34 if (num_frames == kSamplesPer48kHzChannel) {
35 return 3;
36 }
37 return 1;
38 }
39
40 } // namespace
41
AudioBuffer(size_t input_rate,size_t input_num_channels,size_t buffer_rate,size_t buffer_num_channels,size_t output_rate,size_t output_num_channels)42 AudioBuffer::AudioBuffer(size_t input_rate,
43 size_t input_num_channels,
44 size_t buffer_rate,
45 size_t buffer_num_channels,
46 size_t output_rate,
47 size_t output_num_channels)
48 : input_num_frames_(static_cast<int>(input_rate) / 100),
49 input_num_channels_(input_num_channels),
50 buffer_num_frames_(static_cast<int>(buffer_rate) / 100),
51 buffer_num_channels_(buffer_num_channels),
52 output_num_frames_(static_cast<int>(output_rate) / 100),
53 output_num_channels_(0),
54 num_channels_(buffer_num_channels),
55 num_bands_(NumBandsFromFramesPerChannel(buffer_num_frames_)),
56 num_split_frames_(rtc::CheckedDivExact(buffer_num_frames_, num_bands_)),
57 data_(
58 new ChannelBuffer<float>(buffer_num_frames_, buffer_num_channels_)) {
59 RTC_DCHECK_GT(input_num_frames_, 0);
60 RTC_DCHECK_GT(buffer_num_frames_, 0);
61 RTC_DCHECK_GT(output_num_frames_, 0);
62 RTC_DCHECK_GT(input_num_channels_, 0);
63 RTC_DCHECK_GT(buffer_num_channels_, 0);
64 RTC_DCHECK_LE(buffer_num_channels_, input_num_channels_);
65
66 const bool input_resampling_needed = input_num_frames_ != buffer_num_frames_;
67 const bool output_resampling_needed =
68 output_num_frames_ != buffer_num_frames_;
69 if (input_resampling_needed) {
70 for (size_t i = 0; i < buffer_num_channels_; ++i) {
71 input_resamplers_.push_back(std::unique_ptr<PushSincResampler>(
72 new PushSincResampler(input_num_frames_, buffer_num_frames_)));
73 }
74 }
75
76 if (output_resampling_needed) {
77 for (size_t i = 0; i < buffer_num_channels_; ++i) {
78 output_resamplers_.push_back(std::unique_ptr<PushSincResampler>(
79 new PushSincResampler(buffer_num_frames_, output_num_frames_)));
80 }
81 }
82
83 if (num_bands_ > 1) {
84 split_data_.reset(new ChannelBuffer<float>(
85 buffer_num_frames_, buffer_num_channels_, num_bands_));
86 splitting_filter_.reset(new SplittingFilter(
87 buffer_num_channels_, num_bands_, buffer_num_frames_));
88 }
89 }
90
~AudioBuffer()91 AudioBuffer::~AudioBuffer() {}
92
set_downmixing_to_specific_channel(size_t channel)93 void AudioBuffer::set_downmixing_to_specific_channel(size_t channel) {
94 downmix_by_averaging_ = false;
95 RTC_DCHECK_GT(input_num_channels_, channel);
96 channel_for_downmixing_ = std::min(channel, input_num_channels_ - 1);
97 }
98
set_downmixing_by_averaging()99 void AudioBuffer::set_downmixing_by_averaging() {
100 downmix_by_averaging_ = true;
101 }
102
CopyFrom(const float * const * stacked_data,const StreamConfig & stream_config)103 void AudioBuffer::CopyFrom(const float* const* stacked_data,
104 const StreamConfig& stream_config) {
105 RTC_DCHECK_EQ(stream_config.num_frames(), input_num_frames_);
106 RTC_DCHECK_EQ(stream_config.num_channels(), input_num_channels_);
107 RestoreNumChannels();
108 const bool downmix_needed = input_num_channels_ > 1 && num_channels_ == 1;
109
110 const bool resampling_needed = input_num_frames_ != buffer_num_frames_;
111
112 if (downmix_needed) {
113 RTC_DCHECK_GE(kMaxSamplesPerChannel, input_num_frames_);
114
115 std::array<float, kMaxSamplesPerChannel> downmix;
116 if (downmix_by_averaging_) {
117 const float kOneByNumChannels = 1.f / input_num_channels_;
118 for (size_t i = 0; i < input_num_frames_; ++i) {
119 float value = stacked_data[0][i];
120 for (size_t j = 1; j < input_num_channels_; ++j) {
121 value += stacked_data[j][i];
122 }
123 downmix[i] = value * kOneByNumChannels;
124 }
125 }
126 const float* downmixed_data = downmix_by_averaging_
127 ? downmix.data()
128 : stacked_data[channel_for_downmixing_];
129
130 if (resampling_needed) {
131 input_resamplers_[0]->Resample(downmixed_data, input_num_frames_,
132 data_->channels()[0], buffer_num_frames_);
133 }
134 const float* data_to_convert =
135 resampling_needed ? data_->channels()[0] : downmixed_data;
136 FloatToFloatS16(data_to_convert, buffer_num_frames_, data_->channels()[0]);
137 } else {
138 if (resampling_needed) {
139 for (size_t i = 0; i < num_channels_; ++i) {
140 input_resamplers_[i]->Resample(stacked_data[i], input_num_frames_,
141 data_->channels()[i],
142 buffer_num_frames_);
143 FloatToFloatS16(data_->channels()[i], buffer_num_frames_,
144 data_->channels()[i]);
145 }
146 } else {
147 for (size_t i = 0; i < num_channels_; ++i) {
148 FloatToFloatS16(stacked_data[i], buffer_num_frames_,
149 data_->channels()[i]);
150 }
151 }
152 }
153 }
154
CopyTo(const StreamConfig & stream_config,float * const * stacked_data)155 void AudioBuffer::CopyTo(const StreamConfig& stream_config,
156 float* const* stacked_data) {
157 RTC_DCHECK_EQ(stream_config.num_frames(), output_num_frames_);
158
159 const bool resampling_needed = output_num_frames_ != buffer_num_frames_;
160 if (resampling_needed) {
161 for (size_t i = 0; i < num_channels_; ++i) {
162 FloatS16ToFloat(data_->channels()[i], buffer_num_frames_,
163 data_->channels()[i]);
164 output_resamplers_[i]->Resample(data_->channels()[i], buffer_num_frames_,
165 stacked_data[i], output_num_frames_);
166 }
167 } else {
168 for (size_t i = 0; i < num_channels_; ++i) {
169 FloatS16ToFloat(data_->channels()[i], buffer_num_frames_,
170 stacked_data[i]);
171 }
172 }
173
174 for (size_t i = num_channels_; i < stream_config.num_channels(); ++i) {
175 memcpy(stacked_data[i], stacked_data[0],
176 output_num_frames_ * sizeof(**stacked_data));
177 }
178 }
179
CopyTo(AudioBuffer * buffer) const180 void AudioBuffer::CopyTo(AudioBuffer* buffer) const {
181 RTC_DCHECK_EQ(buffer->num_frames(), output_num_frames_);
182
183 const bool resampling_needed = output_num_frames_ != buffer_num_frames_;
184 if (resampling_needed) {
185 for (size_t i = 0; i < num_channels_; ++i) {
186 output_resamplers_[i]->Resample(data_->channels()[i], buffer_num_frames_,
187 buffer->channels()[i],
188 buffer->num_frames());
189 }
190 } else {
191 for (size_t i = 0; i < num_channels_; ++i) {
192 memcpy(buffer->channels()[i], data_->channels()[i],
193 buffer_num_frames_ * sizeof(**buffer->channels()));
194 }
195 }
196
197 for (size_t i = num_channels_; i < buffer->num_channels(); ++i) {
198 memcpy(buffer->channels()[i], buffer->channels()[0],
199 output_num_frames_ * sizeof(**buffer->channels()));
200 }
201 }
202
RestoreNumChannels()203 void AudioBuffer::RestoreNumChannels() {
204 num_channels_ = buffer_num_channels_;
205 data_->set_num_channels(buffer_num_channels_);
206 if (split_data_.get()) {
207 split_data_->set_num_channels(buffer_num_channels_);
208 }
209 }
210
set_num_channels(size_t num_channels)211 void AudioBuffer::set_num_channels(size_t num_channels) {
212 RTC_DCHECK_GE(buffer_num_channels_, num_channels);
213 num_channels_ = num_channels;
214 data_->set_num_channels(num_channels);
215 if (split_data_.get()) {
216 split_data_->set_num_channels(num_channels);
217 }
218 }
219
220 // The resampler is only for supporting 48kHz to 16kHz in the reverse stream.
CopyFrom(const int16_t * const interleaved_data,const StreamConfig & stream_config)221 void AudioBuffer::CopyFrom(const int16_t* const interleaved_data,
222 const StreamConfig& stream_config) {
223 RTC_DCHECK_EQ(stream_config.num_channels(), input_num_channels_);
224 RTC_DCHECK_EQ(stream_config.num_frames(), input_num_frames_);
225 RestoreNumChannels();
226
227 const bool resampling_required = input_num_frames_ != buffer_num_frames_;
228
229 const int16_t* interleaved = interleaved_data;
230 if (num_channels_ == 1) {
231 if (input_num_channels_ == 1) {
232 if (resampling_required) {
233 std::array<float, kMaxSamplesPerChannel> float_buffer;
234 S16ToFloatS16(interleaved, input_num_frames_, float_buffer.data());
235 input_resamplers_[0]->Resample(float_buffer.data(), input_num_frames_,
236 data_->channels()[0],
237 buffer_num_frames_);
238 } else {
239 S16ToFloatS16(interleaved, input_num_frames_, data_->channels()[0]);
240 }
241 } else {
242 std::array<float, kMaxSamplesPerChannel> float_buffer;
243 float* downmixed_data =
244 resampling_required ? float_buffer.data() : data_->channels()[0];
245 if (downmix_by_averaging_) {
246 for (size_t j = 0, k = 0; j < input_num_frames_; ++j) {
247 int32_t sum = 0;
248 for (size_t i = 0; i < input_num_channels_; ++i, ++k) {
249 sum += interleaved[k];
250 }
251 downmixed_data[j] = sum / static_cast<int16_t>(input_num_channels_);
252 }
253 } else {
254 for (size_t j = 0, k = channel_for_downmixing_; j < input_num_frames_;
255 ++j, k += input_num_channels_) {
256 downmixed_data[j] = interleaved[k];
257 }
258 }
259
260 if (resampling_required) {
261 input_resamplers_[0]->Resample(downmixed_data, input_num_frames_,
262 data_->channels()[0],
263 buffer_num_frames_);
264 }
265 }
266 } else {
267 auto deinterleave_channel = [](size_t channel, size_t num_channels,
268 size_t samples_per_channel, const int16_t* x,
269 float* y) {
270 for (size_t j = 0, k = channel; j < samples_per_channel;
271 ++j, k += num_channels) {
272 y[j] = x[k];
273 }
274 };
275
276 if (resampling_required) {
277 std::array<float, kMaxSamplesPerChannel> float_buffer;
278 for (size_t i = 0; i < num_channels_; ++i) {
279 deinterleave_channel(i, num_channels_, input_num_frames_, interleaved,
280 float_buffer.data());
281 input_resamplers_[i]->Resample(float_buffer.data(), input_num_frames_,
282 data_->channels()[i],
283 buffer_num_frames_);
284 }
285 } else {
286 for (size_t i = 0; i < num_channels_; ++i) {
287 deinterleave_channel(i, num_channels_, input_num_frames_, interleaved,
288 data_->channels()[i]);
289 }
290 }
291 }
292 }
293
CopyTo(const StreamConfig & stream_config,int16_t * const interleaved_data)294 void AudioBuffer::CopyTo(const StreamConfig& stream_config,
295 int16_t* const interleaved_data) {
296 const size_t config_num_channels = stream_config.num_channels();
297
298 RTC_DCHECK(config_num_channels == num_channels_ || num_channels_ == 1);
299 RTC_DCHECK_EQ(stream_config.num_frames(), output_num_frames_);
300
301 const bool resampling_required = buffer_num_frames_ != output_num_frames_;
302
303 int16_t* interleaved = interleaved_data;
304 if (num_channels_ == 1) {
305 std::array<float, kMaxSamplesPerChannel> float_buffer;
306
307 if (resampling_required) {
308 output_resamplers_[0]->Resample(data_->channels()[0], buffer_num_frames_,
309 float_buffer.data(), output_num_frames_);
310 }
311 const float* deinterleaved =
312 resampling_required ? float_buffer.data() : data_->channels()[0];
313
314 if (config_num_channels == 1) {
315 for (size_t j = 0; j < output_num_frames_; ++j) {
316 interleaved[j] = FloatS16ToS16(deinterleaved[j]);
317 }
318 } else {
319 for (size_t i = 0, k = 0; i < output_num_frames_; ++i) {
320 float tmp = FloatS16ToS16(deinterleaved[i]);
321 for (size_t j = 0; j < config_num_channels; ++j, ++k) {
322 interleaved[k] = tmp;
323 }
324 }
325 }
326 } else {
327 auto interleave_channel = [](size_t channel, size_t num_channels,
328 size_t samples_per_channel, const float* x,
329 int16_t* y) {
330 for (size_t k = 0, j = channel; k < samples_per_channel;
331 ++k, j += num_channels) {
332 y[j] = FloatS16ToS16(x[k]);
333 }
334 };
335
336 if (resampling_required) {
337 for (size_t i = 0; i < num_channels_; ++i) {
338 std::array<float, kMaxSamplesPerChannel> float_buffer;
339 output_resamplers_[i]->Resample(data_->channels()[i],
340 buffer_num_frames_, float_buffer.data(),
341 output_num_frames_);
342 interleave_channel(i, config_num_channels, output_num_frames_,
343 float_buffer.data(), interleaved);
344 }
345 } else {
346 for (size_t i = 0; i < num_channels_; ++i) {
347 interleave_channel(i, config_num_channels, output_num_frames_,
348 data_->channels()[i], interleaved);
349 }
350 }
351
352 for (size_t i = num_channels_; i < config_num_channels; ++i) {
353 for (size_t j = 0, k = i, n = num_channels_; j < output_num_frames_;
354 ++j, k += config_num_channels, n += config_num_channels) {
355 interleaved[k] = interleaved[n];
356 }
357 }
358 }
359 }
360
SplitIntoFrequencyBands()361 void AudioBuffer::SplitIntoFrequencyBands() {
362 splitting_filter_->Analysis(data_.get(), split_data_.get());
363 }
364
MergeFrequencyBands()365 void AudioBuffer::MergeFrequencyBands() {
366 splitting_filter_->Synthesis(split_data_.get(), data_.get());
367 }
368
ExportSplitChannelData(size_t channel,int16_t * const * split_band_data) const369 void AudioBuffer::ExportSplitChannelData(
370 size_t channel,
371 int16_t* const* split_band_data) const {
372 for (size_t k = 0; k < num_bands(); ++k) {
373 const float* band_data = split_bands_const(channel)[k];
374
375 RTC_DCHECK(split_band_data[k]);
376 RTC_DCHECK(band_data);
377 for (size_t i = 0; i < num_frames_per_band(); ++i) {
378 split_band_data[k][i] = FloatS16ToS16(band_data[i]);
379 }
380 }
381 }
382
ImportSplitChannelData(size_t channel,const int16_t * const * split_band_data)383 void AudioBuffer::ImportSplitChannelData(
384 size_t channel,
385 const int16_t* const* split_band_data) {
386 for (size_t k = 0; k < num_bands(); ++k) {
387 float* band_data = split_bands(channel)[k];
388 RTC_DCHECK(split_band_data[k]);
389 RTC_DCHECK(band_data);
390 for (size_t i = 0; i < num_frames_per_band(); ++i) {
391 band_data[i] = split_band_data[k][i];
392 }
393 }
394 }
395
396 } // namespace webrtc
397