1 /* 2 * Copyright (c) 2014 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/common_audio/lapped_transform.h" 12 13 #include <algorithm> 14 #include <cstdlib> 15 #include <cstring> 16 17 #include "webrtc/base/checks.h" 18 #include "webrtc/common_audio/real_fourier.h" 19 20 namespace webrtc { 21 22 void LappedTransform::BlockThunk::ProcessBlock(const float* const* input, 23 size_t num_frames, 24 size_t num_input_channels, 25 size_t num_output_channels, 26 float* const* output) { 27 RTC_CHECK_EQ(num_input_channels, parent_->num_in_channels_); 28 RTC_CHECK_EQ(num_output_channels, parent_->num_out_channels_); 29 RTC_CHECK_EQ(parent_->block_length_, num_frames); 30 31 for (size_t i = 0; i < num_input_channels; ++i) { 32 memcpy(parent_->real_buf_.Row(i), input[i], 33 num_frames * sizeof(*input[0])); 34 parent_->fft_->Forward(parent_->real_buf_.Row(i), 35 parent_->cplx_pre_.Row(i)); 36 } 37 38 size_t block_length = RealFourier::ComplexLength( 39 RealFourier::FftOrder(num_frames)); 40 RTC_CHECK_EQ(parent_->cplx_length_, block_length); 41 parent_->block_processor_->ProcessAudioBlock(parent_->cplx_pre_.Array(), 42 num_input_channels, 43 parent_->cplx_length_, 44 num_output_channels, 45 parent_->cplx_post_.Array()); 46 47 for (size_t i = 0; i < num_output_channels; ++i) { 48 parent_->fft_->Inverse(parent_->cplx_post_.Row(i), 49 parent_->real_buf_.Row(i)); 50 memcpy(output[i], parent_->real_buf_.Row(i), 51 num_frames * sizeof(*input[0])); 52 } 53 } 54 55 LappedTransform::LappedTransform(size_t num_in_channels, 56 size_t num_out_channels, 57 size_t chunk_length, 58 const float* window, 59 size_t block_length, 60 size_t shift_amount, 61 Callback* callback) 62 : blocker_callback_(this), 63 num_in_channels_(num_in_channels), 64 num_out_channels_(num_out_channels), 65 block_length_(block_length), 66 chunk_length_(chunk_length), 67 block_processor_(callback), 68 blocker_(chunk_length_, 69 block_length_, 70 num_in_channels_, 71 num_out_channels_, 72 window, 73 shift_amount, 74 &blocker_callback_), 75 fft_(RealFourier::Create(RealFourier::FftOrder(block_length_))), 76 cplx_length_(RealFourier::ComplexLength(fft_->order())), 77 real_buf_(num_in_channels, 78 block_length_, 79 RealFourier::kFftBufferAlignment), 80 cplx_pre_(num_in_channels, 81 cplx_length_, 82 RealFourier::kFftBufferAlignment), 83 cplx_post_(num_out_channels, 84 cplx_length_, 85 RealFourier::kFftBufferAlignment) { 86 RTC_CHECK(num_in_channels_ > 0 && num_out_channels_ > 0); 87 RTC_CHECK_GT(block_length_, 0u); 88 RTC_CHECK_GT(chunk_length_, 0u); 89 RTC_CHECK(block_processor_); 90 91 // block_length_ power of 2? 92 RTC_CHECK_EQ(0u, block_length_ & (block_length_ - 1)); 93 } 94 95 void LappedTransform::ProcessChunk(const float* const* in_chunk, 96 float* const* out_chunk) { 97 blocker_.ProcessChunk(in_chunk, chunk_length_, num_in_channels_, 98 num_out_channels_, out_chunk); 99 } 100 101 } // namespace webrtc 102