Home | History | Annotate | Download | only in voice_engine
      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/voice_engine/utility.h"
     12 
     13 #include "webrtc/base/logging.h"
     14 #include "webrtc/common_audio/resampler/include/push_resampler.h"
     15 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     16 #include "webrtc/common_types.h"
     17 #include "webrtc/modules/include/module_common_types.h"
     18 #include "webrtc/modules/utility/include/audio_frame_operations.h"
     19 #include "webrtc/voice_engine/voice_engine_defines.h"
     20 
     21 namespace webrtc {
     22 namespace voe {
     23 
     24 void RemixAndResample(const AudioFrame& src_frame,
     25                       PushResampler<int16_t>* resampler,
     26                       AudioFrame* dst_frame) {
     27   RemixAndResample(src_frame.data_, src_frame.samples_per_channel_,
     28                    src_frame.num_channels_, src_frame.sample_rate_hz_,
     29                    resampler, dst_frame);
     30   dst_frame->timestamp_ = src_frame.timestamp_;
     31   dst_frame->elapsed_time_ms_ = src_frame.elapsed_time_ms_;
     32   dst_frame->ntp_time_ms_ = src_frame.ntp_time_ms_;
     33 }
     34 
     35 void RemixAndResample(const int16_t* src_data,
     36                       size_t samples_per_channel,
     37                       size_t num_channels,
     38                       int sample_rate_hz,
     39                       PushResampler<int16_t>* resampler,
     40                       AudioFrame* dst_frame) {
     41   const int16_t* audio_ptr = src_data;
     42   size_t audio_ptr_num_channels = num_channels;
     43   int16_t mono_audio[AudioFrame::kMaxDataSizeSamples];
     44 
     45   // Downmix before resampling.
     46   if (num_channels == 2 && dst_frame->num_channels_ == 1) {
     47     AudioFrameOperations::StereoToMono(src_data, samples_per_channel,
     48                                        mono_audio);
     49     audio_ptr = mono_audio;
     50     audio_ptr_num_channels = 1;
     51   }
     52 
     53   if (resampler->InitializeIfNeeded(sample_rate_hz, dst_frame->sample_rate_hz_,
     54                                     audio_ptr_num_channels) == -1) {
     55     LOG(LS_ERROR) << "InitializeIfNeeded failed: sample_rate_hz = "
     56                   << sample_rate_hz << ", dst_frame->sample_rate_hz_ = "
     57                   << dst_frame->sample_rate_hz_
     58                   << ", audio_ptr_num_channels = " << audio_ptr_num_channels;
     59     assert(false);
     60   }
     61 
     62   const size_t src_length = samples_per_channel * audio_ptr_num_channels;
     63   int out_length = resampler->Resample(audio_ptr, src_length, dst_frame->data_,
     64                                        AudioFrame::kMaxDataSizeSamples);
     65   if (out_length == -1) {
     66     LOG(LS_ERROR) << "Resample failed: audio_ptr = " << audio_ptr
     67                   << ", src_length = " << src_length
     68                   << ", dst_frame->data_ = " << dst_frame->data_;
     69     assert(false);
     70   }
     71   dst_frame->samples_per_channel_ = out_length / audio_ptr_num_channels;
     72 
     73   // Upmix after resampling.
     74   if (num_channels == 1 && dst_frame->num_channels_ == 2) {
     75     // The audio in dst_frame really is mono at this point; MonoToStereo will
     76     // set this back to stereo.
     77     dst_frame->num_channels_ = 1;
     78     AudioFrameOperations::MonoToStereo(dst_frame);
     79   }
     80 }
     81 
     82 void MixWithSat(int16_t target[],
     83                 size_t target_channel,
     84                 const int16_t source[],
     85                 size_t source_channel,
     86                 size_t source_len) {
     87   assert(target_channel == 1 || target_channel == 2);
     88   assert(source_channel == 1 || source_channel == 2);
     89 
     90   if (target_channel == 2 && source_channel == 1) {
     91     // Convert source from mono to stereo.
     92     int32_t left = 0;
     93     int32_t right = 0;
     94     for (size_t i = 0; i < source_len; ++i) {
     95       left = source[i] + target[i * 2];
     96       right = source[i] + target[i * 2 + 1];
     97       target[i * 2] = WebRtcSpl_SatW32ToW16(left);
     98       target[i * 2 + 1] = WebRtcSpl_SatW32ToW16(right);
     99     }
    100   } else if (target_channel == 1 && source_channel == 2) {
    101     // Convert source from stereo to mono.
    102     int32_t temp = 0;
    103     for (size_t i = 0; i < source_len / 2; ++i) {
    104       temp = ((source[i * 2] + source[i * 2 + 1]) >> 1) + target[i];
    105       target[i] = WebRtcSpl_SatW32ToW16(temp);
    106     }
    107   } else {
    108     int32_t temp = 0;
    109     for (size_t i = 0; i < source_len; ++i) {
    110       temp = source[i] + target[i];
    111       target[i] = WebRtcSpl_SatW32ToW16(temp);
    112     }
    113   }
    114 }
    115 
    116 }  // namespace voe
    117 }  // namespace webrtc
    118