1 | /* Copyright 2017 The TensorFlow Authors. All Rights Reserved. |
---|---|
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations under the License. |
14 | ==============================================================================*/ |
15 | |
16 | #include "tensorflow/core/kernels/mfcc_dct.h" |
17 | |
18 | #include <math.h> |
19 | #include "tensorflow/core/platform/logging.h" |
20 | |
21 | namespace tensorflow { |
22 | |
23 | MfccDct::MfccDct() : initialized_(false) {} |
24 | |
25 | bool MfccDct::Initialize(int input_length, int coefficient_count) { |
26 | coefficient_count_ = coefficient_count; |
27 | input_length_ = input_length; |
28 | |
29 | if (coefficient_count_ < 1) { |
30 | LOG(ERROR) << "Coefficient count must be positive."; |
31 | return false; |
32 | } |
33 | |
34 | if (input_length < 1) { |
35 | LOG(ERROR) << "Input length must be positive."; |
36 | return false; |
37 | } |
38 | |
39 | if (coefficient_count_ > input_length_) { |
40 | LOG(ERROR) << "Coefficient count must be less than or equal to " |
41 | << "input length."; |
42 | return false; |
43 | } |
44 | |
45 | cosines_.resize(coefficient_count_); |
46 | double fnorm = sqrt(2.0 / input_length_); |
47 | // Some platforms don't have M_PI, so define a local constant here. |
48 | const double pi = std::atan(1) * 4; |
49 | double arg = pi / input_length_; |
50 | for (int i = 0; i < coefficient_count_; ++i) { |
51 | cosines_[i].resize(input_length_); |
52 | for (int j = 0; j < input_length_; ++j) { |
53 | cosines_[i][j] = fnorm * cos(i * arg * (j + 0.5)); |
54 | } |
55 | } |
56 | initialized_ = true; |
57 | return true; |
58 | } |
59 | |
60 | void MfccDct::Compute(const std::vector<double> &input, |
61 | std::vector<double> *output) const { |
62 | if (!initialized_) { |
63 | LOG(ERROR) << "DCT not initialized."; |
64 | return; |
65 | } |
66 | |
67 | output->resize(coefficient_count_); |
68 | int length = input.size(); |
69 | if (length > input_length_) { |
70 | length = input_length_; |
71 | } |
72 | |
73 | for (int i = 0; i < coefficient_count_; ++i) { |
74 | double sum = 0.0; |
75 | for (int j = 0; j < length; ++j) { |
76 | sum += cosines_[i][j] * input[j]; |
77 | } |
78 | (*output)[i] = sum; |
79 | } |
80 | } |
81 | |
82 | } // namespace tensorflow |
83 |