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/include/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 size_t num_in_channels, size_t frames, 39 size_t num_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(size_t num_in_channels, 50 size_t num_out_channels, 51 size_t chunk_length, 52 const float* window, 53 size_t block_length, 54 size_t shift_amount, 55 Callback* callback); ~LappedTransform()56 ~LappedTransform() {} 57 58 // Main audio processing helper method. Internally slices |in_chunk| into 59 // blocks, transforms them to frequency domain, calls the callback for each 60 // block and returns a de-blocked time domain chunk of audio through 61 // |out_chunk|. Both buffers are caller-owned. 62 void ProcessChunk(const float* const* in_chunk, float* const* out_chunk); 63 64 // Get the chunk length. 65 // 66 // The chunk length is the number of samples per channel that must be passed 67 // to ProcessChunk via the parameter in_chunk. 68 // 69 // Returns the same chunk_length passed to the LappedTransform constructor. chunk_length()70 size_t chunk_length() const { return chunk_length_; } 71 72 // Get the number of input channels. 73 // 74 // This is the number of arrays that must be passed to ProcessChunk via 75 // in_chunk. 76 // 77 // Returns the same num_in_channels passed to the LappedTransform constructor. num_in_channels()78 size_t num_in_channels() const { return num_in_channels_; } 79 80 // Get the number of output channels. 81 // 82 // This is the number of arrays that must be passed to ProcessChunk via 83 // out_chunk. 84 // 85 // Returns the same num_out_channels passed to the LappedTransform 86 // constructor. num_out_channels()87 size_t num_out_channels() const { return num_out_channels_; } 88 89 private: 90 // Internal middleware callback, given to the blocker. Transforms each block 91 // and hands it over to the processing method given at construction time. 92 class BlockThunk : public BlockerCallback { 93 public: BlockThunk(LappedTransform * parent)94 explicit BlockThunk(LappedTransform* parent) : parent_(parent) {} 95 96 virtual void ProcessBlock(const float* const* input, 97 size_t num_frames, 98 size_t num_input_channels, 99 size_t num_output_channels, 100 float* const* output); 101 102 private: 103 LappedTransform* const parent_; 104 } blocker_callback_; 105 106 const size_t num_in_channels_; 107 const size_t num_out_channels_; 108 109 const size_t block_length_; 110 const size_t chunk_length_; 111 112 Callback* const block_processor_; 113 Blocker blocker_; 114 115 rtc::scoped_ptr<RealFourier> fft_; 116 const size_t cplx_length_; 117 AlignedArray<float> real_buf_; 118 AlignedArray<std::complex<float> > cplx_pre_; 119 AlignedArray<std::complex<float> > cplx_post_; 120 }; 121 122 } // namespace webrtc 123 124 #endif // WEBRTC_COMMON_AUDIO_LAPPED_TRANSFORM_H_ 125 126