signal.cc
Go to the documentation of this file.
1 // feat/signal.cc
2 
3 // Copyright 2015 Tom Ko
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 #include "base/kaldi-common.h"
21 #include "util/common-utils.h"
22 #include "feat/signal.h"
23 
24 namespace kaldi {
25 
27  int32 num_fft_bins = a.Dim() / 2;
28  for (int32 i = 0; i < num_fft_bins; i++) {
29  // do complex multiplication
30  ComplexMul(a(2*i), a(2*i + 1), &((*b)(2*i)), &((*b)(2*i + 1)));
31  }
32 }
33 
34 void ConvolveSignals(const Vector<BaseFloat> &filter, Vector<BaseFloat> *signal) {
35  int32 signal_length = signal->Dim();
36  int32 filter_length = filter.Dim();
37  int32 output_length = signal_length + filter_length - 1;
38  Vector<BaseFloat> signal_padded(output_length);
39  signal_padded.SetZero();
40  for (int32 i = 0; i < signal_length; i++) {
41  for (int32 j = 0; j < filter_length; j++) {
42  signal_padded(i + j) += (*signal)(i) * filter(j);
43  }
44  }
45  signal->Resize(output_length);
46  signal->CopyFromVec(signal_padded);
47 }
48 
49 
51  int32 signal_length = signal->Dim();
52  int32 filter_length = filter.Dim();
53  int32 output_length = signal_length + filter_length - 1;
54 
55  int32 fft_length = RoundUpToNearestPowerOfTwo(output_length);
56  KALDI_VLOG(1) << "fft_length for full signal convolution is " << fft_length;
57 
58  SplitRadixRealFft<BaseFloat> srfft(fft_length);
59 
60  Vector<BaseFloat> filter_padded(fft_length);
61  filter_padded.Range(0, filter_length).CopyFromVec(filter);
62  srfft.Compute(filter_padded.Data(), true);
63 
64  Vector<BaseFloat> signal_padded(fft_length);
65  signal_padded.Range(0, signal_length).CopyFromVec(*signal);
66  srfft.Compute(signal_padded.Data(), true);
67 
68  ElementwiseProductOfFft(filter_padded, &signal_padded);
69 
70  srfft.Compute(signal_padded.Data(), false);
71  signal_padded.Scale(1.0 / fft_length);
72 
73  signal->Resize(output_length);
74  signal->CopyFromVec(signal_padded.Range(0, output_length));
75 }
76 
78  int32 signal_length = signal->Dim();
79  int32 filter_length = filter.Dim();
80  int32 output_length = signal_length + filter_length - 1;
81  signal->Resize(output_length, kCopyData);
82 
83  KALDI_VLOG(1) << "Length of the filter is " << filter_length;
84 
85  int32 fft_length = RoundUpToNearestPowerOfTwo(4 * filter_length);
86  KALDI_VLOG(1) << "Best FFT length is " << fft_length;
87 
88  int32 block_length = fft_length - filter_length + 1;
89  KALDI_VLOG(1) << "Block size is " << block_length;
90  SplitRadixRealFft<BaseFloat> srfft(fft_length);
91 
92  Vector<BaseFloat> filter_padded(fft_length);
93  filter_padded.Range(0, filter_length).CopyFromVec(filter);
94  srfft.Compute(filter_padded.Data(), true);
95 
96  Vector<BaseFloat> temp_pad(filter_length - 1);
97  temp_pad.SetZero();
98  Vector<BaseFloat> signal_block_padded(fft_length);
99 
100  for (int32 po = 0; po < output_length; po += block_length) {
101  // get a block of the signal
102  int32 process_length = std::min(block_length, output_length - po);
103  signal_block_padded.SetZero();
104  signal_block_padded.Range(0, process_length).CopyFromVec(signal->Range(po, process_length));
105 
106  srfft.Compute(signal_block_padded.Data(), true);
107 
108  ElementwiseProductOfFft(filter_padded, &signal_block_padded);
109 
110  srfft.Compute(signal_block_padded.Data(), false);
111  signal_block_padded.Scale(1.0 / fft_length);
112 
113  // combine the block
114  if (po + block_length < output_length) { // current block is not the last block
115  signal->Range(po, block_length).CopyFromVec(signal_block_padded.Range(0, block_length));
116  signal->Range(po, filter_length - 1).AddVec(1.0, temp_pad);
117  temp_pad.CopyFromVec(signal_block_padded.Range(block_length, filter_length - 1));
118  } else {
119  signal->Range(po, output_length - po).CopyFromVec(
120  signal_block_padded.Range(0, output_length - po));
121  if (filter_length - 1 < output_length - po)
122  signal->Range(po, filter_length - 1).AddVec(1.0, temp_pad);
123  else
124  signal->Range(po, output_length - po).AddVec(1.0, temp_pad.Range(0, output_length - po));
125  }
126  }
127 }
128 }
129 
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
kaldi::int32 int32
int32 RoundUpToNearestPowerOfTwo(int32 n)
Definition: kaldi-math.cc:32
void Resize(MatrixIndexT length, MatrixResizeType resize_type=kSetZero)
Set vector to a specified size (can be zero).
void FFTbasedConvolveSignals(const Vector< BaseFloat > &filter, Vector< BaseFloat > *signal)
Definition: signal.cc:50
void FFTbasedBlockConvolveSignals(const Vector< BaseFloat > &filter, Vector< BaseFloat > *signal)
Definition: signal.cc:77
void CopyFromVec(const VectorBase< Real > &v)
Copy data from another vector (must match own size).
void ElementwiseProductOfFft(const Vector< BaseFloat > &a, Vector< BaseFloat > *b)
Definition: signal.cc:26
Real * Data()
Returns a pointer to the start of the vector&#39;s data.
Definition: kaldi-vector.h:70
void ComplexMul(const Real &a_re, const Real &a_im, Real *b_re, Real *b_im)
ComplexMul implements, inline, the complex multiplication b *= a.
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:64
void Scale(Real alpha)
Multiplies all elements by this constant.
A class representing a vector.
Definition: kaldi-vector.h:406
void ConvolveSignals(const Vector< BaseFloat > &filter, Vector< BaseFloat > *signal)
Definition: signal.cc:34
#define KALDI_VLOG(v)
Definition: kaldi-error.h:156
void SetZero()
Set vector to all zeros.
void Compute(Real *x, bool forward)
If forward == true, this function transforms from a sequence of N real points to its complex fourier ...
Definition: srfft.cc:356
SubVector< Real > Range(const MatrixIndexT o, const MatrixIndexT l)
Returns a sub-vector of a vector (a range of elements).
Definition: kaldi-vector.h:94