• 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     : AudioBuffer(static_cast<int>(input_rate) / 100,
49                   input_num_channels,
50                   static_cast<int>(buffer_rate) / 100,
51                   buffer_num_channels,
52                   static_cast<int>(output_rate) / 100) {}
53 
AudioBuffer(size_t input_num_frames,size_t input_num_channels,size_t buffer_num_frames,size_t buffer_num_channels,size_t output_num_frames)54 AudioBuffer::AudioBuffer(size_t input_num_frames,
55                          size_t input_num_channels,
56                          size_t buffer_num_frames,
57                          size_t buffer_num_channels,
58                          size_t output_num_frames)
59     : input_num_frames_(input_num_frames),
60       input_num_channels_(input_num_channels),
61       buffer_num_frames_(buffer_num_frames),
62       buffer_num_channels_(buffer_num_channels),
63       output_num_frames_(output_num_frames),
64       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_)),
68       data_(
69           new ChannelBuffer<float>(buffer_num_frames_, buffer_num_channels_)) {
70   RTC_DCHECK_GT(input_num_frames_, 0);
71   RTC_DCHECK_GT(buffer_num_frames_, 0);
72   RTC_DCHECK_GT(output_num_frames_, 0);
73   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_);
76 
77   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_)));
84     }
85   }
86 
87   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_)));
91     }
92   }
93 
94   if (num_bands_ > 1) {
95     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_));
99   }
100 }
101 
~AudioBuffer()102 AudioBuffer::~AudioBuffer() {}
103 
set_downmixing_to_specific_channel(size_t channel)104 void 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 
set_downmixing_by_averaging()110 void AudioBuffer::set_downmixing_by_averaging() {
111   downmix_by_averaging_ = true;
112 }
113 
CopyFrom(const float * const * stacked_data,const StreamConfig & stream_config)114 void AudioBuffer::CopyFrom(const float* const* stacked_data,
115                            const StreamConfig& stream_config) {
116   RTC_DCHECK_EQ(stream_config.num_frames(), input_num_frames_);
117   RTC_DCHECK_EQ(stream_config.num_channels(), input_num_channels_);
118   RestoreNumChannels();
119   const bool downmix_needed = input_num_channels_ > 1 && num_channels_ == 1;
120 
121   const bool resampling_needed = input_num_frames_ != buffer_num_frames_;
122 
123   if (downmix_needed) {
124     RTC_DCHECK_GE(kMaxSamplesPerChannel, input_num_frames_);
125 
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 = stacked_data[0][i];
131         for (size_t j = 1; j < input_num_channels_; ++j) {
132           value += stacked_data[j][i];
133         }
134         downmix[i] = value * kOneByNumChannels;
135       }
136     }
137     const float* downmixed_data = downmix_by_averaging_
138                                       ? downmix.data()
139                                       : stacked_data[channel_for_downmixing_];
140 
141     if (resampling_needed) {
142       input_resamplers_[0]->Resample(downmixed_data, input_num_frames_,
143                                      data_->channels()[0], buffer_num_frames_);
144     }
145     const float* data_to_convert =
146         resampling_needed ? data_->channels()[0] : downmixed_data;
147     FloatToFloatS16(data_to_convert, buffer_num_frames_, data_->channels()[0]);
148   } else {
149     if (resampling_needed) {
150       for (size_t i = 0; i < num_channels_; ++i) {
151         input_resamplers_[i]->Resample(stacked_data[i], input_num_frames_,
152                                        data_->channels()[i],
153                                        buffer_num_frames_);
154         FloatToFloatS16(data_->channels()[i], buffer_num_frames_,
155                         data_->channels()[i]);
156       }
157     } else {
158       for (size_t i = 0; i < num_channels_; ++i) {
159         FloatToFloatS16(stacked_data[i], buffer_num_frames_,
160                         data_->channels()[i]);
161       }
162     }
163   }
164 }
165 
CopyTo(const StreamConfig & stream_config,float * const * stacked_data)166 void AudioBuffer::CopyTo(const StreamConfig& stream_config,
167                          float* const* stacked_data) {
168   RTC_DCHECK_EQ(stream_config.num_frames(), output_num_frames_);
169 
170   const bool resampling_needed = output_num_frames_ != buffer_num_frames_;
171   if (resampling_needed) {
172     for (size_t i = 0; i < num_channels_; ++i) {
173       FloatS16ToFloat(data_->channels()[i], buffer_num_frames_,
174                       data_->channels()[i]);
175       output_resamplers_[i]->Resample(data_->channels()[i], buffer_num_frames_,
176                                       stacked_data[i], output_num_frames_);
177     }
178   } else {
179     for (size_t i = 0; i < num_channels_; ++i) {
180       FloatS16ToFloat(data_->channels()[i], buffer_num_frames_,
181                       stacked_data[i]);
182     }
183   }
184 
185   for (size_t i = num_channels_; i < stream_config.num_channels(); ++i) {
186     memcpy(stacked_data[i], stacked_data[0],
187            output_num_frames_ * sizeof(**stacked_data));
188   }
189 }
190 
CopyTo(AudioBuffer * buffer) const191 void AudioBuffer::CopyTo(AudioBuffer* buffer) const {
192   RTC_DCHECK_EQ(buffer->num_frames(), output_num_frames_);
193 
194   const bool resampling_needed = output_num_frames_ != buffer_num_frames_;
195   if (resampling_needed) {
196     for (size_t i = 0; i < num_channels_; ++i) {
197       output_resamplers_[i]->Resample(data_->channels()[i], buffer_num_frames_,
198                                       buffer->channels()[i],
199                                       buffer->num_frames());
200     }
201   } else {
202     for (size_t i = 0; i < num_channels_; ++i) {
203       memcpy(buffer->channels()[i], data_->channels()[i],
204              buffer_num_frames_ * sizeof(**buffer->channels()));
205     }
206   }
207 
208   for (size_t i = num_channels_; i < buffer->num_channels(); ++i) {
209     memcpy(buffer->channels()[i], buffer->channels()[0],
210            output_num_frames_ * sizeof(**buffer->channels()));
211   }
212 }
213 
RestoreNumChannels()214 void AudioBuffer::RestoreNumChannels() {
215   num_channels_ = buffer_num_channels_;
216   data_->set_num_channels(buffer_num_channels_);
217   if (split_data_.get()) {
218     split_data_->set_num_channels(buffer_num_channels_);
219   }
220 }
221 
set_num_channels(size_t num_channels)222 void AudioBuffer::set_num_channels(size_t num_channels) {
223   RTC_DCHECK_GE(buffer_num_channels_, num_channels);
224   num_channels_ = num_channels;
225   data_->set_num_channels(num_channels);
226   if (split_data_.get()) {
227     split_data_->set_num_channels(num_channels);
228   }
229 }
230 
231 // The resampler is only for supporting 48kHz to 16kHz in the reverse stream.
CopyFrom(const int16_t * const interleaved_data,const StreamConfig & stream_config)232 void AudioBuffer::CopyFrom(const int16_t* const interleaved_data,
233                            const StreamConfig& stream_config) {
234   RTC_DCHECK_EQ(stream_config.num_channels(), input_num_channels_);
235   RTC_DCHECK_EQ(stream_config.num_frames(), input_num_frames_);
236   RestoreNumChannels();
237 
238   const bool resampling_required = input_num_frames_ != buffer_num_frames_;
239 
240   const int16_t* interleaved = interleaved_data;
241   if (num_channels_ == 1) {
242     if (input_num_channels_ == 1) {
243       if (resampling_required) {
244         std::array<float, kMaxSamplesPerChannel> float_buffer;
245         S16ToFloatS16(interleaved, input_num_frames_, float_buffer.data());
246         input_resamplers_[0]->Resample(float_buffer.data(), input_num_frames_,
247                                        data_->channels()[0],
248                                        buffer_num_frames_);
249       } else {
250         S16ToFloatS16(interleaved, input_num_frames_, data_->channels()[0]);
251       }
252     } else {
253       std::array<float, kMaxSamplesPerChannel> float_buffer;
254       float* downmixed_data =
255           resampling_required ? float_buffer.data() : data_->channels()[0];
256       if (downmix_by_averaging_) {
257         for (size_t j = 0, k = 0; j < input_num_frames_; ++j) {
258           int32_t sum = 0;
259           for (size_t i = 0; i < input_num_channels_; ++i, ++k) {
260             sum += interleaved[k];
261           }
262           downmixed_data[j] = sum / static_cast<int16_t>(input_num_channels_);
263         }
264       } else {
265         for (size_t j = 0, k = channel_for_downmixing_; j < input_num_frames_;
266              ++j, k += input_num_channels_) {
267           downmixed_data[j] = interleaved[k];
268         }
269       }
270 
271       if (resampling_required) {
272         input_resamplers_[0]->Resample(downmixed_data, input_num_frames_,
273                                        data_->channels()[0],
274                                        buffer_num_frames_);
275       }
276     }
277   } else {
278     auto deinterleave_channel = [](size_t channel, size_t num_channels,
279                                    size_t samples_per_channel, const int16_t* x,
280                                    float* y) {
281       for (size_t j = 0, k = channel; j < samples_per_channel;
282            ++j, k += num_channels) {
283         y[j] = x[k];
284       }
285     };
286 
287     if (resampling_required) {
288       std::array<float, kMaxSamplesPerChannel> float_buffer;
289       for (size_t i = 0; i < num_channels_; ++i) {
290         deinterleave_channel(i, num_channels_, input_num_frames_, interleaved,
291                              float_buffer.data());
292         input_resamplers_[i]->Resample(float_buffer.data(), input_num_frames_,
293                                        data_->channels()[i],
294                                        buffer_num_frames_);
295       }
296     } else {
297       for (size_t i = 0; i < num_channels_; ++i) {
298         deinterleave_channel(i, num_channels_, input_num_frames_, interleaved,
299                              data_->channels()[i]);
300       }
301     }
302   }
303 }
304 
CopyTo(const StreamConfig & stream_config,int16_t * const interleaved_data)305 void AudioBuffer::CopyTo(const StreamConfig& stream_config,
306                          int16_t* const interleaved_data) {
307   const size_t config_num_channels = stream_config.num_channels();
308 
309   RTC_DCHECK(config_num_channels == num_channels_ || num_channels_ == 1);
310   RTC_DCHECK_EQ(stream_config.num_frames(), output_num_frames_);
311 
312   const bool resampling_required = buffer_num_frames_ != output_num_frames_;
313 
314   int16_t* interleaved = interleaved_data;
315   if (num_channels_ == 1) {
316     std::array<float, kMaxSamplesPerChannel> float_buffer;
317 
318     if (resampling_required) {
319       output_resamplers_[0]->Resample(data_->channels()[0], buffer_num_frames_,
320                                       float_buffer.data(), output_num_frames_);
321     }
322     const float* deinterleaved =
323         resampling_required ? float_buffer.data() : data_->channels()[0];
324 
325     if (config_num_channels == 1) {
326       for (size_t j = 0; j < output_num_frames_; ++j) {
327         interleaved[j] = FloatS16ToS16(deinterleaved[j]);
328       }
329     } else {
330       for (size_t i = 0, k = 0; i < output_num_frames_; ++i) {
331         float tmp = FloatS16ToS16(deinterleaved[i]);
332         for (size_t j = 0; j < config_num_channels; ++j, ++k) {
333           interleaved[k] = tmp;
334         }
335       }
336     }
337   } else {
338     auto interleave_channel = [](size_t channel, size_t num_channels,
339                                  size_t samples_per_channel, const float* x,
340                                  int16_t* y) {
341       for (size_t k = 0, j = channel; k < samples_per_channel;
342            ++k, j += num_channels) {
343         y[j] = FloatS16ToS16(x[k]);
344       }
345     };
346 
347     if (resampling_required) {
348       for (size_t i = 0; i < num_channels_; ++i) {
349         std::array<float, kMaxSamplesPerChannel> float_buffer;
350         output_resamplers_[i]->Resample(data_->channels()[i],
351                                         buffer_num_frames_, float_buffer.data(),
352                                         output_num_frames_);
353         interleave_channel(i, config_num_channels, output_num_frames_,
354                            float_buffer.data(), interleaved);
355       }
356     } else {
357       for (size_t i = 0; i < num_channels_; ++i) {
358         interleave_channel(i, config_num_channels, output_num_frames_,
359                            data_->channels()[i], interleaved);
360       }
361     }
362 
363     for (size_t i = num_channels_; i < config_num_channels; ++i) {
364       for (size_t j = 0, k = i, n = num_channels_; j < output_num_frames_;
365            ++j, k += config_num_channels, n += config_num_channels) {
366         interleaved[k] = interleaved[n];
367       }
368     }
369   }
370 }
371 
SplitIntoFrequencyBands()372 void AudioBuffer::SplitIntoFrequencyBands() {
373   splitting_filter_->Analysis(data_.get(), split_data_.get());
374 }
375 
MergeFrequencyBands()376 void AudioBuffer::MergeFrequencyBands() {
377   splitting_filter_->Synthesis(split_data_.get(), data_.get());
378 }
379 
ExportSplitChannelData(size_t channel,int16_t * const * split_band_data) const380 void AudioBuffer::ExportSplitChannelData(
381     size_t channel,
382     int16_t* const* split_band_data) const {
383   for (size_t k = 0; k < num_bands(); ++k) {
384     const float* band_data = split_bands_const(channel)[k];
385 
386     RTC_DCHECK(split_band_data[k]);
387     RTC_DCHECK(band_data);
388     for (size_t i = 0; i < num_frames_per_band(); ++i) {
389       split_band_data[k][i] = FloatS16ToS16(band_data[i]);
390     }
391   }
392 }
393 
ImportSplitChannelData(size_t channel,const int16_t * const * split_band_data)394 void AudioBuffer::ImportSplitChannelData(
395     size_t channel,
396     const int16_t* const* split_band_data) {
397   for (size_t k = 0; k < num_bands(); ++k) {
398     float* band_data = split_bands(channel)[k];
399     RTC_DCHECK(split_band_data[k]);
400     RTC_DCHECK(band_data);
401     for (size_t i = 0; i < num_frames_per_band(); ++i) {
402       band_data[i] = split_band_data[k][i];
403     }
404   }
405 }
406 
407 }  // namespace webrtc
408