Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / common_audio / blocker.h
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_INTERNAL_BEAMFORMER_BLOCKER_H_
12 #define WEBRTC_INTERNAL_BEAMFORMER_BLOCKER_H_
13
14 #include "webrtc/modules/audio_processing/common.h"
15 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
16
17 namespace webrtc {
18
19 // The callback function to process audio in the time domain. Input has already
20 // been windowed, and output will be windowed. The number of input channels
21 // must be >= the number of output channels.
22 class BlockerCallback {
23  public:
24   virtual ~BlockerCallback() {}
25
26   virtual void ProcessBlock(const float* const* input,
27                             int num_frames,
28                             int num_input_channels,
29                             int num_output_channels,
30                             float* const* output) = 0;
31 };
32
33 // The main purpose of Blocker is to abstract away the fact that often we
34 // receive a different number of audio frames than our transform takes. For
35 // example, most FFTs work best when the fft-size is a power of 2, but suppose
36 // we receive 20ms of audio at a sample rate of 48000. That comes to 960 frames
37 // of audio, which is not a power of 2. Blocker allows us to specify the
38 // transform and all other necessary processing via the Process() callback
39 // function without any constraints on the transform-size
40 // (read: |block_size_|) or received-audio-size (read: |chunk_size_|).
41 // We handle this for the multichannel audio case, allowing for different
42 // numbers of input and output channels (for example, beamforming takes 2 or
43 // more input channels and returns 1 output channel). Audio signals are
44 // represented as deinterleaved floats in the range [-1, 1].
45 //
46 // Blocker is responsible for:
47 // - blocking audio while handling potential discontinuities on the edges
48 //   of chunks
49 // - windowing blocks before sending them to Process()
50 // - windowing processed blocks, and overlap-adding them together before
51 //   sending back a processed chunk
52 //
53 // To use blocker:
54 // 1. Impelment a BlockerCallback object |bc|.
55 // 2. Instantiate a Blocker object |b|, passing in |bc|.
56 // 3. As you receive audio, call b.ProcessChunk() to get processed audio.
57 //
58 // A small amount of delay is added to the first received chunk to deal with
59 // the difference in chunk/block sizes. This delay is <= chunk_size.
60 class Blocker {
61  public:
62   Blocker(int chunk_size,
63           int block_size,
64           int num_input_channels,
65           int num_output_channels,
66           const float* window,
67           int shift_amount,
68           BlockerCallback* callback);
69
70   void ProcessChunk(const float* const* input,
71                     int num_frames,
72                     int num_input_channels,
73                     int num_output_channels,
74                     float* const* output);
75
76  private:
77   const int chunk_size_;
78   const int block_size_;
79   const int num_input_channels_;
80   const int num_output_channels_;
81
82   // The number of frames of delay to add at the beginning of the first chunk.
83   //
84   // TODO(claguna): find a lower cap for this than |block_size_|.
85   const int initial_delay_;
86
87   // The frame index into the input buffer where the first block should be read
88   // from. This is necessary because shift_amount_ is not necessarily a
89   // multiple of chunk_size_, so blocks won't line up at the start of the
90   // buffer.
91   int frame_offset_;
92
93   // Since blocks nearly always overlap, there are certain blocks that require
94   // frames from the end of one chunk and the beginning of the next chunk. The
95   // input and output buffers are responsible for saving those frames between
96   // calls to ProcessChunk().
97   //
98   // Both contain |initial delay| + |chunk_size| frames.
99   ChannelBuffer<float> input_buffer_;
100   ChannelBuffer<float> output_buffer_;
101
102   // Space for the input block (can't wrap because of windowing).
103   ChannelBuffer<float> input_block_;
104
105   // Space for the output block (can't wrap because of overlap/add).
106   ChannelBuffer<float> output_block_;
107
108   scoped_ptr<float[]> window_;
109
110   // The amount of frames between the start of contiguous blocks. For example,
111   // |shift_amount_| = |block_size_| / 2 for a Hann window.
112   int shift_amount_;
113
114   BlockerCallback* callback_;
115 };
116
117 }  // namespace webrtc
118
119 #endif  // WEBRTC_INTERNAL_BEAMFORMER_BLOCKER_H_