summaryrefslogtreecommitdiff
path: root/source/use_case/ad
diff options
context:
space:
mode:
authorKshitij Sisodia <kshitij.sisodia@arm.com>2022-05-06 09:13:03 +0100
committerKshitij Sisodia <kshitij.sisodia@arm.com>2022-05-06 17:11:41 +0100
commitaa4bcb14d0cbee910331545dd2fc086b58c37170 (patch)
treee67a43a43f61c6f8b6aad19018b0827baf7e31a6 /source/use_case/ad
parentfcca863bafd5f33522bc14c23dde4540e264ec94 (diff)
downloadml-embedded-evaluation-kit-aa4bcb14d0cbee910331545dd2fc086b58c37170.tar.gz
MLECO-3183: Refactoring application sources
Platform agnostic application sources are moved into application api module with their own independent CMake projects. Changes for MLECO-3080 also included - they create CMake projects individial API's (again, platform agnostic) that dependent on the common logic. The API for KWS_API "joint" API has been removed and now the use case relies on individual KWS, and ASR API libraries. Change-Id: I1f7748dc767abb3904634a04e0991b74ac7b756d Signed-off-by: Kshitij Sisodia <kshitij.sisodia@arm.com>
Diffstat (limited to 'source/use_case/ad')
-rw-r--r--source/use_case/ad/include/AdMelSpectrogram.hpp97
-rw-r--r--source/use_case/ad/include/AdModel.hpp59
-rw-r--r--source/use_case/ad/include/AdProcessing.hpp230
-rw-r--r--source/use_case/ad/include/MelSpectrogram.hpp234
-rw-r--r--source/use_case/ad/src/AdMelSpectrogram.cc93
-rw-r--r--source/use_case/ad/src/AdModel.cc54
-rw-r--r--source/use_case/ad/src/AdProcessing.cc208
-rw-r--r--source/use_case/ad/src/MainLoop.cc25
-rw-r--r--source/use_case/ad/src/MelSpectrogram.cc316
-rw-r--r--source/use_case/ad/usecase.cmake3
10 files changed, 26 insertions, 1293 deletions
diff --git a/source/use_case/ad/include/AdMelSpectrogram.hpp b/source/use_case/ad/include/AdMelSpectrogram.hpp
deleted file mode 100644
index 05c5bfc..0000000
--- a/source/use_case/ad/include/AdMelSpectrogram.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2021 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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.
- */
-#ifndef ADMELSPECTROGRAM_HPP
-#define ADMELSPECTROGRAM_HPP
-
-#include "MelSpectrogram.hpp"
-
-namespace arm {
-namespace app {
-namespace audio {
-
- /* Class to provide anomaly detection specific Mel Spectrogram calculation requirements */
- class AdMelSpectrogram : public MelSpectrogram {
-
- public:
- static constexpr uint32_t ms_defaultSamplingFreq = 16000;
- static constexpr uint32_t ms_defaultNumFbankBins = 64;
- static constexpr uint32_t ms_defaultMelLoFreq = 0;
- static constexpr uint32_t ms_defaultMelHiFreq = 8000;
- static constexpr bool ms_defaultUseHtkMethod = false;
-
- explicit AdMelSpectrogram(const size_t frameLen)
- : MelSpectrogram(MelSpecParams(
- ms_defaultSamplingFreq, ms_defaultNumFbankBins,
- ms_defaultMelLoFreq, ms_defaultMelHiFreq,
- frameLen, ms_defaultUseHtkMethod))
- {}
-
- AdMelSpectrogram() = delete;
- ~AdMelSpectrogram() = default;
-
- protected:
-
- /**
- * @brief Overrides base class implementation of this function.
- * @param[in] fftVec Vector populated with FFT magnitudes
- * @param[in] melFilterBank 2D Vector with filter bank weights
- * @param[in] filterBankFilterFirst Vector containing the first indices of filter bank
- * to be used for each bin.
- * @param[in] filterBankFilterLast Vector containing the last indices of filter bank
- * to be used for each bin.
- * @param[out] melEnergies Pre-allocated vector of MEL energies to be
- * populated.
- * @return true if successful, false otherwise
- */
- virtual bool ApplyMelFilterBank(
- std::vector<float>& fftVec,
- std::vector<std::vector<float>>& melFilterBank,
- std::vector<uint32_t>& filterBankFilterFirst,
- std::vector<uint32_t>& filterBankFilterLast,
- std::vector<float>& melEnergies) override;
-
- /**
- * @brief Override for the base class implementation convert mel
- * energies to logarithmic scale. The difference from
- * default behaviour is that the power is converted to dB
- * and subsequently clamped.
- * @param[in,out] melEnergies - 1D vector of Mel energies
- **/
- virtual void ConvertToLogarithmicScale(std::vector<float>& melEnergies) override;
-
- /**
- * @brief Given the low and high Mel values, get the normaliser
- * for weights to be applied when populating the filter
- * bank. Override for the base class implementation.
- * @param[in] leftMel - low Mel frequency value
- * @param[in] rightMel - high Mel frequency value
- * @param[in] useHTKMethod - bool to signal if HTK method is to be
- * used for calculation
- * @return Return float value to be applied
- * when populating the filter bank.
- */
- virtual float GetMelFilterBankNormaliser(
- const float& leftMel,
- const float& rightMel,
- const bool useHTKMethod) override;
- };
-
-} /* namespace audio */
-} /* namespace app */
-} /* namespace arm */
-
-#endif /* ADMELSPECTROGRAM_HPP */
diff --git a/source/use_case/ad/include/AdModel.hpp b/source/use_case/ad/include/AdModel.hpp
deleted file mode 100644
index 2195a7c..0000000
--- a/source/use_case/ad/include/AdModel.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2021-2022 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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.
- */
-#ifndef AD_MODEL_HPP
-#define AD_MODEL_HPP
-
-#include "Model.hpp"
-
-extern const int g_FrameLength;
-extern const int g_FrameStride;
-extern const float g_ScoreThreshold;
-extern const float g_TrainingMean;
-
-namespace arm {
-namespace app {
-
- class AdModel : public Model {
-
- public:
- /* Indices for the expected model - based on input tensor shape */
- static constexpr uint32_t ms_inputRowsIdx = 1;
- static constexpr uint32_t ms_inputColsIdx = 2;
-
- protected:
- /** @brief Gets the reference to op resolver interface class */
- const tflite::MicroOpResolver& GetOpResolver() override;
-
- /** @brief Adds operations to the op resolver instance */
- bool EnlistOperations() override;
-
- const uint8_t* ModelPointer() override;
-
- size_t ModelSize() override;
-
- private:
- /* Maximum number of individual operations that can be enlisted */
- static constexpr int ms_maxOpCnt = 6;
-
- /* A mutable op resolver instance */
- tflite::MicroMutableOpResolver<ms_maxOpCnt> m_opResolver;
- };
-
-} /* namespace app */
-} /* namespace arm */
-
-#endif /* AD_MODEL_HPP */
diff --git a/source/use_case/ad/include/AdProcessing.hpp b/source/use_case/ad/include/AdProcessing.hpp
deleted file mode 100644
index 9abf6f1..0000000
--- a/source/use_case/ad/include/AdProcessing.hpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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.
- */
-#ifndef AD_PROCESSING_HPP
-#define AD_PROCESSING_HPP
-
-#include "BaseProcessing.hpp"
-#include "AudioUtils.hpp"
-#include "AdMelSpectrogram.hpp"
-#include "log_macros.h"
-
-namespace arm {
-namespace app {
-
- /**
- * @brief Pre-processing class for anomaly detection use case.
- * Implements methods declared by BasePreProcess and anything else needed
- * to populate input tensors ready for inference.
- */
- class AdPreProcess : public BasePreProcess {
-
- public:
- /**
- * @brief Constructor for AdPreProcess class objects
- * @param[in] inputTensor input tensor pointer from the tensor arena.
- * @param[in] melSpectrogramFrameLen MEL spectrogram's frame length
- * @param[in] melSpectrogramFrameStride MEL spectrogram's frame stride
- * @param[in] adModelTrainingMean Training mean for the Anomaly detection model being used.
- */
- explicit AdPreProcess(TfLiteTensor* inputTensor,
- uint32_t melSpectrogramFrameLen,
- uint32_t melSpectrogramFrameStride,
- float adModelTrainingMean);
-
- ~AdPreProcess() = default;
-
- /**
- * @brief Function to invoke pre-processing and populate the input vector
- * @param input pointer to input data. For anomaly detection, this is the pointer to
- * the audio data.
- * @param inputSize Size of the data being passed in for pre-processing.
- * @return True if successful, false otherwise.
- */
- bool DoPreProcess(const void* input, size_t inputSize) override;
-
- /**
- * @brief Getter function for audio window size computed when constructing
- * the class object.
- * @return Audio window size as 32 bit unsigned integer.
- */
- uint32_t GetAudioWindowSize();
-
- /**
- * @brief Getter function for audio window stride computed when constructing
- * the class object.
- * @return Audio window stride as 32 bit unsigned integer.
- */
- uint32_t GetAudioDataStride();
-
- /**
- * @brief Setter function for current audio index. This is only used for evaluating
- * if previously computed features can be re-used from cache.
- */
- void SetAudioWindowIndex(uint32_t idx);
-
- private:
- bool m_validInstance{false}; /**< Indicates the current object is valid. */
- uint32_t m_melSpectrogramFrameLen{}; /**< MEL spectrogram's window frame length */
- uint32_t m_melSpectrogramFrameStride{}; /**< MEL spectrogram's window frame stride */
- uint8_t m_inputResizeScale{}; /**< Downscaling factor for the MEL energy matrix. */
- uint32_t m_numMelSpecVectorsInAudioStride{}; /**< Number of frames to move across the audio. */
- uint32_t m_audioDataWindowSize{}; /**< Audio window size computed based on other parameters. */
- uint32_t m_audioDataStride{}; /**< Audio window stride computed. */
- uint32_t m_numReusedFeatureVectors{}; /**< Number of MEL vectors that can be re-used */
- uint32_t m_audioWindowIndex{}; /**< Current audio window index (from audio's sliding window) */
-
- audio::SlidingWindow<const int16_t> m_melWindowSlider; /**< Internal MEL spectrogram window slider */
- audio::AdMelSpectrogram m_melSpec; /**< MEL spectrogram computation object */
- std::function<void
- (std::vector<int16_t>&, int, bool, size_t, size_t)> m_featureCalc; /**< Feature calculator object */
- };
-
- class AdPostProcess : public BasePostProcess {
- public:
- /**
- * @brief Constructor for AdPostProcess object.
- * @param[in] outputTensor Output tensor pointer.
- */
- explicit AdPostProcess(TfLiteTensor* outputTensor);
-
- ~AdPostProcess() = default;
-
- /**
- * @brief Function to do the post-processing on the output tensor.
- * @return True if successful, false otherwise.
- */
- bool DoPostProcess() override;
-
- /**
- * @brief Getter function for an element from the de-quantised output vector.
- * @param index Index of the element to be retrieved.
- * @return index represented as a 32 bit floating point number.
- */
- float GetOutputValue(uint32_t index);
-
- private:
- TfLiteTensor* m_outputTensor{}; /**< Output tensor pointer */
- std::vector<float> m_dequantizedOutputVec{}; /**< Internal output vector */
-
- /**
- * @brief De-quantizes and flattens the output tensor into a vector.
- * @tparam T template parameter to indicate data type.
- * @return True if successful, false otherwise.
- */
- template<typename T>
- bool Dequantize()
- {
- TfLiteTensor* tensor = this->m_outputTensor;
- if (tensor == nullptr) {
- printf_err("Invalid output tensor.\n");
- return false;
- }
- T* tensorData = tflite::GetTensorData<T>(tensor);
-
- uint32_t totalOutputSize = 1;
- for (int inputDim = 0; inputDim < tensor->dims->size; inputDim++){
- totalOutputSize *= tensor->dims->data[inputDim];
- }
-
- /* For getting the floating point values, we need quantization parameters */
- QuantParams quantParams = GetTensorQuantParams(tensor);
-
- this->m_dequantizedOutputVec = std::vector<float>(totalOutputSize, 0);
-
- for (size_t i = 0; i < totalOutputSize; ++i) {
- this->m_dequantizedOutputVec[i] = quantParams.scale * (tensorData[i] - quantParams.offset);
- }
-
- return true;
- }
- };
-
- /* Templated instances available: */
- template bool AdPostProcess::Dequantize<int8_t>();
-
- /**
- * @brief Generic feature calculator factory.
- *
- * Returns lambda function to compute features using features cache.
- * Real features math is done by a lambda function provided as a parameter.
- * Features are written to input tensor memory.
- *
- * @tparam T feature vector type.
- * @param inputTensor model input tensor pointer.
- * @param cacheSize number of feature vectors to cache. Defined by the sliding window overlap.
- * @param compute features calculator function.
- * @return lambda function to compute features.
- */
- template<class T>
- std::function<void (std::vector<int16_t>&, size_t, bool, size_t, size_t)>
- FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize,
- std::function<std::vector<T> (std::vector<int16_t>& )> compute)
- {
- /* Feature cache to be captured by lambda function*/
- static std::vector<std::vector<T>> featureCache = std::vector<std::vector<T>>(cacheSize);
-
- return [=](std::vector<int16_t>& audioDataWindow,
- size_t index,
- bool useCache,
- size_t featuresOverlapIndex,
- size_t resizeScale)
- {
- T* tensorData = tflite::GetTensorData<T>(inputTensor);
- std::vector<T> features;
-
- /* Reuse features from cache if cache is ready and sliding windows overlap.
- * Overlap is in the beginning of sliding window with a size of a feature cache. */
- if (useCache && index < featureCache.size()) {
- features = std::move(featureCache[index]);
- } else {
- features = std::move(compute(audioDataWindow));
- }
- auto size = features.size() / resizeScale;
- auto sizeBytes = sizeof(T);
-
- /* Input should be transposed and "resized" by skipping elements. */
- for (size_t outIndex = 0; outIndex < size; outIndex++) {
- std::memcpy(tensorData + (outIndex*size) + index, &features[outIndex*resizeScale], sizeBytes);
- }
-
- /* Start renewing cache as soon iteration goes out of the windows overlap. */
- if (index >= featuresOverlapIndex / resizeScale) {
- featureCache[index - featuresOverlapIndex / resizeScale] = std::move(features);
- }
- };
- }
-
- template std::function<void (std::vector<int16_t>&, size_t , bool, size_t, size_t)>
- FeatureCalc<int8_t>(TfLiteTensor* inputTensor,
- size_t cacheSize,
- std::function<std::vector<int8_t> (std::vector<int16_t>&)> compute);
-
- template std::function<void(std::vector<int16_t>&, size_t, bool, size_t, size_t)>
- FeatureCalc<float>(TfLiteTensor *inputTensor,
- size_t cacheSize,
- std::function<std::vector<float>(std::vector<int16_t>&)> compute);
-
- std::function<void (std::vector<int16_t>&, int, bool, size_t, size_t)>
- GetFeatureCalculator(audio::AdMelSpectrogram& melSpec,
- TfLiteTensor* inputTensor,
- size_t cacheSize,
- float trainingMean);
-
-} /* namespace app */
-} /* namespace arm */
-
-#endif /* AD_PROCESSING_HPP */
diff --git a/source/use_case/ad/include/MelSpectrogram.hpp b/source/use_case/ad/include/MelSpectrogram.hpp
deleted file mode 100644
index d3ea3f7..0000000
--- a/source/use_case/ad/include/MelSpectrogram.hpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2021 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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.
- */
-#ifndef MELSPECTROGRAM_HPP
-#define MELSPECTROGRAM_HPP
-
-#include "PlatformMath.hpp"
-
-#include <vector>
-#include <cstdint>
-#include <cmath>
-#include <limits>
-#include <string>
-
-namespace arm {
-namespace app {
-namespace audio {
-
- /* Mel Spectrogram consolidated parameters */
- class MelSpecParams {
- public:
- float m_samplingFreq;
- uint32_t m_numFbankBins;
- float m_melLoFreq;
- float m_melHiFreq;
- uint32_t m_frameLen;
- uint32_t m_frameLenPadded;
- bool m_useHtkMethod;
-
- /** @brief Constructor */
- MelSpecParams(const float samplingFreq, const uint32_t numFbankBins,
- const float melLoFreq, const float melHiFreq,
- const uint32_t frameLen, const bool useHtkMethod);
-
- MelSpecParams() = delete;
- ~MelSpecParams() = default;
-
- /** @brief String representation of parameters */
- std::string Str() const;
- };
-
- /**
- * @brief Class for Mel Spectrogram feature extraction.
- * Based on https://github.com/ARM-software/ML-KWS-for-MCU/blob/master/Deployment/Source/MFCC/mfcc.cpp
- * This class is designed to be generic and self-sufficient but
- * certain calculation routines can be overridden to accommodate
- * use-case specific requirements.
- */
- class MelSpectrogram {
-
- public:
- /**
- * @brief Extract Mel Spectrogram for one single small frame of
- * audio data e.g. 640 samples.
- * @param[in] audioData Vector of audio samples to calculate
- * features for.
- * @param[in] trainingMean Value to subtract from the the computed mel spectrogram, default 0.
- * @return Vector of extracted Mel Spectrogram features.
- **/
- std::vector<float> ComputeMelSpec(const std::vector<int16_t>& audioData, float trainingMean = 0);
-
- /**
- * @brief Constructor
- * @param[in] params Mel Spectrogram parameters
- */
- explicit MelSpectrogram(const MelSpecParams& params);
-
- MelSpectrogram() = delete;
- ~MelSpectrogram() = default;
-
- /** @brief Initialise */
- void Init();
-
- /**
- * @brief Extract Mel Spectrogram features and quantise for one single small
- * frame of audio data e.g. 640 samples.
- * @param[in] audioData Vector of audio samples to calculate
- * features for.
- * @param[in] quantScale quantisation scale.
- * @param[in] quantOffset quantisation offset.
- * @param[in] trainingMean training mean.
- * @return Vector of extracted quantised Mel Spectrogram features.
- **/
- template<typename T>
- std::vector<T> MelSpecComputeQuant(const std::vector<int16_t>& audioData,
- const float quantScale,
- const int quantOffset,
- float trainingMean = 0)
- {
- this->ComputeMelSpec(audioData, trainingMean);
- float minVal = std::numeric_limits<T>::min();
- float maxVal = std::numeric_limits<T>::max();
-
- std::vector<T> melSpecOut(this->m_params.m_numFbankBins);
- const size_t numFbankBins = this->m_params.m_numFbankBins;
-
- /* Quantize to T. */
- for (size_t k = 0; k < numFbankBins; ++k) {
- auto quantizedEnergy = std::round(((this->m_melEnergies[k]) / quantScale) + quantOffset);
- melSpecOut[k] = static_cast<T>(std::min<float>(std::max<float>(quantizedEnergy, minVal), maxVal));
- }
-
- return melSpecOut;
- }
-
- /* Constants */
- static constexpr float ms_logStep = /*logf(6.4)*/ 1.8562979903656 / 27.0;
- static constexpr float ms_freqStep = 200.0 / 3;
- static constexpr float ms_minLogHz = 1000.0;
- static constexpr float ms_minLogMel = ms_minLogHz / ms_freqStep;
-
- protected:
- /**
- * @brief Project input frequency to Mel Scale.
- * @param[in] freq input frequency in floating point
- * @param[in] useHTKMethod bool to signal if HTK method is to be
- * used for calculation
- * @return Mel transformed frequency in floating point
- **/
- static float MelScale(const float freq,
- const bool useHTKMethod = true);
-
- /**
- * @brief Inverse Mel transform - convert MEL warped frequency
- * back to normal frequency
- * @param[in] melFreq Mel frequency in floating point
- * @param[in] useHTKMethod bool to signal if HTK method is to be
- * used for calculation
- * @return Real world frequency in floating point
- **/
- static float InverseMelScale(const float melFreq,
- const bool useHTKMethod = true);
-
- /**
- * @brief Populates MEL energies after applying the MEL filter
- * bank weights and adding them up to be placed into
- * bins, according to the filter bank's first and last
- * indices (pre-computed for each filter bank element
- * by CreateMelFilterBank function).
- * @param[in] fftVec Vector populated with FFT magnitudes
- * @param[in] melFilterBank 2D Vector with filter bank weights
- * @param[in] filterBankFilterFirst Vector containing the first indices of filter bank
- * to be used for each bin.
- * @param[in] filterBankFilterLast Vector containing the last indices of filter bank
- * to be used for each bin.
- * @param[out] melEnergies Pre-allocated vector of MEL energies to be
- * populated.
- * @return true if successful, false otherwise
- */
- virtual bool ApplyMelFilterBank(
- std::vector<float>& fftVec,
- std::vector<std::vector<float>>& melFilterBank,
- std::vector<uint32_t>& filterBankFilterFirst,
- std::vector<uint32_t>& filterBankFilterLast,
- std::vector<float>& melEnergies);
-
- /**
- * @brief Converts the Mel energies for logarithmic scale
- * @param[in,out] melEnergies 1D vector of Mel energies
- **/
- virtual void ConvertToLogarithmicScale(std::vector<float>& melEnergies);
-
- /**
- * @brief Given the low and high Mel values, get the normaliser
- * for weights to be applied when populating the filter
- * bank.
- * @param[in] leftMel low Mel frequency value
- * @param[in] rightMel high Mel frequency value
- * @param[in] useHTKMethod bool to signal if HTK method is to be
- * used for calculation
- * @return Return float value to be applied
- * when populating the filter bank.
- */
- virtual float GetMelFilterBankNormaliser(
- const float& leftMel,
- const float& rightMel,
- const bool useHTKMethod);
-
- private:
- MelSpecParams m_params;
- std::vector<float> m_frame;
- std::vector<float> m_buffer;
- std::vector<float> m_melEnergies;
- std::vector<float> m_windowFunc;
- std::vector<std::vector<float>> m_melFilterBank;
- std::vector<uint32_t> m_filterBankFilterFirst;
- std::vector<uint32_t> m_filterBankFilterLast;
- bool m_filterBankInitialised;
- arm::app::math::FftInstance m_fftInstance;
-
- /**
- * @brief Initialises the filter banks.
- **/
- void InitMelFilterBank();
-
- /**
- * @brief Signals whether the instance of MelSpectrogram has had its
- * required buffers initialised
- * @return True if initialised, false otherwise
- **/
- bool IsMelFilterBankInited() const;
-
- /**
- * @brief Create mel filter banks for Mel Spectrogram calculation.
- * @return 2D vector of floats
- **/
- std::vector<std::vector<float>> CreateMelFilterBank();
-
- /**
- * @brief Computes the magnitude from an interleaved complex array
- **/
- void ConvertToPowerSpectrum();
-
- };
-
-} /* namespace audio */
-} /* namespace app */
-} /* namespace arm */
-
-
-#endif /* MELSPECTROGRAM_HPP */
diff --git a/source/use_case/ad/src/AdMelSpectrogram.cc b/source/use_case/ad/src/AdMelSpectrogram.cc
deleted file mode 100644
index 14b9323..0000000
--- a/source/use_case/ad/src/AdMelSpectrogram.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2021 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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 "AdMelSpectrogram.hpp"
-#include "PlatformMath.hpp"
-#include "log_macros.h"
-
-#include <cfloat>
-
-namespace arm {
-namespace app {
-namespace audio {
-
- bool AdMelSpectrogram::ApplyMelFilterBank(
- std::vector<float>& fftVec,
- std::vector<std::vector<float>>& melFilterBank,
- std::vector<uint32_t>& filterBankFilterFirst,
- std::vector<uint32_t>& filterBankFilterLast,
- std::vector<float>& melEnergies)
- {
- const size_t numBanks = melEnergies.size();
-
- if (numBanks != filterBankFilterFirst.size() ||
- numBanks != filterBankFilterLast.size()) {
- printf_err("unexpected filter bank lengths\n");
- return false;
- }
-
- for (size_t bin = 0; bin < numBanks; ++bin) {
- auto filterBankIter = melFilterBank[bin].begin();
- auto end = melFilterBank[bin].end();
- float melEnergy = FLT_MIN; /* Avoid log of zero at later stages. */
- const uint32_t firstIndex = filterBankFilterFirst[bin];
- const uint32_t lastIndex = std::min<int32_t>(filterBankFilterLast[bin], fftVec.size() - 1);
-
- for (uint32_t i = firstIndex; i <= lastIndex && filterBankIter != end; ++i) {
- melEnergy += (*filterBankIter++ * fftVec[i]);
- }
-
- melEnergies[bin] = melEnergy;
- }
-
- return true;
- }
-
- void AdMelSpectrogram::ConvertToLogarithmicScale(
- std::vector<float>& melEnergies)
- {
- /* Container for natural logarithms of mel energies */
- std::vector <float> vecLogEnergies(melEnergies.size(), 0.f);
-
- /* Because we are taking natural logs, we need to multiply by log10(e).
- * Also, for wav2letter model, we scale our log10 values by 10 */
- constexpr float multiplier = 10.0 * /* default scalar */
- 0.4342944819032518; /* log10f(std::exp(1.0))*/
-
- /* Take log of the whole vector */
- math::MathUtils::VecLogarithmF32(melEnergies, vecLogEnergies);
-
- /* Scale the log values. */
- for (auto iterM = melEnergies.begin(), iterL = vecLogEnergies.begin();
- iterM != melEnergies.end() && iterL != vecLogEnergies.end(); ++iterM, ++iterL) {
-
- *iterM = *iterL * multiplier;
- }
- }
-
- float AdMelSpectrogram::GetMelFilterBankNormaliser(
- const float& leftMel,
- const float& rightMel,
- const bool useHTKMethod)
- {
- /* Slaney normalization for mel weights. */
- return (2.0f / (AdMelSpectrogram::InverseMelScale(rightMel, useHTKMethod) -
- AdMelSpectrogram::InverseMelScale(leftMel, useHTKMethod)));
- }
-
-} /* namespace audio */
-} /* namespace app */
-} /* namespace arm */
diff --git a/source/use_case/ad/src/AdModel.cc b/source/use_case/ad/src/AdModel.cc
deleted file mode 100644
index a2ef260..0000000
--- a/source/use_case/ad/src/AdModel.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2021 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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 "AdModel.hpp"
-#include "log_macros.h"
-
-const tflite::MicroOpResolver& arm::app::AdModel::GetOpResolver()
-{
- return this->m_opResolver;
-}
-
-bool arm::app::AdModel::EnlistOperations()
-{
- this->m_opResolver.AddAveragePool2D();
- this->m_opResolver.AddConv2D();
- this->m_opResolver.AddDepthwiseConv2D();
- this->m_opResolver.AddRelu6();
- this->m_opResolver.AddReshape();
-
-#if defined(ARM_NPU)
- if (kTfLiteOk == this->m_opResolver.AddEthosU()) {
- info("Added %s support to op resolver\n",
- tflite::GetString_ETHOSU());
- } else {
- printf_err("Failed to add Arm NPU support to op resolver.");
- return false;
- }
-#endif /* ARM_NPU */
- return true;
-}
-
-extern uint8_t* GetModelPointer();
-const uint8_t* arm::app::AdModel::ModelPointer()
-{
- return GetModelPointer();
-}
-extern size_t GetModelLen();
-size_t arm::app::AdModel::ModelSize()
-{
- return GetModelLen();
-}
diff --git a/source/use_case/ad/src/AdProcessing.cc b/source/use_case/ad/src/AdProcessing.cc
deleted file mode 100644
index a33131c..0000000
--- a/source/use_case/ad/src/AdProcessing.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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 "AdProcessing.hpp"
-
-#include "AdModel.hpp"
-
-namespace arm {
-namespace app {
-
-AdPreProcess::AdPreProcess(TfLiteTensor* inputTensor,
- uint32_t melSpectrogramFrameLen,
- uint32_t melSpectrogramFrameStride,
- float adModelTrainingMean):
- m_validInstance{false},
- m_melSpectrogramFrameLen{melSpectrogramFrameLen},
- m_melSpectrogramFrameStride{melSpectrogramFrameStride},
- /**< Model is trained on features downsampled 2x */
- m_inputResizeScale{2},
- /**< We are choosing to move by 20 frames across the audio for each inference. */
- m_numMelSpecVectorsInAudioStride{20},
- m_audioDataStride{m_numMelSpecVectorsInAudioStride * melSpectrogramFrameStride},
- m_melSpec{melSpectrogramFrameLen}
-{
- if (!inputTensor) {
- printf_err("Invalid input tensor provided to pre-process\n");
- return;
- }
-
- TfLiteIntArray* inputShape = inputTensor->dims;
-
- if (!inputShape) {
- printf_err("Invalid input tensor dims\n");
- return;
- }
-
- const uint32_t kNumRows = inputShape->data[AdModel::ms_inputRowsIdx];
- const uint32_t kNumCols = inputShape->data[AdModel::ms_inputColsIdx];
-
- /* Deduce the data length required for 1 inference from the network parameters. */
- this->m_audioDataWindowSize = (((this->m_inputResizeScale * kNumCols) - 1) *
- melSpectrogramFrameStride) +
- melSpectrogramFrameLen;
- this->m_numReusedFeatureVectors = kNumRows -
- (this->m_numMelSpecVectorsInAudioStride /
- this->m_inputResizeScale);
- this->m_melSpec.Init();
-
- /* Creating a Mel Spectrogram sliding window for the data required for 1 inference.
- * "resizing" done here by multiplying stride by resize scale. */
- this->m_melWindowSlider = audio::SlidingWindow<const int16_t>(
- nullptr, /* to be populated later. */
- this->m_audioDataWindowSize,
- melSpectrogramFrameLen,
- melSpectrogramFrameStride * this->m_inputResizeScale);
-
- /* Construct feature calculation function. */
- this->m_featureCalc = GetFeatureCalculator(this->m_melSpec, inputTensor,
- this->m_numReusedFeatureVectors,
- adModelTrainingMean);
- this->m_validInstance = true;
-}
-
-bool AdPreProcess::DoPreProcess(const void* input, size_t inputSize)
-{
- /* Check that we have a valid instance. */
- if (!this->m_validInstance) {
- printf_err("Invalid pre-processor instance\n");
- return false;
- }
-
- /* We expect that we can traverse the size with which the MEL spectrogram
- * sliding window was initialised with. */
- if (!input || inputSize < this->m_audioDataWindowSize) {
- printf_err("Invalid input provided for pre-processing\n");
- return false;
- }
-
- /* We moved to the next window - set the features sliding to the new address. */
- this->m_melWindowSlider.Reset(static_cast<const int16_t*>(input));
-
- /* The first window does not have cache ready. */
- const bool useCache = this->m_audioWindowIndex > 0 && this->m_numReusedFeatureVectors > 0;
-
- /* Start calculating features inside one audio sliding window. */
- while (this->m_melWindowSlider.HasNext()) {
- const int16_t* melSpecWindow = this->m_melWindowSlider.Next();
- std::vector<int16_t> melSpecAudioData = std::vector<int16_t>(
- melSpecWindow,
- melSpecWindow + this->m_melSpectrogramFrameLen);
-
- /* Compute features for this window and write them to input tensor. */
- this->m_featureCalc(melSpecAudioData,
- this->m_melWindowSlider.Index(),
- useCache,
- this->m_numMelSpecVectorsInAudioStride,
- this->m_inputResizeScale);
- }
-
- return true;
-}
-
-uint32_t AdPreProcess::GetAudioWindowSize()
-{
- return this->m_audioDataWindowSize;
-}
-
-uint32_t AdPreProcess::GetAudioDataStride()
-{
- return this->m_audioDataStride;
-}
-
-void AdPreProcess::SetAudioWindowIndex(uint32_t idx)
-{
- this->m_audioWindowIndex = idx;
-}
-
-AdPostProcess::AdPostProcess(TfLiteTensor* outputTensor) :
- m_outputTensor {outputTensor}
-{}
-
-bool AdPostProcess::DoPostProcess()
-{
- switch (this->m_outputTensor->type) {
- case kTfLiteInt8:
- this->Dequantize<int8_t>();
- break;
- default:
- printf_err("Unsupported tensor type");
- return false;
- }
-
- math::MathUtils::SoftmaxF32(this->m_dequantizedOutputVec);
- return true;
-}
-
-float AdPostProcess::GetOutputValue(uint32_t index)
-{
- if (index < this->m_dequantizedOutputVec.size()) {
- return this->m_dequantizedOutputVec[index];
- }
- printf_err("Invalid index for output\n");
- return 0.0;
-}
-
-std::function<void (std::vector<int16_t>&, int, bool, size_t, size_t)>
-GetFeatureCalculator(audio::AdMelSpectrogram& melSpec,
- TfLiteTensor* inputTensor,
- size_t cacheSize,
- float trainingMean)
-{
- std::function<void (std::vector<int16_t>&, size_t, bool, size_t, size_t)> melSpecFeatureCalc;
-
- TfLiteQuantization quant = inputTensor->quantization;
-
- if (kTfLiteAffineQuantization == quant.type) {
-
- auto* quantParams = static_cast<TfLiteAffineQuantization*>(quant.params);
- const float quantScale = quantParams->scale->data[0];
- const int quantOffset = quantParams->zero_point->data[0];
-
- switch (inputTensor->type) {
- case kTfLiteInt8: {
- melSpecFeatureCalc = FeatureCalc<int8_t>(
- inputTensor,
- cacheSize,
- [=, &melSpec](std::vector<int16_t>& audioDataWindow) {
- return melSpec.MelSpecComputeQuant<int8_t>(
- audioDataWindow,
- quantScale,
- quantOffset,
- trainingMean);
- }
- );
- break;
- }
- default:
- printf_err("Tensor type %s not supported\n", TfLiteTypeGetName(inputTensor->type));
- }
- } else {
- melSpecFeatureCalc = FeatureCalc<float>(
- inputTensor,
- cacheSize,
- [=, &melSpec](
- std::vector<int16_t>& audioDataWindow) {
- return melSpec.ComputeMelSpec(
- audioDataWindow,
- trainingMean);
- });
- }
- return melSpecFeatureCalc;
-}
-
-} /* namespace app */
-} /* namespace arm */
diff --git a/source/use_case/ad/src/MainLoop.cc b/source/use_case/ad/src/MainLoop.cc
index 140359b..e9f7b4e 100644
--- a/source/use_case/ad/src/MainLoop.cc
+++ b/source/use_case/ad/src/MainLoop.cc
@@ -18,7 +18,17 @@
#include "AdModel.hpp" /* Model class for running inference */
#include "UseCaseCommonUtils.hpp" /* Utils functions */
#include "UseCaseHandler.hpp" /* Handlers for different user options */
-#include "log_macros.h"
+#include "log_macros.h" /* Logging functions */
+#include "BufAttributes.hpp" /* Buffer attributes to be applied */
+
+namespace arm {
+ namespace app {
+ static uint8_t tensorArena[ACTIVATION_BUF_SZ] ACTIVATION_BUF_ATTRIBUTE;
+ } /* namespace app */
+} /* namespace arm */
+
+extern uint8_t* GetModelPointer();
+extern size_t GetModelLen();
enum opcodes
{
@@ -49,12 +59,23 @@ void main_loop()
arm::app::AdModel model; /* Model wrapper object. */
/* Load the model. */
- if (!model.Init())
+ if (!model.Init(arm::app::tensorArena,
+ sizeof(arm::app::tensorArena),
+ GetModelPointer(),
+ GetModelLen()))
{
printf_err("failed to initialise model\n");
return;
}
+#if !defined(ARM_NPU)
+ /* If it is not a NPU build check if the model contains a NPU operator */
+ if (model.ContainsEthosUOperator()) {
+ printf_err("No driver support for Ethos-U operator found in the model.\n");
+ return;
+ }
+#endif /* ARM_NPU */
+
/* Instantiate application context. */
arm::app::ApplicationContext caseContext;
diff --git a/source/use_case/ad/src/MelSpectrogram.cc b/source/use_case/ad/src/MelSpectrogram.cc
deleted file mode 100644
index ff0c536..0000000
--- a/source/use_case/ad/src/MelSpectrogram.cc
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (c) 2021 Arm Limited. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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 "MelSpectrogram.hpp"
-
-#include "PlatformMath.hpp"
-#include "log_macros.h"
-
-#include <cfloat>
-#include <cinttypes>
-
-namespace arm {
-namespace app {
-namespace audio {
-
- MelSpecParams::MelSpecParams(
- const float samplingFreq,
- const uint32_t numFbankBins,
- const float melLoFreq,
- const float melHiFreq,
- const uint32_t frameLen,
- const bool useHtkMethod):
- m_samplingFreq(samplingFreq),
- m_numFbankBins(numFbankBins),
- m_melLoFreq(melLoFreq),
- m_melHiFreq(melHiFreq),
- m_frameLen(frameLen),
-
- /* Smallest power of 2 >= frame length. */
- m_frameLenPadded(pow(2, ceil((log(frameLen)/log(2))))),
- m_useHtkMethod(useHtkMethod)
- {}
-
- std::string MelSpecParams::Str() const
- {
- char strC[1024];
- snprintf(strC, sizeof(strC) - 1, "\n \
- \n\t Sampling frequency: %f\
- \n\t Number of filter banks: %" PRIu32 "\
- \n\t Mel frequency limit (low): %f\
- \n\t Mel frequency limit (high): %f\
- \n\t Frame length: %" PRIu32 "\
- \n\t Padded frame length: %" PRIu32 "\
- \n\t Using HTK for Mel scale: %s\n",
- this->m_samplingFreq, this->m_numFbankBins, this->m_melLoFreq,
- this->m_melHiFreq, this->m_frameLen,
- this->m_frameLenPadded, this->m_useHtkMethod ? "yes" : "no");
- return std::string{strC};
- }
-
- MelSpectrogram::MelSpectrogram(const MelSpecParams& params):
- m_params(params),
- m_filterBankInitialised(false)
- {
- this->m_buffer = std::vector<float>(
- this->m_params.m_frameLenPadded, 0.0);
- this->m_frame = std::vector<float>(
- this->m_params.m_frameLenPadded, 0.0);
- this->m_melEnergies = std::vector<float>(
- this->m_params.m_numFbankBins, 0.0);
-
- this->m_windowFunc = std::vector<float>(this->m_params.m_frameLen);
- const auto multiplier = static_cast<float>(2 * M_PI / this->m_params.m_frameLen);
-
- /* Create window function. */
- for (size_t i = 0; i < this->m_params.m_frameLen; ++i) {
- this->m_windowFunc[i] = (0.5 - (0.5 *
- math::MathUtils::CosineF32(static_cast<float>(i) * multiplier)));
- }
-
- math::MathUtils::FftInitF32(this->m_params.m_frameLenPadded, this->m_fftInstance);
- debug("Instantiated Mel Spectrogram object: %s\n", this->m_params.Str().c_str());
- }
-
- void MelSpectrogram::Init()
- {
- this->InitMelFilterBank();
- }
-
- float MelSpectrogram::MelScale(const float freq, const bool useHTKMethod)
- {
- if (useHTKMethod) {
- return 1127.0f * logf (1.0f + freq / 700.0f);
- } else {
- /* Slaney formula for mel scale. */
- float mel = freq / ms_freqStep;
-
- if (freq >= ms_minLogHz) {
- mel = ms_minLogMel + logf(freq / ms_minLogHz) / ms_logStep;
- }
- return mel;
- }
- }
-
- float MelSpectrogram::InverseMelScale(const float melFreq, const bool useHTKMethod)
- {
- if (useHTKMethod) {
- return 700.0f * (expf (melFreq / 1127.0f) - 1.0f);
- } else {
- /* Slaney formula for inverse mel scale. */
- float freq = ms_freqStep * melFreq;
-
- if (melFreq >= ms_minLogMel) {
- freq = ms_minLogHz * expf(ms_logStep * (melFreq - ms_minLogMel));
- }
- return freq;
- }
- }
-
- bool MelSpectrogram::ApplyMelFilterBank(
- std::vector<float>& fftVec,
- std::vector<std::vector<float>>& melFilterBank,
- std::vector<uint32_t>& filterBankFilterFirst,
- std::vector<uint32_t>& filterBankFilterLast,
- std::vector<float>& melEnergies)
- {
- const size_t numBanks = melEnergies.size();
-
- if (numBanks != filterBankFilterFirst.size() ||
- numBanks != filterBankFilterLast.size()) {
- printf_err("unexpected filter bank lengths\n");
- return false;
- }
-
- for (size_t bin = 0; bin < numBanks; ++bin) {
- auto filterBankIter = melFilterBank[bin].begin();
- auto end = melFilterBank[bin].end();
- float melEnergy = FLT_MIN; /* Avoid log of zero at later stages */
- const uint32_t firstIndex = filterBankFilterFirst[bin];
- const uint32_t lastIndex = std::min<int32_t>(filterBankFilterLast[bin], fftVec.size() - 1);
-
- for (uint32_t i = firstIndex; i <= lastIndex && filterBankIter != end; ++i) {
- float energyRep = math::MathUtils::SqrtF32(fftVec[i]);
- melEnergy += (*filterBankIter++ * energyRep);
- }
-
- melEnergies[bin] = melEnergy;
- }
-
- return true;
- }
-
- void MelSpectrogram::ConvertToLogarithmicScale(std::vector<float>& melEnergies)
- {
- for (float& melEnergy : melEnergies) {
- melEnergy = logf(melEnergy);
- }
- }
-
- void MelSpectrogram::ConvertToPowerSpectrum()
- {
- const uint32_t halfDim = this->m_buffer.size() / 2;
-
- /* Handle this special case. */
- float firstEnergy = this->m_buffer[0] * this->m_buffer[0];
- float lastEnergy = this->m_buffer[1] * this->m_buffer[1];
-
- math::MathUtils::ComplexMagnitudeSquaredF32(
- this->m_buffer.data(),
- this->m_buffer.size(),
- this->m_buffer.data(),
- this->m_buffer.size()/2);
-
- this->m_buffer[0] = firstEnergy;
- this->m_buffer[halfDim] = lastEnergy;
- }
-
- float MelSpectrogram::GetMelFilterBankNormaliser(
- const float& leftMel,
- const float& rightMel,
- const bool useHTKMethod)
- {
- UNUSED(leftMel);
- UNUSED(rightMel);
- UNUSED(useHTKMethod);
-
- /* By default, no normalisation => return 1 */
- return 1.f;
- }
-
- void MelSpectrogram::InitMelFilterBank()
- {
- if (!this->IsMelFilterBankInited()) {
- this->m_melFilterBank = this->CreateMelFilterBank();
- this->m_filterBankInitialised = true;
- }
- }
-
- bool MelSpectrogram::IsMelFilterBankInited() const
- {
- return this->m_filterBankInitialised;
- }
-
- std::vector<float> MelSpectrogram::ComputeMelSpec(const std::vector<int16_t>& audioData, float trainingMean)
- {
- this->InitMelFilterBank();
-
- /* TensorFlow way of normalizing .wav data to (-1, 1). */
- constexpr float normaliser = 1.0/(1<<15);
- for (size_t i = 0; i < this->m_params.m_frameLen; ++i) {
- this->m_frame[i] = static_cast<float>(audioData[i]) * normaliser;
- }
-
- /* Apply window function to input frame. */
- for(size_t i = 0; i < this->m_params.m_frameLen; ++i) {
- this->m_frame[i] *= this->m_windowFunc[i];
- }
-
- /* Set remaining frame values to 0. */
- std::fill(this->m_frame.begin() + this->m_params.m_frameLen,this->m_frame.end(), 0);
-
- /* Compute FFT. */
- math::MathUtils::FftF32(this->m_frame, this->m_buffer, this->m_fftInstance);
-
- /* Convert to power spectrum. */
- this->ConvertToPowerSpectrum();
-
- /* Apply mel filterbanks. */
- if (!this->ApplyMelFilterBank(this->m_buffer,
- this->m_melFilterBank,
- this->m_filterBankFilterFirst,
- this->m_filterBankFilterLast,
- this->m_melEnergies)) {
- printf_err("Failed to apply MEL filter banks\n");
- }
-
- /* Convert to logarithmic scale */
- this->ConvertToLogarithmicScale(this->m_melEnergies);
-
- /* Perform mean subtraction. */
- for (auto& energy:this->m_melEnergies) {
- energy -= trainingMean;
- }
-
- return this->m_melEnergies;
- }
-
- std::vector<std::vector<float>> MelSpectrogram::CreateMelFilterBank()
- {
- size_t numFftBins = this->m_params.m_frameLenPadded / 2;
- float fftBinWidth = static_cast<float>(this->m_params.m_samplingFreq) / this->m_params.m_frameLenPadded;
-
- float melLowFreq = MelSpectrogram::MelScale(this->m_params.m_melLoFreq,
- this->m_params.m_useHtkMethod);
- float melHighFreq = MelSpectrogram::MelScale(this->m_params.m_melHiFreq,
- this->m_params.m_useHtkMethod);
- float melFreqDelta = (melHighFreq - melLowFreq) / (this->m_params.m_numFbankBins + 1);
-
- std::vector<float> thisBin = std::vector<float>(numFftBins);
- std::vector<std::vector<float>> melFilterBank(
- this->m_params.m_numFbankBins);
- this->m_filterBankFilterFirst =
- std::vector<uint32_t>(this->m_params.m_numFbankBins);
- this->m_filterBankFilterLast =
- std::vector<uint32_t>(this->m_params.m_numFbankBins);
-
- for (size_t bin = 0; bin < this->m_params.m_numFbankBins; bin++) {
- float leftMel = melLowFreq + bin * melFreqDelta;
- float centerMel = melLowFreq + (bin + 1) * melFreqDelta;
- float rightMel = melLowFreq + (bin + 2) * melFreqDelta;
-
- uint32_t firstIndex = 0;
- uint32_t lastIndex = 0;
- bool firstIndexFound = false;
- const float normaliser = this->GetMelFilterBankNormaliser(leftMel, rightMel, this->m_params.m_useHtkMethod);
-
- for (size_t i = 0; i < numFftBins; ++i) {
- float freq = (fftBinWidth * i); /* Center freq of this fft bin. */
- float mel = MelSpectrogram::MelScale(freq, this->m_params.m_useHtkMethod);
- thisBin[i] = 0.0;
-
- if (mel > leftMel && mel < rightMel) {
- float weight;
- if (mel <= centerMel) {
- weight = (mel - leftMel) / (centerMel - leftMel);
- } else {
- weight = (rightMel - mel) / (rightMel - centerMel);
- }
-
- thisBin[i] = weight * normaliser;
- if (!firstIndexFound) {
- firstIndex = i;
- firstIndexFound = true;
- }
- lastIndex = i;
- }
- }
-
- this->m_filterBankFilterFirst[bin] = firstIndex;
- this->m_filterBankFilterLast[bin] = lastIndex;
-
- /* Copy the part we care about. */
- for (uint32_t i = firstIndex; i <= lastIndex; ++i) {
- melFilterBank[bin].push_back(thisBin[i]);
- }
- }
-
- return melFilterBank;
- }
-
-} /* namespace audio */
-} /* namespace app */
-} /* namespace arm */
diff --git a/source/use_case/ad/usecase.cmake b/source/use_case/ad/usecase.cmake
index 23b4c32..06d7681 100644
--- a/source/use_case/ad/usecase.cmake
+++ b/source/use_case/ad/usecase.cmake
@@ -15,6 +15,9 @@
# limitations under the License.
#----------------------------------------------------------------------------
+# Append the API to use for this use case
+list(APPEND ${use_case}_API_LIST "ad")
+
USER_OPTION(${use_case}_FILE_PATH "Directory with custom WAV input files, or path to a single input WAV file, to use in the evaluation application."
${CMAKE_CURRENT_SOURCE_DIR}/resources/${use_case}/samples/
PATH_OR_FILE)