• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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