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