LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/audio/utility - audio_frame_operations.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 119 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "webrtc/audio/utility/audio_frame_operations.h"
      12             : 
      13             : #include <algorithm>
      14             : 
      15             : #include "webrtc/base/checks.h"
      16             : #include "webrtc/base/safe_conversions.h"
      17             : #include "webrtc/modules/include/module_common_types.h"
      18             : 
      19             : namespace webrtc {
      20             : namespace {
      21             : 
      22             : // 2.7ms @ 48kHz, 4ms @ 32kHz, 8ms @ 16kHz.
      23             : const size_t kMuteFadeFrames = 128;
      24             : const float kMuteFadeInc = 1.0f / kMuteFadeFrames;
      25             : 
      26             : }  // namespace
      27             : 
      28           0 : void AudioFrameOperations::Add(const AudioFrame& frame_to_add,
      29             :                                AudioFrame* result_frame) {
      30             :   // Sanity check.
      31           0 :   RTC_DCHECK(result_frame);
      32           0 :   RTC_DCHECK_GT(result_frame->num_channels_, 0);
      33           0 :   RTC_DCHECK_EQ(result_frame->num_channels_, frame_to_add.num_channels_);
      34             : 
      35           0 :   bool no_previous_data = false;
      36           0 :   if (result_frame->samples_per_channel_ != frame_to_add.samples_per_channel_) {
      37             :     // Special case we have no data to start with.
      38           0 :     RTC_DCHECK_EQ(result_frame->samples_per_channel_, 0);
      39           0 :     result_frame->samples_per_channel_ = frame_to_add.samples_per_channel_;
      40           0 :     no_previous_data = true;
      41             :   }
      42             : 
      43           0 :   if (result_frame->vad_activity_ == AudioFrame::kVadActive ||
      44           0 :       frame_to_add.vad_activity_ == AudioFrame::kVadActive) {
      45           0 :     result_frame->vad_activity_ = AudioFrame::kVadActive;
      46           0 :   } else if (result_frame->vad_activity_ == AudioFrame::kVadUnknown ||
      47           0 :              frame_to_add.vad_activity_ == AudioFrame::kVadUnknown) {
      48           0 :     result_frame->vad_activity_ = AudioFrame::kVadUnknown;
      49             :   }
      50             : 
      51           0 :   if (result_frame->speech_type_ != frame_to_add.speech_type_)
      52           0 :     result_frame->speech_type_ = AudioFrame::kUndefined;
      53             : 
      54           0 :   if (no_previous_data) {
      55           0 :     std::copy(frame_to_add.data_, frame_to_add.data_ +
      56           0 :                                       frame_to_add.samples_per_channel_ *
      57           0 :                                           result_frame->num_channels_,
      58           0 :               result_frame->data_);
      59             :   } else {
      60           0 :     for (size_t i = 0;
      61           0 :          i < result_frame->samples_per_channel_ * result_frame->num_channels_;
      62             :          i++) {
      63           0 :       const int32_t wrap_guard = static_cast<int32_t>(result_frame->data_[i]) +
      64           0 :                            static_cast<int32_t>(frame_to_add.data_[i]);
      65           0 :       result_frame->data_[i] = rtc::saturated_cast<int16_t>(wrap_guard);
      66             :     }
      67             :   }
      68           0 :   return;
      69             : }
      70             : 
      71           0 : void AudioFrameOperations::MonoToStereo(const int16_t* src_audio,
      72             :                                         size_t samples_per_channel,
      73             :                                         int16_t* dst_audio) {
      74           0 :   for (size_t i = 0; i < samples_per_channel; i++) {
      75           0 :     dst_audio[2 * i] = src_audio[i];
      76           0 :     dst_audio[2 * i + 1] = src_audio[i];
      77             :   }
      78           0 : }
      79             : 
      80           0 : int AudioFrameOperations::MonoToStereo(AudioFrame* frame) {
      81           0 :   if (frame->num_channels_ != 1) {
      82           0 :     return -1;
      83             :   }
      84           0 :   if ((frame->samples_per_channel_ * 2) >= AudioFrame::kMaxDataSizeSamples) {
      85             :     // Not enough memory to expand from mono to stereo.
      86           0 :     return -1;
      87             :   }
      88             : 
      89             :   int16_t data_copy[AudioFrame::kMaxDataSizeSamples];
      90           0 :   memcpy(data_copy, frame->data_,
      91           0 :          sizeof(int16_t) * frame->samples_per_channel_);
      92           0 :   MonoToStereo(data_copy, frame->samples_per_channel_, frame->data_);
      93           0 :   frame->num_channels_ = 2;
      94             : 
      95           0 :   return 0;
      96             : }
      97             : 
      98           0 : void AudioFrameOperations::StereoToMono(const int16_t* src_audio,
      99             :                                         size_t samples_per_channel,
     100             :                                         int16_t* dst_audio) {
     101           0 :   for (size_t i = 0; i < samples_per_channel; i++) {
     102           0 :     dst_audio[i] = (src_audio[2 * i] + src_audio[2 * i + 1]) >> 1;
     103             :   }
     104           0 : }
     105             : 
     106           0 : int AudioFrameOperations::StereoToMono(AudioFrame* frame) {
     107           0 :   if (frame->num_channels_ != 2) {
     108           0 :     return -1;
     109             :   }
     110             : 
     111           0 :   StereoToMono(frame->data_, frame->samples_per_channel_, frame->data_);
     112           0 :   frame->num_channels_ = 1;
     113             : 
     114           0 :   return 0;
     115             : }
     116             : 
     117           0 : void AudioFrameOperations::SwapStereoChannels(AudioFrame* frame) {
     118           0 :   RTC_DCHECK(frame);
     119           0 :   if (frame->num_channels_ != 2) {
     120           0 :     return;
     121             :   }
     122             : 
     123           0 :   for (size_t i = 0; i < frame->samples_per_channel_ * 2; i += 2) {
     124           0 :     int16_t temp_data = frame->data_[i];
     125           0 :     frame->data_[i] = frame->data_[i + 1];
     126           0 :     frame->data_[i + 1] = temp_data;
     127             :   }
     128             : }
     129             : 
     130           0 : void AudioFrameOperations::Mute(AudioFrame* frame,
     131             :                                 bool previous_frame_muted,
     132             :                                 bool current_frame_muted) {
     133           0 :   RTC_DCHECK(frame);
     134           0 :   if (!previous_frame_muted && !current_frame_muted) {
     135             :     // Not muted, don't touch.
     136           0 :   } else if (previous_frame_muted && current_frame_muted) {
     137             :     // Frame fully muted.
     138           0 :     size_t total_samples = frame->samples_per_channel_ * frame->num_channels_;
     139           0 :     RTC_DCHECK_GE(AudioFrame::kMaxDataSizeSamples, total_samples);
     140           0 :     memset(frame->data_, 0, sizeof(frame->data_[0]) * total_samples);
     141             :   } else {
     142             :     // Limit number of samples to fade, if frame isn't long enough.
     143           0 :     size_t count = kMuteFadeFrames;
     144           0 :     float inc = kMuteFadeInc;
     145           0 :     if (frame->samples_per_channel_ < kMuteFadeFrames) {
     146           0 :       count = frame->samples_per_channel_;
     147           0 :       if (count > 0) {
     148           0 :         inc = 1.0f / count;
     149             :       }
     150             :     }
     151             : 
     152           0 :     size_t start = 0;
     153           0 :     size_t end = count;
     154           0 :     float start_g = 0.0f;
     155           0 :     if (current_frame_muted) {
     156             :       // Fade out the last |count| samples of frame.
     157           0 :       RTC_DCHECK(!previous_frame_muted);
     158           0 :       start = frame->samples_per_channel_ - count;
     159           0 :       end = frame->samples_per_channel_;
     160           0 :       start_g = 1.0f;
     161           0 :       inc = -inc;
     162             :     } else {
     163             :       // Fade in the first |count| samples of frame.
     164           0 :       RTC_DCHECK(previous_frame_muted);
     165             :     }
     166             : 
     167             :     // Perform fade.
     168           0 :     size_t channels = frame->num_channels_;
     169           0 :     for (size_t j = 0; j < channels; ++j) {
     170           0 :       float g = start_g;
     171           0 :       for (size_t i = start * channels; i < end * channels; i += channels) {
     172           0 :         g += inc;
     173           0 :         frame->data_[i + j] *= g;
     174             :       }
     175             :     }
     176             :   }
     177           0 : }
     178             : 
     179           0 : void AudioFrameOperations::Mute(AudioFrame* frame) {
     180           0 :   Mute(frame, true, true);
     181           0 : }
     182             : 
     183           0 : void AudioFrameOperations::ApplyHalfGain(AudioFrame* frame) {
     184           0 :   RTC_DCHECK(frame);
     185           0 :   RTC_DCHECK_GT(frame->num_channels_, 0);
     186           0 :   if (frame->num_channels_ < 1) {
     187           0 :     return;
     188             :   }
     189             : 
     190           0 :   for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_;
     191             :        i++) {
     192           0 :     frame->data_[i] = frame->data_[i] >> 1;
     193             :   }
     194             : }
     195             : 
     196           0 : int AudioFrameOperations::Scale(float left, float right, AudioFrame& frame) {
     197           0 :   if (frame.num_channels_ != 2) {
     198           0 :     return -1;
     199             :   }
     200             : 
     201           0 :   for (size_t i = 0; i < frame.samples_per_channel_; i++) {
     202           0 :     frame.data_[2 * i] = static_cast<int16_t>(left * frame.data_[2 * i]);
     203           0 :     frame.data_[2 * i + 1] =
     204           0 :         static_cast<int16_t>(right * frame.data_[2 * i + 1]);
     205             :   }
     206           0 :   return 0;
     207             : }
     208             : 
     209           0 : int AudioFrameOperations::ScaleWithSat(float scale, AudioFrame& frame) {
     210           0 :   int32_t temp_data = 0;
     211             : 
     212             :   // Ensure that the output result is saturated [-32768, +32767].
     213           0 :   for (size_t i = 0; i < frame.samples_per_channel_ * frame.num_channels_;
     214             :        i++) {
     215           0 :     temp_data = static_cast<int32_t>(scale * frame.data_[i]);
     216           0 :     if (temp_data < -32768) {
     217           0 :       frame.data_[i] = -32768;
     218           0 :     } else if (temp_data > 32767) {
     219           0 :       frame.data_[i] = 32767;
     220             :     } else {
     221           0 :       frame.data_[i] = static_cast<int16_t>(temp_data);
     222             :     }
     223             :   }
     224           0 :   return 0;
     225             : }
     226             : }  // namespace webrtc

Generated by: LCOV version 1.13