online-feature.h (5710B)
1 /** 2 * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) 3 * 4 * See LICENSE for clarification regarding multiple authors 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 // The content in this file is copied/modified from 20 // This file is copied/modified from kaldi/src/feat/online-feature.h 21 #ifndef KALDI_NATIVE_FBANK_CSRC_ONLINE_FEATURE_H_ 22 #define KALDI_NATIVE_FBANK_CSRC_ONLINE_FEATURE_H_ 23 24 #include <cstdint> 25 #include <deque> 26 #include <vector> 27 28 #include "kaldi-native-fbank/csrc/feature-fbank.h" 29 #include "kaldi-native-fbank/csrc/feature-mfcc.h" 30 #include "kaldi-native-fbank/csrc/feature-window.h" 31 #include "kaldi-native-fbank/csrc/whisper-feature.h" 32 33 namespace knf { 34 35 /// This class serves as a storage for feature vectors with an option to limit 36 /// the memory usage by removing old elements. The deleted frames indices are 37 /// "remembered" so that regardless of the MAX_ITEMS setting, the user always 38 /// provides the indices as if no deletion was being performed. 39 /// This is useful when processing very long recordings which would otherwise 40 /// cause the memory to eventually blow up when the features are not being 41 /// removed. 42 class RecyclingVector { 43 public: 44 /// By default it does not remove any elements. 45 explicit RecyclingVector(int32_t items_to_hold = -1); 46 47 ~RecyclingVector() = default; 48 RecyclingVector(const RecyclingVector &) = delete; 49 RecyclingVector &operator=(const RecyclingVector &) = delete; 50 51 // The pointer is owned by RecyclingVector 52 // Users should not free it 53 const float *At(int32_t index) const; 54 55 void PushBack(std::vector<float> item); 56 57 /// This method returns the size as if no "recycling" had happened, 58 /// i.e. equivalent to the number of times the PushBack method has been 59 /// called. 60 int32_t Size() const; 61 62 // discard the first n frames 63 void Pop(int32_t n); 64 65 private: 66 std::deque<std::vector<float>> items_; 67 int32_t items_to_hold_; 68 int32_t first_available_index_; 69 }; 70 71 /// This is a templated class for online feature extraction; 72 /// it's templated on a class like MfccComputer or PlpComputer 73 /// that does the basic feature extraction. 74 template <class C> 75 class OnlineGenericBaseFeature { 76 public: 77 // Constructor from options class 78 explicit OnlineGenericBaseFeature(const typename C::Options &opts); 79 80 int32_t Dim() const { return computer_.Dim(); } 81 82 float FrameShiftInSeconds() const { 83 return computer_.GetFrameOptions().frame_shift_ms / 1000.0f; 84 } 85 86 int32_t NumFramesReady() const { return features_.Size(); } 87 88 // Note: IsLastFrame() will only ever return true if you have called 89 // InputFinished() (and this frame is the last frame). 90 bool IsLastFrame(int32_t frame) const { 91 return input_finished_ && frame == NumFramesReady() - 1; 92 } 93 94 const float *GetFrame(int32_t frame) const { return features_.At(frame); } 95 96 // This would be called from the application, when you get 97 // more wave data. Note: the sampling_rate is only provided so 98 // the code can assert that it matches the sampling rate 99 // expected in the options. 100 // 101 // @param sampling_rate The sampling_rate of the input waveform 102 // @param waveform Pointer to a 1-D array of size n 103 // @param n Number of entries in waveform 104 void AcceptWaveform(float sampling_rate, const float *waveform, int32_t n); 105 106 // InputFinished() tells the class you won't be providing any 107 // more waveform. This will help flush out the last frame or two 108 // of features, in the case where snip-edges == false; it also 109 // affects the return value of IsLastFrame(). 110 void InputFinished(); 111 112 // discard the first n frames 113 void Pop(int32_t n) { features_.Pop(n); } 114 115 private: 116 // This function computes any additional feature frames that it is possible to 117 // compute from 'waveform_remainder_', which at this point may contain more 118 // than just a remainder-sized quantity (because AcceptWaveform() appends to 119 // waveform_remainder_ before calling this function). It adds these feature 120 // frames to features_, and shifts off any now-unneeded samples of input from 121 // waveform_remainder_ while incrementing waveform_offset_ by the same amount. 122 void ComputeFeatures(); 123 124 C computer_; // class that does the MFCC or PLP or filterbank computation 125 126 FeatureWindowFunction window_function_; 127 128 // features_ is the Mfcc or Plp or Fbank features that we have already 129 // computed. 130 131 RecyclingVector features_; 132 133 // True if the user has called "InputFinished()" 134 bool input_finished_; 135 136 // waveform_offset_ is the number of samples of waveform that we have 137 // already discarded, i.e. that were prior to 'waveform_remainder_'. 138 int64_t waveform_offset_; 139 140 // waveform_remainder_ is a short piece of waveform that we may need to keep 141 // after extracting all the whole frames we can (whatever length of feature 142 // will be required for the next phase of computation). 143 // It is a 1-D tensor 144 std::vector<float> waveform_remainder_; 145 }; 146 147 using OnlineFbank = OnlineGenericBaseFeature<FbankComputer>; 148 using OnlineMfcc = OnlineGenericBaseFeature<MfccComputer>; 149 using OnlineWhisperFbank = OnlineGenericBaseFeature<WhisperFeatureComputer>; 150 151 } // namespace knf 152 153 #endif // KALDI_NATIVE_FBANK_CSRC_ONLINE_FEATURE_H_