blob: 81ded91738ff332aa037767d70bdcd65caffd456 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
andrew@webrtc.org63a50982012-05-02 23:56:37 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_processing/audio_buffer.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
Yves Gerey988cc082018-10-23 12:03:01 +020013#include <string.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
Yves Gerey988cc082018-10-23 12:03:01 +020015#include <cstdint>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "common_audio/channel_buffer.h"
18#include "common_audio/include/audio_util.h"
19#include "common_audio/resampler/push_sinc_resampler.h"
Yves Gerey988cc082018-10-23 12:03:01 +020020#include "modules/audio_processing/splitting_filter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/checks.h"
andrew@webrtc.org755b04a2011-11-15 16:57:56 +000022
niklase@google.com470e71d2011-07-07 08:21:25 +000023namespace webrtc {
24namespace {
25
Per Åhgrend47941e2019-08-22 11:51:13 +020026constexpr size_t kSamplesPer32kHzChannel = 320;
27constexpr size_t kSamplesPer48kHzChannel = 480;
Per Åhgren3e8bf282019-08-29 23:38:40 +020028constexpr size_t kMaxSamplesPerChannel = AudioBuffer::kMaxSampleRate / 100;
Alejandro Luebs5a92aa82015-04-27 11:34:45 -070029
Per Åhgrend47941e2019-08-22 11:51:13 +020030size_t NumBandsFromFramesPerChannel(size_t num_frames) {
31 if (num_frames == kSamplesPer32kHzChannel) {
32 return 2;
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000033 }
Per Åhgrend47941e2019-08-22 11:51:13 +020034 if (num_frames == kSamplesPer48kHzChannel) {
35 return 3;
36 }
37 return 1;
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000038}
39
niklase@google.com470e71d2011-07-07 08:21:25 +000040} // namespace
41
Per Åhgrend47941e2019-08-22 11:51:13 +020042AudioBuffer::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)
Per Åhgren2ca0b362019-08-26 11:21:16 +020048 : AudioBuffer(static_cast<int>(input_rate) / 100,
Per Åhgrend47941e2019-08-22 11:51:13 +020049 input_num_channels,
Per Åhgren2ca0b362019-08-26 11:21:16 +020050 static_cast<int>(buffer_rate) / 100,
Per Åhgrend47941e2019-08-22 11:51:13 +020051 buffer_num_channels,
Per Åhgren2ca0b362019-08-26 11:21:16 +020052 static_cast<int>(output_rate) / 100) {}
Per Åhgrend47941e2019-08-22 11:51:13 +020053
Steve Antonf254e9e2019-08-21 17:52:28 +000054AudioBuffer::AudioBuffer(size_t input_num_frames,
Per Åhgrend47941e2019-08-22 11:51:13 +020055 size_t input_num_channels,
56 size_t buffer_num_frames,
57 size_t buffer_num_channels,
Steve Antonf254e9e2019-08-21 17:52:28 +000058 size_t output_num_frames)
59 : input_num_frames_(input_num_frames),
Per Åhgrend47941e2019-08-22 11:51:13 +020060 input_num_channels_(input_num_channels),
61 buffer_num_frames_(buffer_num_frames),
62 buffer_num_channels_(buffer_num_channels),
Steve Antonf254e9e2019-08-21 17:52:28 +000063 output_num_frames_(output_num_frames),
Per Åhgrend47941e2019-08-22 11:51:13 +020064 output_num_channels_(0),
65 num_channels_(buffer_num_channels),
66 num_bands_(NumBandsFromFramesPerChannel(buffer_num_frames_)),
67 num_split_frames_(rtc::CheckedDivExact(buffer_num_frames_, num_bands_)),
Gustaf Ullberg422b9e02019-10-09 13:02:14 +020068 data_(
69 new ChannelBuffer<float>(buffer_num_frames_, buffer_num_channels_)) {
kwibergaf476c72016-11-28 15:21:39 -080070 RTC_DCHECK_GT(input_num_frames_, 0);
Per Åhgrend47941e2019-08-22 11:51:13 +020071 RTC_DCHECK_GT(buffer_num_frames_, 0);
kwibergaf476c72016-11-28 15:21:39 -080072 RTC_DCHECK_GT(output_num_frames_, 0);
Per Åhgrend47941e2019-08-22 11:51:13 +020073 RTC_DCHECK_GT(input_num_channels_, 0);
74 RTC_DCHECK_GT(buffer_num_channels_, 0);
75 RTC_DCHECK_LE(buffer_num_channels_, input_num_channels_);
niklase@google.com470e71d2011-07-07 08:21:25 +000076
Per Åhgrend47941e2019-08-22 11:51:13 +020077 const bool input_resampling_needed = input_num_frames_ != buffer_num_frames_;
78 const bool output_resampling_needed =
79 output_num_frames_ != buffer_num_frames_;
80 if (input_resampling_needed) {
81 for (size_t i = 0; i < buffer_num_channels_; ++i) {
82 input_resamplers_.push_back(std::unique_ptr<PushSincResampler>(
83 new PushSincResampler(input_num_frames_, buffer_num_frames_)));
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000084 }
Per Åhgrend47941e2019-08-22 11:51:13 +020085 }
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000086
Per Åhgrend47941e2019-08-22 11:51:13 +020087 if (output_resampling_needed) {
88 for (size_t i = 0; i < buffer_num_channels_; ++i) {
89 output_resamplers_.push_back(std::unique_ptr<PushSincResampler>(
90 new PushSincResampler(buffer_num_frames_, output_num_frames_)));
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +000091 }
92 }
93
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +000094 if (num_bands_ > 1) {
Per Åhgrend47941e2019-08-22 11:51:13 +020095 split_data_.reset(new ChannelBuffer<float>(
96 buffer_num_frames_, buffer_num_channels_, num_bands_));
97 splitting_filter_.reset(new SplittingFilter(
98 buffer_num_channels_, num_bands_, buffer_num_frames_));
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +000099 }
100}
101
andrew@webrtc.org103657b2014-04-24 18:28:56 +0000102AudioBuffer::~AudioBuffer() {}
103
Per Åhgrend47941e2019-08-22 11:51:13 +0200104void AudioBuffer::set_downmixing_to_specific_channel(size_t channel) {
105 downmix_by_averaging_ = false;
106 RTC_DCHECK_GT(input_num_channels_, channel);
107 channel_for_downmixing_ = std::min(channel, input_num_channels_ - 1);
108}
109
110void AudioBuffer::set_downmixing_by_averaging() {
111 downmix_by_averaging_ = true;
112}
113
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000114void AudioBuffer::CopyFrom(const float* const* data,
Michael Graczyk86c6d332015-07-23 11:41:39 -0700115 const StreamConfig& stream_config) {
kwiberg9e2be5f2016-09-14 05:23:22 -0700116 RTC_DCHECK_EQ(stream_config.num_frames(), input_num_frames_);
Per Åhgrend47941e2019-08-22 11:51:13 +0200117 RTC_DCHECK_EQ(stream_config.num_channels(), input_num_channels_);
118 RestoreNumChannels();
119 const bool downmix_needed = input_num_channels_ > 1 && num_channels_ == 1;
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000120
Per Åhgrend47941e2019-08-22 11:51:13 +0200121 const bool resampling_needed = input_num_frames_ != buffer_num_frames_;
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000122
Per Åhgrend47941e2019-08-22 11:51:13 +0200123 if (downmix_needed) {
Per Åhgren3e8bf282019-08-29 23:38:40 +0200124 RTC_DCHECK_GE(kMaxSamplesPerChannel, input_num_frames_);
Per Åhgrend47941e2019-08-22 11:51:13 +0200125
126 std::array<float, kMaxSamplesPerChannel> downmix;
127 if (downmix_by_averaging_) {
128 const float kOneByNumChannels = 1.f / input_num_channels_;
129 for (size_t i = 0; i < input_num_frames_; ++i) {
130 float value = data[0][i];
131 for (size_t j = 1; j < input_num_channels_; ++j) {
132 value += data[j][i];
133 }
134 downmix[i] = value * kOneByNumChannels;
135 }
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000136 }
Per Åhgrend47941e2019-08-22 11:51:13 +0200137 const float* downmixed_data =
138 downmix_by_averaging_ ? downmix.data() : data[channel_for_downmixing_];
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000139
Per Åhgrend47941e2019-08-22 11:51:13 +0200140 if (resampling_needed) {
141 input_resamplers_[0]->Resample(downmixed_data, input_num_frames_,
142 data_->channels()[0], buffer_num_frames_);
143 }
144 const float* data_to_convert =
145 resampling_needed ? data_->channels()[0] : downmixed_data;
146 FloatToFloatS16(data_to_convert, buffer_num_frames_, data_->channels()[0]);
147 } else {
148 if (resampling_needed) {
149 for (size_t i = 0; i < num_channels_; ++i) {
150 input_resamplers_[i]->Resample(data[i], input_num_frames_,
151 data_->channels()[i],
152 buffer_num_frames_);
153 FloatToFloatS16(data_->channels()[i], buffer_num_frames_,
154 data_->channels()[i]);
155 }
156 } else {
157 for (size_t i = 0; i < num_channels_; ++i) {
158 FloatToFloatS16(data[i], buffer_num_frames_, data_->channels()[i]);
159 }
160 }
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000161 }
162}
163
Michael Graczyk86c6d332015-07-23 11:41:39 -0700164void AudioBuffer::CopyTo(const StreamConfig& stream_config,
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000165 float* const* data) {
kwiberg9e2be5f2016-09-14 05:23:22 -0700166 RTC_DCHECK_EQ(stream_config.num_frames(), output_num_frames_);
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000167
Per Åhgrend47941e2019-08-22 11:51:13 +0200168 const bool resampling_needed = output_num_frames_ != buffer_num_frames_;
169 if (resampling_needed) {
Peter Kasting69558702016-01-12 16:26:35 -0800170 for (size_t i = 0; i < num_channels_; ++i) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200171 FloatS16ToFloat(data_->channels()[i], buffer_num_frames_,
172 data_->channels()[i]);
173 output_resamplers_[i]->Resample(data_->channels()[i], buffer_num_frames_,
174 data[i], output_num_frames_);
175 }
176 } else {
177 for (size_t i = 0; i < num_channels_; ++i) {
178 FloatS16ToFloat(data_->channels()[i], buffer_num_frames_, data[i]);
andrew@webrtc.orgddbb8a22014-04-22 21:00:04 +0000179 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000180 }
aluebsb2328d12016-01-11 20:32:29 -0800181
Peter Kasting69558702016-01-12 16:26:35 -0800182 for (size_t i = num_channels_; i < stream_config.num_channels(); ++i) {
aluebsb2328d12016-01-11 20:32:29 -0800183 memcpy(data[i], data[0], output_num_frames_ * sizeof(**data));
184 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000185}
186
Gustaf Ullberg422b9e02019-10-09 13:02:14 +0200187void AudioBuffer::CopyTo(AudioBuffer* buffer) const {
188 RTC_DCHECK_EQ(buffer->num_frames(), output_num_frames_);
189
190 const bool resampling_needed = output_num_frames_ != buffer_num_frames_;
191 if (resampling_needed) {
192 for (size_t i = 0; i < num_channels_; ++i) {
193 output_resamplers_[i]->Resample(data_->channels()[i], buffer_num_frames_,
194 buffer->channels()[i],
195 buffer->num_frames());
196 }
197 } else {
198 for (size_t i = 0; i < num_channels_; ++i) {
199 memcpy(buffer->channels()[i], data_->channels()[i],
200 buffer_num_frames_ * sizeof(**buffer->channels()));
201 }
202 }
203
204 for (size_t i = num_channels_; i < buffer->num_channels(); ++i) {
205 memcpy(buffer->channels()[i], buffer->channels()[0],
206 output_num_frames_ * sizeof(**buffer->channels()));
207 }
208}
209
Per Åhgrend47941e2019-08-22 11:51:13 +0200210void AudioBuffer::RestoreNumChannels() {
211 num_channels_ = buffer_num_channels_;
212 data_->set_num_channels(buffer_num_channels_);
Alejandro Luebsa181c9a2016-06-30 15:33:37 -0700213 if (split_data_.get()) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200214 split_data_->set_num_channels(buffer_num_channels_);
Alejandro Luebsa181c9a2016-06-30 15:33:37 -0700215 }
andrew@webrtc.org17e40642014-03-04 20:58:13 +0000216}
217
Peter Kasting69558702016-01-12 16:26:35 -0800218void AudioBuffer::set_num_channels(size_t num_channels) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200219 RTC_DCHECK_GE(buffer_num_channels_, num_channels);
aluebs@webrtc.org27d106b2014-12-11 17:09:21 +0000220 num_channels_ = num_channels;
Alejandro Luebsa181c9a2016-06-30 15:33:37 -0700221 data_->set_num_channels(num_channels);
222 if (split_data_.get()) {
223 split_data_->set_num_channels(num_channels);
224 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000225}
226
Alejandro Luebs05c76052015-05-20 14:39:39 -0700227// The resampler is only for supporting 48kHz to 16kHz in the reverse stream.
Per Åhgrend47941e2019-08-22 11:51:13 +0200228void AudioBuffer::CopyFrom(const AudioFrame* frame) {
229 RTC_DCHECK_EQ(frame->num_channels_, input_num_channels_);
kwiberg9e2be5f2016-09-14 05:23:22 -0700230 RTC_DCHECK_EQ(frame->samples_per_channel_, input_num_frames_);
Per Åhgrend47941e2019-08-22 11:51:13 +0200231 RestoreNumChannels();
niklase@google.com470e71d2011-07-07 08:21:25 +0000232
Per Åhgrend47941e2019-08-22 11:51:13 +0200233 const bool resampling_required = input_num_frames_ != buffer_num_frames_;
Per Åhgren81c0cf22019-08-21 15:02:37 +0200234
Per Åhgrend47941e2019-08-22 11:51:13 +0200235 const int16_t* interleaved = frame->data();
236 if (num_channels_ == 1) {
237 if (input_num_channels_ == 1) {
238 if (resampling_required) {
239 std::array<float, kMaxSamplesPerChannel> float_buffer;
240 S16ToFloatS16(interleaved, input_num_frames_, float_buffer.data());
241 input_resamplers_[0]->Resample(float_buffer.data(), input_num_frames_,
242 data_->channels()[0],
243 buffer_num_frames_);
244 } else {
245 S16ToFloatS16(interleaved, input_num_frames_, data_->channels()[0]);
246 }
247 } else {
248 std::array<float, kMaxSamplesPerChannel> float_buffer;
249 float* downmixed_data =
250 resampling_required ? float_buffer.data() : data_->channels()[0];
251 if (downmix_by_averaging_) {
252 for (size_t j = 0, k = 0; j < input_num_frames_; ++j) {
253 int32_t sum = 0;
254 for (size_t i = 0; i < input_num_channels_; ++i, ++k) {
255 sum += interleaved[k];
256 }
257 downmixed_data[j] = sum / static_cast<int16_t>(input_num_channels_);
258 }
259 } else {
260 for (size_t j = 0, k = channel_for_downmixing_; j < input_num_frames_;
261 ++j, k += input_num_channels_) {
262 downmixed_data[j] = interleaved[k];
263 }
264 }
265
266 if (resampling_required) {
267 input_resamplers_[0]->Resample(downmixed_data, input_num_frames_,
268 data_->channels()[0],
269 buffer_num_frames_);
270 }
271 }
272 } else {
273 auto deinterleave_channel = [](size_t channel, size_t num_channels,
274 size_t samples_per_channel, const int16_t* x,
275 float* y) {
276 for (size_t j = 0, k = channel; j < samples_per_channel;
277 ++j, k += num_channels) {
278 y[j] = x[k];
279 }
280 };
281
282 if (resampling_required) {
283 std::array<float, kMaxSamplesPerChannel> float_buffer;
284 for (size_t i = 0; i < num_channels_; ++i) {
285 deinterleave_channel(i, num_channels_, input_num_frames_, interleaved,
286 float_buffer.data());
287 input_resamplers_[i]->Resample(float_buffer.data(), input_num_frames_,
288 data_->channels()[i],
289 buffer_num_frames_);
290 }
291 } else {
292 for (size_t i = 0; i < num_channels_; ++i) {
293 deinterleave_channel(i, num_channels_, input_num_frames_, interleaved,
294 data_->channels()[i]);
295 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000296 }
297 }
298}
299
Per Åhgrend47941e2019-08-22 11:51:13 +0200300void AudioBuffer::CopyTo(AudioFrame* frame) const {
kwiberg9e2be5f2016-09-14 05:23:22 -0700301 RTC_DCHECK(frame->num_channels_ == num_channels_ || num_channels_ == 1);
302 RTC_DCHECK_EQ(frame->samples_per_channel_, output_num_frames_);
ekmeyerson60d9b332015-08-14 10:35:55 -0700303
Per Åhgrend47941e2019-08-22 11:51:13 +0200304 const bool resampling_required = buffer_num_frames_ != output_num_frames_;
Per Åhgren81c0cf22019-08-21 15:02:37 +0200305
Per Åhgrend47941e2019-08-22 11:51:13 +0200306 int16_t* interleaved = frame->mutable_data();
307 if (num_channels_ == 1) {
308 std::array<float, kMaxSamplesPerChannel> float_buffer;
309
310 if (resampling_required) {
311 output_resamplers_[0]->Resample(data_->channels()[0], buffer_num_frames_,
312 float_buffer.data(), output_num_frames_);
313 }
314 const float* deinterleaved =
315 resampling_required ? float_buffer.data() : data_->channels()[0];
316
317 if (frame->num_channels_ == 1) {
318 for (size_t j = 0; j < output_num_frames_; ++j) {
319 interleaved[j] = FloatS16ToS16(deinterleaved[j]);
320 }
321 } else {
322 for (size_t i = 0, k = 0; i < output_num_frames_; ++i) {
323 float tmp = FloatS16ToS16(deinterleaved[i]);
324 for (size_t j = 0; j < frame->num_channels_; ++j, ++k) {
325 interleaved[k] = tmp;
326 }
327 }
328 }
ekmeyerson60d9b332015-08-14 10:35:55 -0700329 } else {
Per Åhgrend47941e2019-08-22 11:51:13 +0200330 auto interleave_channel = [](size_t channel, size_t num_channels,
331 size_t samples_per_channel, const float* x,
332 int16_t* y) {
333 for (size_t k = 0, j = channel; k < samples_per_channel;
334 ++k, j += num_channels) {
335 y[j] = FloatS16ToS16(x[k]);
336 }
337 };
338
339 if (resampling_required) {
340 for (size_t i = 0; i < num_channels_; ++i) {
341 std::array<float, kMaxSamplesPerChannel> float_buffer;
342 output_resamplers_[i]->Resample(data_->channels()[i],
343 buffer_num_frames_, float_buffer.data(),
344 output_num_frames_);
345 interleave_channel(i, frame->num_channels_, output_num_frames_,
346 float_buffer.data(), interleaved);
347 }
348 } else {
349 for (size_t i = 0; i < num_channels_; ++i) {
350 interleave_channel(i, frame->num_channels_, output_num_frames_,
351 data_->channels()[i], interleaved);
352 }
353 }
354
355 for (size_t i = num_channels_; i < frame->num_channels_; ++i) {
356 for (size_t j = 0, k = i, n = num_channels_; j < output_num_frames_;
357 ++j, k += frame->num_channels_, n += frame->num_channels_) {
358 interleaved[k] = interleaved[n];
359 }
360 }
ekmeyerson60d9b332015-08-14 10:35:55 -0700361 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000362}
363
aluebs@webrtc.orgbe05c742014-11-14 22:18:10 +0000364void AudioBuffer::SplitIntoFrequencyBands() {
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +0000365 splitting_filter_->Analysis(data_.get(), split_data_.get());
aluebs@webrtc.orgbe05c742014-11-14 22:18:10 +0000366}
367
368void AudioBuffer::MergeFrequencyBands() {
aluebs@webrtc.orgd35a5c32015-02-10 22:52:15 +0000369 splitting_filter_->Synthesis(split_data_.get(), data_.get());
aluebs@webrtc.orgbe05c742014-11-14 22:18:10 +0000370}
371
Per Åhgrend47941e2019-08-22 11:51:13 +0200372void AudioBuffer::ExportSplitChannelData(size_t channel,
Per Åhgren928146f2019-08-20 09:19:21 +0200373 int16_t* const* split_band_data) {
374 for (size_t k = 0; k < num_bands(); ++k) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200375 const float* band_data = split_bands(channel)[k];
376
Per Åhgren928146f2019-08-20 09:19:21 +0200377 RTC_DCHECK(split_band_data[k]);
378 RTC_DCHECK(band_data);
379 for (size_t i = 0; i < num_frames_per_band(); ++i) {
380 split_band_data[k][i] = FloatS16ToS16(band_data[i]);
381 }
382 }
383}
384
Per Åhgrend47941e2019-08-22 11:51:13 +0200385void AudioBuffer::ImportSplitChannelData(
Per Åhgren928146f2019-08-20 09:19:21 +0200386 size_t channel,
387 const int16_t* const* split_band_data) {
388 for (size_t k = 0; k < num_bands(); ++k) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200389 float* band_data = split_bands(channel)[k];
Per Åhgren928146f2019-08-20 09:19:21 +0200390 RTC_DCHECK(split_band_data[k]);
391 RTC_DCHECK(band_data);
392 for (size_t i = 0; i < num_frames_per_band(); ++i) {
393 band_data[i] = split_band_data[k][i];
394 }
395 }
396}
397
niklase@google.com470e71d2011-07-07 08:21:25 +0000398} // namespace webrtc