acm_resampler.cc (2938B)
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_coding/acm2/acm_resampler.h" 12 13 #include <array> 14 #include <cstdint> 15 16 #include "api/audio/audio_frame.h" 17 #include "api/audio/audio_view.h" 18 #include "rtc_base/checks.h" 19 20 namespace webrtc { 21 namespace acm2 { 22 23 ResamplerHelper::ResamplerHelper() { 24 ClearSamples(last_audio_buffer_); 25 } 26 27 bool ResamplerHelper::MaybeResample(int desired_sample_rate_hz, 28 AudioFrame* audio_frame) { 29 const int current_sample_rate_hz = audio_frame->sample_rate_hz_; 30 RTC_DCHECK_NE(current_sample_rate_hz, 0); 31 RTC_DCHECK_GT(desired_sample_rate_hz, 0); 32 33 // Update if resampling is required. 34 // TODO(tommi): `desired_sample_rate_hz` should never be -1. 35 // Remove the first check. 36 const bool need_resampling = 37 (desired_sample_rate_hz != -1) && 38 (current_sample_rate_hz != desired_sample_rate_hz); 39 40 if (need_resampling && !resampled_last_output_frame_) { 41 // Prime the resampler with the last frame. 42 InterleavedView<const int16_t> src(last_audio_buffer_.data(), 43 audio_frame->samples_per_channel(), 44 audio_frame->num_channels()); 45 std::array<int16_t, AudioFrame::kMaxDataSizeSamples> temp_output; 46 InterleavedView<int16_t> dst( 47 temp_output.data(), 48 SampleRateToDefaultChannelSize(desired_sample_rate_hz), 49 audio_frame->num_channels_); 50 resampler_.Resample(src, dst); 51 } 52 53 // TODO(bugs.webrtc.org/3923) Glitches in the output may appear if the output 54 // rate from NetEq changes. 55 if (need_resampling) { 56 // Grab the source view of the current layout before changing properties. 57 InterleavedView<const int16_t> src = audio_frame->data_view(); 58 audio_frame->SetSampleRateAndChannelSize(desired_sample_rate_hz); 59 InterleavedView<int16_t> dst = audio_frame->mutable_data( 60 audio_frame->samples_per_channel(), audio_frame->num_channels()); 61 // TODO(tommi): Don't resample muted audio frames. 62 resampler_.Resample(src, dst); 63 resampled_last_output_frame_ = true; 64 } else { 65 resampled_last_output_frame_ = false; 66 // We might end up here ONLY if codec is changed. 67 } 68 69 // Store current audio in `last_audio_buffer_` for next time. 70 InterleavedView<int16_t> dst(last_audio_buffer_.data(), 71 audio_frame->samples_per_channel(), 72 audio_frame->num_channels()); 73 CopySamples(dst, audio_frame->data_view()); 74 75 return true; 76 } 77 78 } // namespace acm2 79 } // namespace webrtc