|
|
// Copyright (c) 2017 Personal (Binbin Zhang)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "feature_pipeline.h"
#include <algorithm>
#include <utility>
namespace wenet { using namespace fst; FeaturePipeline::FeaturePipeline(const FeaturePipelineConfig& config) : config_(config), feature_dim_(config.num_bins), fbank_(config.num_bins, config.sample_rate, config.frame_length, config.frame_shift, config.low_freq, config.pre_emphasis, config.scale_input_to_unit, config.log_floor, config.log_base, config.window_type, config.mel_type, config.norm_type), num_frames_(0), input_finished_(false) {}
void FeaturePipeline::AcceptWaveform(const float* pcm, const int size) { std::vector<std::vector<float>> feats; std::vector<float> waves; waves.insert(waves.end(), remained_wav_.begin(), remained_wav_.end()); waves.insert(waves.end(), pcm, pcm + size); int num_frames = fbank_.Compute(waves, &feats); feature_queue_.Push(std::move(feats)); num_frames_ += num_frames;
int left_samples = waves.size() - config_.frame_shift * num_frames; remained_wav_.resize(left_samples); std::copy(waves.begin() + config_.frame_shift * num_frames, waves.end(), remained_wav_.begin()); // We are still adding wave, notify input is not finished
finish_condition_.notify_one(); }
void FeaturePipeline::AcceptWaveform(const int16_t* pcm, const int size) { auto* float_pcm = new float[size]; for (size_t i = 0; i < size; i++) { float_pcm[i] = static_cast<float>(pcm[i]); } this->AcceptWaveform(float_pcm, size); delete[] float_pcm; }
void FeaturePipeline::set_input_finished() { CHECK(!input_finished_); { std::lock_guard<std::mutex> lock(mutex_); input_finished_ = true; } finish_condition_.notify_one(); }
bool FeaturePipeline::ReadOne(std::vector<float>* feat) { if (!feature_queue_.Empty()) { *feat = std::move(feature_queue_.Pop()); return true; } else { std::unique_lock<std::mutex> lock(mutex_); while (!input_finished_) { // This will release the lock and wait for notify_one()
// from AcceptWaveform() or set_input_finished()
finish_condition_.wait(lock); if (!feature_queue_.Empty()) { *feat = std::move(feature_queue_.Pop()); return true; } } CHECK(input_finished_); // Double check queue.empty, see issue#893 for detailed discussions.
if (!feature_queue_.Empty()) { *feat = std::move(feature_queue_.Pop()); return true; } else { return false; } } }
bool FeaturePipeline::Read(int num_frames, std::vector<std::vector<float>>* feats) { feats->clear(); if (feature_queue_.Size() >= num_frames) { *feats = std::move(feature_queue_.Pop(num_frames)); return true; } else { std::unique_lock<std::mutex> lock(mutex_); while (!input_finished_) { // This will release the lock and wait for notify_one()
// from AcceptWaveform() or set_input_finished()
finish_condition_.wait(lock); if (feature_queue_.Size() >= num_frames) { *feats = std::move(feature_queue_.Pop(num_frames)); return true; } } CHECK(input_finished_); // Double check queue.empty, see issue#893 for detailed discussions.
if (feature_queue_.Size() >= num_frames) { *feats = std::move(feature_queue_.Pop(num_frames)); return true; } else { *feats = std::move(feature_queue_.Pop(feature_queue_.Size())); return false; } } }
void FeaturePipeline::Reset() { input_finished_ = false; num_frames_ = 0; remained_wav_.clear(); feature_queue_.Clear(); }
} // namespace wenet
|