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 #ifndef WEBRTC_COMMON_AUDIO_LAPPED_TRANSFORM_H_ 12 #define WEBRTC_COMMON_AUDIO_LAPPED_TRANSFORM_H_ 13 14 #include <complex> 15 16 #include "webrtc/base/scoped_ptr.h" 17 #include "webrtc/common_audio/blocker.h" 18 #include "webrtc/common_audio/real_fourier.h" 19 #include "webrtc/system_wrappers/interface/aligned_array.h" 20 21 namespace webrtc { 22 23 // Helper class for audio processing modules which operate on frequency domain 24 // input derived from the windowed time domain audio stream. 25 // 26 // The input audio chunk is sliced into possibly overlapping blocks, multiplied 27 // by a window and transformed with an FFT implementation. The transformed data 28 // is supplied to the given callback for processing. The processed output is 29 // then inverse transformed into the time domain and spliced back into a chunk 30 // which constitutes the final output of this processing module. 31 class LappedTransform { 32 public: 33 class Callback { 34 public: ~Callback()35 virtual ~Callback() {} 36 37 virtual void ProcessAudioBlock(const std::complex<float>* const* in_block, 38 int in_channels, int frames, 39 int out_channels, 40 std::complex<float>* const* out_block) = 0; 41 }; 42 43 // Construct a transform instance. |chunk_length| is the number of samples in 44 // each channel. |window| defines the window, owned by the caller (a copy is 45 // made internally); |window| should have length equal to |block_length|. 46 // |block_length| defines the length of a block, in samples. 47 // |shift_amount| is in samples. |callback| is the caller-owned audio 48 // processing function called for each block of the input chunk. 49 LappedTransform(int in_channels, int out_channels, int chunk_length, 50 const float* window, int block_length, int shift_amount, 51 Callback* callback); ~LappedTransform()52 ~LappedTransform() {} 53 54 // Main audio processing helper method. Internally slices |in_chunk| into 55 // blocks, transforms them to frequency domain, calls the callback for each 56 // block and returns a de-blocked time domain chunk of audio through 57 // |out_chunk|. Both buffers are caller-owned. 58 void ProcessChunk(const float* const* in_chunk, float* const* out_chunk); 59 60 private: 61 // Internal middleware callback, given to the blocker. Transforms each block 62 // and hands it over to the processing method given at construction time. 63 class BlockThunk : public BlockerCallback { 64 public: BlockThunk(LappedTransform * parent)65 explicit BlockThunk(LappedTransform* parent) : parent_(parent) {} 66 67 virtual void ProcessBlock(const float* const* input, int num_frames, 68 int num_input_channels, int num_output_channels, 69 float* const* output); 70 71 private: 72 LappedTransform* const parent_; 73 } blocker_callback_; 74 75 const int in_channels_; 76 const int out_channels_; 77 78 const int block_length_; 79 const int chunk_length_; 80 81 Callback* const block_processor_; 82 Blocker blocker_; 83 84 rtc::scoped_ptr<RealFourier> fft_; 85 const int cplx_length_; 86 AlignedArray<float> real_buf_; 87 AlignedArray<std::complex<float> > cplx_pre_; 88 AlignedArray<std::complex<float> > cplx_post_; 89 }; 90 91 } // namespace webrtc 92 93 #endif // WEBRTC_COMMON_AUDIO_LAPPED_TRANSFORM_H_ 94 95