janitor

janitor
git clone https://git.prime8.dev/janitor.git
Log | Files | Refs | README | LICENSE

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_