tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_frame_manipulator.cc (3732B)


      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_mixer/audio_frame_manipulator.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 
     16 #include "api/audio/audio_frame.h"
     17 #include "api/audio/channel_layout.h"
     18 #include "audio/utility/audio_frame_operations.h"
     19 #include "audio/utility/channel_mixer.h"
     20 #include "rtc_base/checks.h"
     21 
     22 namespace webrtc {
     23 
     24 uint32_t AudioMixerCalculateEnergy(const AudioFrame& audio_frame) {
     25  if (audio_frame.muted()) {
     26    return 0;
     27  }
     28 
     29  uint32_t energy = 0;
     30  const int16_t* frame_data = audio_frame.data();
     31  for (size_t position = 0;
     32       position < audio_frame.samples_per_channel_ * audio_frame.num_channels_;
     33       position++) {
     34    // TODO(aleloi): This can overflow. Convert to floats.
     35    energy += frame_data[position] * frame_data[position];
     36  }
     37  return energy;
     38 }
     39 
     40 void Ramp(float start_gain, float target_gain, AudioFrame* audio_frame) {
     41  RTC_DCHECK(audio_frame);
     42  RTC_DCHECK_GE(start_gain, 0.0f);
     43  RTC_DCHECK_GE(target_gain, 0.0f);
     44  if (start_gain == target_gain || audio_frame->muted()) {
     45    return;
     46  }
     47 
     48  size_t samples = audio_frame->samples_per_channel_;
     49  RTC_DCHECK_LT(0, samples);
     50  float increment = (target_gain - start_gain) / samples;
     51  float gain = start_gain;
     52  int16_t* frame_data = audio_frame->mutable_data();
     53  for (size_t i = 0; i < samples; ++i) {
     54    // If the audio is interleaved of several channels, we want to
     55    // apply the same gain change to the ith sample of every channel.
     56    for (size_t ch = 0; ch < audio_frame->num_channels_; ++ch) {
     57      frame_data[audio_frame->num_channels_ * i + ch] *= gain;
     58    }
     59    gain += increment;
     60  }
     61 }
     62 
     63 void RemixFrame(size_t target_number_of_channels, AudioFrame* frame) {
     64  RTC_DCHECK_GE(target_number_of_channels, 1);
     65  // TODO(bugs.webrtc.org/10783): take channel layout into account as well.
     66  if (frame->num_channels() == target_number_of_channels) {
     67    return;
     68  }
     69 
     70  // Use legacy components for the most simple cases (mono <-> stereo) to ensure
     71  // that native WebRTC clients are not affected when support for multi-channel
     72  // audio is added to Chrome.
     73  // TODO(bugs.webrtc.org/10783): utilize channel mixer for mono/stereo as well.
     74  if (target_number_of_channels < 3 && frame->num_channels() < 3) {
     75    if (frame->num_channels() > target_number_of_channels) {
     76      AudioFrameOperations::DownmixChannels(target_number_of_channels, frame);
     77    } else {
     78      AudioFrameOperations::UpmixChannels(target_number_of_channels, frame);
     79    }
     80  } else {
     81    // Use generic channel mixer when the number of channels for input our
     82    // output is larger than two. E.g. stereo -> 5.1 channel up-mixing.
     83    // TODO(bugs.webrtc.org/10783): ensure that actual channel layouts are used
     84    // instead of guessing based on number of channels.
     85    const ChannelLayout output_layout(
     86        GuessChannelLayout(target_number_of_channels));
     87    const ChannelLayout input_layout(GuessChannelLayout(frame->num_channels()));
     88    ChannelMixer mixer(input_layout, frame->num_channels(), output_layout,
     89                       target_number_of_channels);
     90    mixer.Transform(frame);
     91    RTC_DCHECK_EQ(frame->channel_layout(), output_layout);
     92  }
     93  RTC_DCHECK_EQ(frame->num_channels(), target_number_of_channels)
     94      << "Wrong number of channels, " << frame->num_channels() << " vs "
     95      << target_number_of_channels;
     96 }
     97 
     98 }  // namespace webrtc