From c350cdced0a8a2ca17376f58813e6d48d796ac7c Mon Sep 17 00:00:00 2001 From: alexander Date: Thu, 29 Apr 2021 20:36:09 +0100 Subject: MLECO-1868: Code static analyzer warnings fixes Signed-off-by: alexander Change-Id: Ie423e9cad3fabec6ab077ded7236813fe4933dea --- docs/sections/customizing.md | 4 +- source/application/hal/hal.c | 22 ++-- source/application/main/Classifier.cc | 117 ++++++++------------ source/application/main/Mfcc.cc | 61 ++++++----- source/application/main/PlatformMath.cc | 4 +- source/application/main/Profiler.cc | 6 +- source/application/main/include/Classifier.hpp | 2 +- source/application/main/include/DataStructures.hpp | 4 +- source/application/main/include/Mfcc.hpp | 24 ++--- source/application/main/include/Profiler.hpp | 4 +- source/application/tensorflow-lite-micro/Model.cc | 4 +- source/use_case/ad/include/AdMelSpectrogram.hpp | 4 +- source/use_case/ad/include/AdModel.hpp | 4 +- source/use_case/ad/include/MelSpectrogram.hpp | 22 ++-- source/use_case/ad/src/AdMelSpectrogram.cc | 17 +-- source/use_case/ad/src/MelSpectrogram.cc | 53 ++++----- source/use_case/ad/src/UseCaseHandler.cc | 113 +++++++++---------- source/use_case/asr/include/AsrClassifier.hpp | 6 +- source/use_case/asr/include/Wav2LetterMfcc.hpp | 4 +- source/use_case/asr/include/Wav2LetterModel.hpp | 4 +- .../use_case/asr/include/Wav2LetterPostprocess.hpp | 18 ++-- .../use_case/asr/include/Wav2LetterPreprocess.hpp | 38 +++---- source/use_case/asr/src/AsrClassifier.cc | 39 ++++--- source/use_case/asr/src/UseCaseHandler.cc | 20 ++-- source/use_case/asr/src/Wav2LetterMfcc.cc | 23 ++-- source/use_case/asr/src/Wav2LetterPostprocess.cc | 32 +++--- source/use_case/asr/src/Wav2LetterPreprocess.cc | 38 +++---- .../use_case/img_class/include/MobileNetModel.hpp | 4 +- source/use_case/img_class/src/UseCaseHandler.cc | 28 ++--- source/use_case/kws/include/DsCnnModel.hpp | 4 +- source/use_case/kws/src/UseCaseHandler.cc | 88 +++++++-------- source/use_case/kws_asr/include/AsrClassifier.hpp | 6 +- source/use_case/kws_asr/include/DsCnnModel.hpp | 4 +- source/use_case/kws_asr/include/Wav2LetterMfcc.hpp | 5 +- .../use_case/kws_asr/include/Wav2LetterModel.hpp | 4 +- .../kws_asr/include/Wav2LetterPostprocess.hpp | 12 +-- .../kws_asr/include/Wav2LetterPreprocess.hpp | 38 +++---- source/use_case/kws_asr/src/AsrClassifier.cc | 40 +++---- source/use_case/kws_asr/src/UseCaseHandler.cc | 120 ++++++++++----------- source/use_case/kws_asr/src/Wav2LetterMfcc.cc | 23 ++-- .../use_case/kws_asr/src/Wav2LetterPostprocess.cc | 19 ++-- .../use_case/kws_asr/src/Wav2LetterPreprocess.cc | 38 +++---- tests/common/ClassifierTests.cc | 81 +++++++------- tests/use_case/asr/AsrClassifierTests.cc | 4 +- tests/use_case/asr/AsrFeaturesTests.cc | 38 +++---- 45 files changed, 622 insertions(+), 621 deletions(-) diff --git a/docs/sections/customizing.md b/docs/sections/customizing.md index 323ffb5..b4b5bba 100644 --- a/docs/sections/customizing.md +++ b/docs/sections/customizing.md @@ -410,10 +410,10 @@ class HelloWorldModel: public Model { private: /* Maximum number of individual operations that can be enlisted. */ - static constexpr int _ms_maxOpCnt = 5; + static constexpr int ms_maxOpCnt = 5; /* A mutable op resolver instance. */ - tflite::MicroMutableOpResolver<_ms_maxOpCnt> _m_opResolver; + tflite::MicroMutableOpResolver _m_opResolver; }; } /* namespace app */ } /* namespace arm */ diff --git a/source/application/hal/hal.c b/source/application/hal/hal.c index dbf94ba..9c2ce32 100644 --- a/source/application/hal/hal.c +++ b/source/application/hal/hal.c @@ -32,7 +32,7 @@ * @brief Initialises the Arm Ethos-U55 NPU * @return 0 if successful, error code otherwise **/ -static int _arm_npu_init(void); +static int arm_npu_init(void); #endif /* ARM_NPU */ @@ -54,7 +54,7 @@ int hal_init(hal_platform* platform, data_acq_module* data_acq, /** * @brief Local helper function to clean the slate for current platform. **/ -static void _hal_platform_clear(hal_platform* platform) +static void hal_platform_clear(hal_platform* platform) { assert(platform); platform->inited = 0; @@ -64,7 +64,7 @@ int hal_platform_init(hal_platform* platform) { int state; assert(platform && platform->platform_init); - _hal_platform_clear(platform); + hal_platform_clear(platform); /* Initialise platform */ if (0 != (state = platform->platform_init())) { @@ -94,7 +94,7 @@ int hal_platform_init(hal_platform* platform) #if defined(ARM_NPU) /* If Arm Ethos-U55 NPU is to be used, we initialise it here */ - if (0 != (state = _arm_npu_init())) { + if (0 != (state = arm_npu_init())) { return state; } @@ -120,7 +120,7 @@ void hal_platform_release(hal_platform *platform) data_acq_channel_release(platform->data_acq); data_psn_system_release(platform->data_psn); - _hal_platform_clear(platform); + hal_platform_clear(platform); info("releasing platform %s\n", platform->plat_name); platform->platform_release(); } @@ -130,7 +130,7 @@ void hal_platform_release(hal_platform *platform) * @brief Defines the Ethos-U interrupt handler: just a wrapper around the default * implementation. **/ -static void _arm_npu_irq_handler(void) +static void arm_npu_irq_handler(void) { /* Call the default interrupt handler from the NPU driver */ ethosu_irq_handler(); @@ -139,19 +139,19 @@ static void _arm_npu_irq_handler(void) /** * @brief Initialises the NPU IRQ **/ -static void _arm_npu_irq_init(void) +static void arm_npu_irq_init(void) { const IRQn_Type ethosu_irqnum = (IRQn_Type)EthosU_IRQn; /* Register the EthosU IRQ handler in our vector table. * Note, this handler comes from the EthosU driver */ - NVIC_SetVector(ethosu_irqnum, (uint32_t)_arm_npu_irq_handler); + NVIC_SetVector(ethosu_irqnum, (uint32_t)arm_npu_irq_handler); /* Enable the IRQ */ NVIC_EnableIRQ(ethosu_irqnum); debug("EthosU IRQ#: %u, Handler: 0x%p\n", - ethosu_irqnum, _arm_npu_irq_handler); + ethosu_irqnum, arm_npu_irq_handler); } static int _arm_npu_timing_adapter_init(void) @@ -213,7 +213,7 @@ static int _arm_npu_timing_adapter_init(void) return 0; } -static int _arm_npu_init(void) +static int arm_npu_init(void) { int err = 0; @@ -224,7 +224,7 @@ static int _arm_npu_init(void) } /* Initialise the IRQ */ - _arm_npu_irq_init(); + arm_npu_irq_init(); /* Initialise Ethos-U55 device */ const void * ethosu_base_address = (void *)(SEC_ETHOS_U55_BASE); diff --git a/source/application/main/Classifier.cc b/source/application/main/Classifier.cc index bc2c378..9a47f3d 100644 --- a/source/application/main/Classifier.cc +++ b/source/application/main/Classifier.cc @@ -28,69 +28,52 @@ namespace arm { namespace app { template - bool Classifier::_GetTopNResults(TfLiteTensor* tensor, - std::vector& vecResults, - uint32_t topNCount, - const std::vector & labels) - { - std::set> sortedSet; - - /* NOTE: inputVec's size verification against labels should be - * checked by the calling/public function. */ - T* tensorData = tflite::GetTensorData(tensor); - - /* Set initial elements. */ - for (uint32_t i = 0; i < topNCount; ++i) { - sortedSet.insert({tensorData[i], i}); - } - - /* Initialise iterator. */ - auto setFwdIter = sortedSet.begin(); - - /* Scan through the rest of elements with compare operations. */ - for (uint32_t i = topNCount; i < labels.size(); ++i) { - if (setFwdIter->first < tensorData[i]) { - sortedSet.erase(*setFwdIter); - sortedSet.insert({tensorData[i], i}); - setFwdIter = sortedSet.begin(); - } - } - - /* Final results' container. */ - vecResults = std::vector(topNCount); + void SetVectorResults(std::set>& topNSet, + std::vector& vecResults, + TfLiteTensor* tensor, + const std::vector & labels) { /* For getting the floating point values, we need quantization parameters. */ QuantParams quantParams = GetTensorQuantParams(tensor); /* Reset the iterator to the largest element - use reverse iterator. */ - auto setRevIter = sortedSet.rbegin(); - - /* Populate results - * Note: we could combine this loop with the loop above, but that - * would, involve more multiplications and other operations. - **/ - for (size_t i = 0; i < vecResults.size(); ++i, ++setRevIter) { - double score = static_cast (setRevIter->first); - vecResults[i].m_normalisedVal = quantParams.scale * - (score - quantParams.offset); - vecResults[i].m_label = labels[setRevIter->second]; - vecResults[i].m_labelIdx = setRevIter->second; + auto topNIter = topNSet.rbegin(); + for (size_t i = 0; i < vecResults.size() && topNIter != topNSet.rend(); ++i, ++topNIter) { + T score = topNIter->first; + vecResults[i].m_normalisedVal = quantParams.scale * (score - quantParams.offset); + vecResults[i].m_label = labels[topNIter->second]; + vecResults[i].m_labelIdx = topNIter->second; } - return true; } template<> - bool Classifier::_GetTopNResults(TfLiteTensor* tensor, - std::vector& vecResults, - uint32_t topNCount, - const std::vector & labels) + void SetVectorResults(std::set>& topNSet, + std::vector& vecResults, + TfLiteTensor* tensor, + const std::vector & labels) { + UNUSED(tensor); + /* Reset the iterator to the largest element - use reverse iterator. */ + auto topNIter = topNSet.rbegin(); + for (size_t i = 0; i < vecResults.size() && topNIter != topNSet.rend(); ++i, ++topNIter) { + vecResults[i].m_normalisedVal = topNIter->first; + vecResults[i].m_label = labels[topNIter->second]; + vecResults[i].m_labelIdx = topNIter->second; + } + + } + + template + bool Classifier::GetTopNResults(TfLiteTensor* tensor, + std::vector& vecResults, + uint32_t topNCount, + const std::vector & labels) { - std::set> sortedSet; + std::set> sortedSet; /* NOTE: inputVec's size verification against labels should be * checked by the calling/public function. */ - float* tensorData = tflite::GetTensorData(tensor); + T* tensorData = tflite::GetTensorData(tensor); /* Set initial elements. */ for (uint32_t i = 0; i < topNCount; ++i) { @@ -112,29 +95,18 @@ namespace app { /* Final results' container. */ vecResults = std::vector(topNCount); - /* Reset the iterator to the largest element - use reverse iterator. */ - auto setRevIter = sortedSet.rbegin(); - - /* Populate results - * Note: we could combine this loop with the loop above, but that - * would, involve more multiplications and other operations. - **/ - for (size_t i = 0; i < vecResults.size(); ++i, ++setRevIter) { - vecResults[i].m_normalisedVal = setRevIter->first; - vecResults[i].m_label = labels[setRevIter->second]; - vecResults[i].m_labelIdx = setRevIter->second; - } + SetVectorResults(sortedSet, vecResults, tensor, labels); return true; } - template bool Classifier::_GetTopNResults(TfLiteTensor* tensor, - std::vector& vecResults, - uint32_t topNCount, const std::vector & labels); + template bool Classifier::GetTopNResults(TfLiteTensor* tensor, + std::vector& vecResults, + uint32_t topNCount, const std::vector & labels); - template bool Classifier::_GetTopNResults(TfLiteTensor* tensor, - std::vector& vecResults, - uint32_t topNCount, const std::vector & labels); + template bool Classifier::GetTopNResults(TfLiteTensor* tensor, + std::vector& vecResults, + uint32_t topNCount, const std::vector & labels); bool Classifier::GetClassificationResults( TfLiteTensor* outputTensor, @@ -158,6 +130,9 @@ namespace app { } else if (totalOutputSize != labels.size()) { printf_err("Output size doesn't match the labels' size\n"); return false; + } else if (topNCount == 0) { + printf_err("Top N results cannot be zero\n"); + return false; } bool resultState; @@ -166,13 +141,13 @@ namespace app { /* Get the top N results. */ switch (outputTensor->type) { case kTfLiteUInt8: - resultState = _GetTopNResults(outputTensor, vecResults, topNCount, labels); + resultState = GetTopNResults(outputTensor, vecResults, topNCount, labels); break; case kTfLiteInt8: - resultState = _GetTopNResults(outputTensor, vecResults, topNCount, labels); + resultState = GetTopNResults(outputTensor, vecResults, topNCount, labels); break; case kTfLiteFloat32: - resultState = _GetTopNResults(outputTensor, vecResults, topNCount, labels); + resultState = GetTopNResults(outputTensor, vecResults, topNCount, labels); break; default: printf_err("Tensor type %s not supported by classifier\n", TfLiteTypeGetName(outputTensor->type)); @@ -180,7 +155,7 @@ namespace app { } if (!resultState) { - printf_err("Failed to get sorted set\n"); + printf_err("Failed to get top N results set\n"); return false; } diff --git a/source/application/main/Mfcc.cc b/source/application/main/Mfcc.cc index bf16159..9ddcb5d 100644 --- a/source/application/main/Mfcc.cc +++ b/source/application/main/Mfcc.cc @@ -44,7 +44,7 @@ namespace audio { m_useHtkMethod(useHtkMethod) {} - std::string MfccParams::Str() + std::string MfccParams::Str() const { char strC[1024]; snprintf(strC, sizeof(strC) - 1, "\n \ @@ -74,7 +74,7 @@ namespace audio { this->_m_params.m_numFbankBins, 0.0); this->_m_windowFunc = std::vector(this->_m_params.m_frameLen); - const float multiplier = 2 * M_PI / this->_m_params.m_frameLen; + const auto multiplier = static_cast(2 * M_PI / this->_m_params.m_frameLen); /* Create window function. */ for (size_t i = 0; i < this->_m_params.m_frameLen; i++) { @@ -88,7 +88,7 @@ namespace audio { void MFCC::Init() { - this->_InitMelFilterBank(); + this->InitMelFilterBank(); } float MFCC::MelScale(const float freq, const bool useHTKMethod) @@ -126,8 +126,8 @@ namespace audio { bool MFCC::ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) { const size_t numBanks = melEnergies.size(); @@ -140,11 +140,12 @@ namespace audio { 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 */ - int32_t firstIndex = filterBankFilterFirst[bin]; - int32_t lastIndex = filterBankFilterLast[bin]; + const uint32_t firstIndex = filterBankFilterFirst[bin]; + const uint32_t lastIndex = std::min(filterBankFilterLast[bin], fftVec.size() - 1); - for (int i = firstIndex; i <= lastIndex; i++) { + for (uint32_t i = firstIndex; i <= lastIndex && filterBankIter != end; i++) { float energyRep = math::MathUtils::SqrtF32(fftVec[i]); melEnergy += (*filterBankIter++ * energyRep); } @@ -157,14 +158,14 @@ namespace audio { void MFCC::ConvertToLogarithmicScale(std::vector& melEnergies) { - for (size_t bin = 0; bin < melEnergies.size(); ++bin) { - melEnergies[bin] = logf(melEnergies[bin]); + for (float& melEnergy : melEnergies) { + melEnergy = logf(melEnergy); } } - void MFCC::_ConvertToPowerSpectrum() + void MFCC::ConvertToPowerSpectrum() { - const uint32_t halfDim = this->_m_params.m_frameLenPadded / 2; + const uint32_t halfDim = this->_m_buffer.size() / 2; /* Handle this special case. */ float firstEnergy = this->_m_buffer[0] * this->_m_buffer[0]; @@ -193,7 +194,7 @@ namespace audio { for (int32_t k = 0, m = 0; k < coefficientCount; k++, m += inputLength) { for (int32_t n = 0; n < inputLength; n++) { dctMatix[m+n] = normalizer * - math::MathUtils::CosineF32((n + 0.5) * angle); + math::MathUtils::CosineF32((n + 0.5f) * angle); } angle += angleIncr; } @@ -214,10 +215,10 @@ namespace audio { return 1.f; } - void MFCC::_InitMelFilterBank() + void MFCC::InitMelFilterBank() { - if (!this->_IsMelFilterBankInited()) { - this->_m_melFilterBank = this->_CreateMelFilterBank(); + if (!this->IsMelFilterBankInited()) { + this->_m_melFilterBank = this->CreateMelFilterBank(); this->_m_dctMatrix = this->CreateDCTMatrix( this->_m_params.m_numFbankBins, this->_m_params.m_numMfccFeatures); @@ -225,17 +226,17 @@ namespace audio { } } - bool MFCC::_IsMelFilterBankInited() + bool MFCC::IsMelFilterBankInited() const { return this->_m_filterBankInitialised; } - void MFCC::_MfccComputePreFeature(const std::vector& audioData) + void MFCC::MfccComputePreFeature(const std::vector& audioData) { - this->_InitMelFilterBank(); + this->InitMelFilterBank(); /* TensorFlow way of normalizing .wav data to (-1, 1). */ - constexpr float normaliser = 1.0/(1<<15); + constexpr float normaliser = 1.0/(1u<<15u); for (size_t i = 0; i < this->_m_params.m_frameLen; i++) { this->_m_frame[i] = static_cast(audioData[i]) * normaliser; } @@ -252,7 +253,7 @@ namespace audio { math::MathUtils::FftF32(this->_m_frame, this->_m_buffer, this->_m_fftInstance); /* Convert to power spectrum. */ - this->_ConvertToPowerSpectrum(); + this->ConvertToPowerSpectrum(); /* Apply mel filterbanks. */ if (!this->ApplyMelFilterBank(this->_m_buffer, @@ -269,7 +270,7 @@ namespace audio { std::vector MFCC::MfccCompute(const std::vector& audioData) { - this->_MfccComputePreFeature(audioData); + this->MfccComputePreFeature(audioData); std::vector mfccOut(this->_m_params.m_numMfccFeatures); @@ -288,7 +289,7 @@ namespace audio { return mfccOut; } - std::vector> MFCC::_CreateMelFilterBank() + std::vector> MFCC::CreateMelFilterBank() { size_t numFftBins = this->_m_params.m_frameLenPadded / 2; float fftBinWidth = static_cast(this->_m_params.m_samplingFreq) / this->_m_params.m_frameLenPadded; @@ -303,17 +304,18 @@ namespace audio { std::vector> melFilterBank( this->_m_params.m_numFbankBins); this->_m_filterBankFilterFirst = - std::vector(this->_m_params.m_numFbankBins); + std::vector(this->_m_params.m_numFbankBins); this->_m_filterBankFilterLast = - std::vector(this->_m_params.m_numFbankBins); + std::vector(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; - int32_t firstIndex = -1; - int32_t lastIndex = -1; + 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++) { @@ -330,8 +332,9 @@ namespace audio { } thisBin[i] = weight * normaliser; - if (firstIndex == -1) { + if (!firstIndexFound) { firstIndex = i; + firstIndexFound = true; } lastIndex = i; } @@ -341,7 +344,7 @@ namespace audio { this->_m_filterBankFilterLast[bin] = lastIndex; /* Copy the part we care about. */ - for (int32_t i = firstIndex; i <= lastIndex; i++) { + for (uint32_t i = firstIndex; i <= lastIndex; i++) { melFilterBank[bin].push_back(thisBin[i]); } } diff --git a/source/application/main/PlatformMath.cc b/source/application/main/PlatformMath.cc index a9f5049..9d18151 100644 --- a/source/application/main/PlatformMath.cc +++ b/source/application/main/PlatformMath.cc @@ -121,7 +121,7 @@ namespace math { float sumReal = 0, sumImag = 0; for (int t = 0; t < inputLength; t++) { - float angle = 2 * M_PI * t * k / inputLength; + auto angle = static_cast(2 * M_PI * t * k / inputLength); sumReal += input[t] * cosf(angle); sumImag += -input[t] * sinf(angle); } @@ -147,7 +147,7 @@ namespace math { output.size()); #else /* ARM_DSP_AVAILABLE */ for (auto in = input.begin(), out = output.begin(); - in != input.end(); ++in, ++out) { + in != input.end() && out != output.end(); ++in, ++out) { *out = logf(*in); } #endif /* ARM_DSP_AVAILABLE */ diff --git a/source/application/main/Profiler.cc b/source/application/main/Profiler.cc index 0456ba4..10a828a 100644 --- a/source/application/main/Profiler.cc +++ b/source/application/main/Profiler.cc @@ -54,7 +54,7 @@ namespace app { this->_m_tstampEnd = this->_m_pPlatform->timer->stop_profiling(); this->_m_started = false; - this->_AddProfilingUnit(this->_m_tstampSt, this->_m_tstampEnd, this->_m_name); + this->AddProfilingUnit(this->_m_tstampSt, this->_m_tstampEnd, this->_m_name); return true; } @@ -238,8 +238,8 @@ namespace app { this->_m_name = std::string(str); } - void Profiler::_AddProfilingUnit(time_counter start, time_counter end, - const std::string& name) + void Profiler::AddProfilingUnit(time_counter start, time_counter end, + const std::string& name) { platform_timer * timer = this->_m_pPlatform->timer; diff --git a/source/application/main/include/Classifier.hpp b/source/application/main/include/Classifier.hpp index 510e6f9..3ee3148 100644 --- a/source/application/main/include/Classifier.hpp +++ b/source/application/main/include/Classifier.hpp @@ -62,7 +62,7 @@ namespace app { * @return true if successful, false otherwise. **/ template - bool _GetTopNResults(TfLiteTensor* tensor, + bool GetTopNResults(TfLiteTensor* tensor, std::vector& vecResults, uint32_t topNCount, const std::vector & labels); diff --git a/source/application/main/include/DataStructures.hpp b/source/application/main/include/DataStructures.hpp index 5cc8b5e..2f267c0 100644 --- a/source/application/main/include/DataStructures.hpp +++ b/source/application/main/include/DataStructures.hpp @@ -47,15 +47,13 @@ namespace app { * @param[in] rows Number of rows. * @param[in] cols Number of columns. */ - Array2d(unsigned rows, unsigned cols) + Array2d(unsigned rows, unsigned cols): _m_rows(rows), _m_cols(cols) { if (rows == 0 || cols == 0) { printf_err("Array2d constructor has 0 size.\n"); _m_data = nullptr; return; } - _m_rows = rows; - _m_cols = cols; _m_data = new T[rows * cols]; } diff --git a/source/application/main/include/Mfcc.hpp b/source/application/main/include/Mfcc.hpp index 6379fab..dcafe62 100644 --- a/source/application/main/include/Mfcc.hpp +++ b/source/application/main/include/Mfcc.hpp @@ -52,7 +52,7 @@ namespace audio { ~MfccParams() = default; /** @brief String representation of parameters */ - std::string Str(); + std::string Str() const; }; /** @@ -100,7 +100,7 @@ namespace audio { const float quantScale, const int quantOffset) { - this->_MfccComputePreFeature(audioData); + this->MfccComputePreFeature(audioData); float minVal = std::numeric_limits::min(); float maxVal = std::numeric_limits::max(); @@ -154,7 +154,7 @@ namespace audio { * 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). + * 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 @@ -168,8 +168,8 @@ namespace audio { virtual bool ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies); /** @@ -214,37 +214,37 @@ namespace audio { std::vector _m_windowFunc; std::vector> _m_melFilterBank; std::vector _m_dctMatrix; - std::vector _m_filterBankFilterFirst; - std::vector _m_filterBankFilterLast; + std::vector _m_filterBankFilterFirst; + std::vector _m_filterBankFilterLast; bool _m_filterBankInitialised; arm::app::math::FftInstance _m_fftInstance; /** * @brief Initialises the filter banks and the DCT matrix. **/ - void _InitMelFilterBank(); + void InitMelFilterBank(); /** * @brief Signals whether the instance of MFCC has had its * required buffers initialised. * @return true if initialised, false otherwise. **/ - bool _IsMelFilterBankInited(); + bool IsMelFilterBankInited() const; /** * @brief Create mel filter banks for MFCC calculation. * @return 2D vector of floats. **/ - std::vector> _CreateMelFilterBank(); + std::vector> CreateMelFilterBank(); /** * @brief Computes and populates internal memeber buffers used * in MFCC feature calculation * @param[in] audioData 1D vector of 16-bit audio data. */ - void _MfccComputePreFeature(const std::vector& audioData); + void MfccComputePreFeature(const std::vector& audioData); /** @brief Computes the magnitude from an interleaved complex array. */ - void _ConvertToPowerSpectrum(); + void ConvertToPowerSpectrum(); }; diff --git a/source/application/main/include/Profiler.hpp b/source/application/main/include/Profiler.hpp index d93b257..c5f77e7 100644 --- a/source/application/main/include/Profiler.hpp +++ b/source/application/main/include/Profiler.hpp @@ -125,8 +125,8 @@ namespace app { * @param[in] name Name for the profiling unit series to be * appended to. **/ - void _AddProfilingUnit(time_counter start, time_counter end, - const std::string& name); + void AddProfilingUnit(time_counter start, time_counter end, + const std::string& name); }; } /* namespace app */ diff --git a/source/application/tensorflow-lite-micro/Model.cc b/source/application/tensorflow-lite-micro/Model.cc index 0775467..abf97b6 100644 --- a/source/application/tensorflow-lite-micro/Model.cc +++ b/source/application/tensorflow-lite-micro/Model.cc @@ -317,7 +317,7 @@ bool arm::app::Model::ShowModelInfoHandler() } namespace arm { namespace app { - static uint8_t _tensor_arena[ACTIVATION_BUF_SZ] ACTIVATION_BUF_ATTRIBUTE; + static uint8_t tensor_arena[ACTIVATION_BUF_SZ] ACTIVATION_BUF_ATTRIBUTE; } /* namespace app */ } /* namespace arm */ @@ -328,5 +328,5 @@ size_t arm::app::Model::GetActivationBufferSize() uint8_t *arm::app::Model::GetTensorArena() { - return _tensor_arena; + return tensor_arena; } \ No newline at end of file diff --git a/source/use_case/ad/include/AdMelSpectrogram.hpp b/source/use_case/ad/include/AdMelSpectrogram.hpp index cf8a1d4..30a77c1 100644 --- a/source/use_case/ad/include/AdMelSpectrogram.hpp +++ b/source/use_case/ad/include/AdMelSpectrogram.hpp @@ -60,8 +60,8 @@ namespace audio { virtual bool ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) override; /** diff --git a/source/use_case/ad/include/AdModel.hpp b/source/use_case/ad/include/AdModel.hpp index 2d83455..bbdf91c 100644 --- a/source/use_case/ad/include/AdModel.hpp +++ b/source/use_case/ad/include/AdModel.hpp @@ -41,10 +41,10 @@ namespace app { private: /* Maximum number of individual operations that can be enlisted */ - static constexpr int _ms_maxOpCnt = 6; + static constexpr int ms_maxOpCnt = 6; /* A mutable op resolver instance */ - tflite::MicroMutableOpResolver<_ms_maxOpCnt> _m_opResolver; + tflite::MicroMutableOpResolver _m_opResolver; }; } /* namespace app */ diff --git a/source/use_case/ad/include/MelSpectrogram.hpp b/source/use_case/ad/include/MelSpectrogram.hpp index c1dd61e..22b5d29 100644 --- a/source/use_case/ad/include/MelSpectrogram.hpp +++ b/source/use_case/ad/include/MelSpectrogram.hpp @@ -49,7 +49,7 @@ namespace audio { ~MelSpecParams() = default; /** @brief String representation of parameters */ - std::string Str(); + std::string Str() const; }; /** @@ -76,7 +76,7 @@ namespace audio { * @brief Constructor * @param[in] params - Mel Spectrogram parameters */ - MelSpectrogram(const MelSpecParams& params); + explicit MelSpectrogram(const MelSpecParams& params); MelSpectrogram() = delete; ~MelSpectrogram() = default; @@ -148,7 +148,7 @@ namespace audio { * 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). + * 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 @@ -162,8 +162,8 @@ namespace audio { virtual bool ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies); /** @@ -195,33 +195,33 @@ namespace audio { std::vector _m_melEnergies; std::vector _m_windowFunc; std::vector> _m_melFilterBank; - std::vector _m_filterBankFilterFirst; - std::vector _m_filterBankFilterLast; + std::vector _m_filterBankFilterFirst; + std::vector _m_filterBankFilterLast; bool _m_filterBankInitialised; arm::app::math::FftInstance _m_fftInstance; /** * @brief Initialises the filter banks. **/ - void _InitMelFilterBank(); + void InitMelFilterBank(); /** * @brief Signals whether the instance of MelSpectrogram has had its * required buffers initialised * @return True if initialised, false otherwise **/ - bool _IsMelFilterBankInited(); + bool IsMelFilterBankInited() const; /** * @brief Create mel filter banks for Mel Spectrogram calculation. * @return 2D vector of floats **/ - std::vector> _CreateMelFilterBank(); + std::vector> CreateMelFilterBank(); /** * @brief Computes the magnitude from an interleaved complex array **/ - void _ConvertToPowerSpectrum(); + void ConvertToPowerSpectrum(); }; diff --git a/source/use_case/ad/src/AdMelSpectrogram.cc b/source/use_case/ad/src/AdMelSpectrogram.cc index 183c05c..e070eb8 100644 --- a/source/use_case/ad/src/AdMelSpectrogram.cc +++ b/source/use_case/ad/src/AdMelSpectrogram.cc @@ -18,6 +18,8 @@ #include "PlatformMath.hpp" +#include + namespace arm { namespace app { namespace audio { @@ -25,8 +27,8 @@ namespace audio { bool AdMelSpectrogram::ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) { const size_t numBanks = melEnergies.size(); @@ -39,11 +41,12 @@ namespace audio { for (size_t bin = 0; bin < numBanks; ++bin) { auto filterBankIter = melFilterBank[bin].begin(); - float melEnergy = 1e-10; /* Avoid log of zero at later stages. */ - const int32_t firstIndex = filterBankFilterFirst[bin]; - const int32_t lastIndex = filterBankFilterLast[bin]; + 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(filterBankFilterLast[bin], fftVec.size() - 1); - for (int32_t i = firstIndex; i <= lastIndex; ++i) { + for (uint32_t i = firstIndex; i <= lastIndex && filterBankIter != end; ++i) { melEnergy += (*filterBankIter++ * fftVec[i]); } @@ -69,7 +72,7 @@ namespace audio { /* Scale the log values. */ for (auto iterM = melEnergies.begin(), iterL = vecLogEnergies.begin(); - iterM != melEnergies.end(); ++iterM, ++iterL) { + iterM != melEnergies.end() && iterL != vecLogEnergies.end(); ++iterM, ++iterL) { *iterM = *iterL * multiplier; } diff --git a/source/use_case/ad/src/MelSpectrogram.cc b/source/use_case/ad/src/MelSpectrogram.cc index 86d57e6..372ebd8 100644 --- a/source/use_case/ad/src/MelSpectrogram.cc +++ b/source/use_case/ad/src/MelSpectrogram.cc @@ -42,7 +42,7 @@ namespace audio { m_useHtkMethod(useHtkMethod) {} - std::string MelSpecParams::Str() + std::string MelSpecParams::Str() const { char strC[1024]; snprintf(strC, sizeof(strC) - 1, "\n \ @@ -71,7 +71,7 @@ namespace audio { this->_m_params.m_numFbankBins, 0.0); this->_m_windowFunc = std::vector(this->_m_params.m_frameLen); - const float multiplier = 2 * M_PI / this->_m_params.m_frameLen; + const auto multiplier = static_cast(2 * M_PI / this->_m_params.m_frameLen); /* Create window function. */ for (size_t i = 0; i < this->_m_params.m_frameLen; ++i) { @@ -85,7 +85,7 @@ namespace audio { void MelSpectrogram::Init() { - this->_InitMelFilterBank(); + this->InitMelFilterBank(); } float MelSpectrogram::MelScale(const float freq, const bool useHTKMethod) @@ -121,8 +121,8 @@ namespace audio { bool MelSpectrogram::ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) { const size_t numBanks = melEnergies.size(); @@ -135,11 +135,12 @@ namespace audio { 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 */ - int32_t firstIndex = filterBankFilterFirst[bin]; - int32_t lastIndex = filterBankFilterLast[bin]; + const uint32_t firstIndex = filterBankFilterFirst[bin]; + const uint32_t lastIndex = std::min(filterBankFilterLast[bin], fftVec.size() - 1); - for (int i = firstIndex; i <= lastIndex; ++i) { + for (uint32_t i = firstIndex; i <= lastIndex && filterBankIter != end; ++i) { float energyRep = math::MathUtils::SqrtF32(fftVec[i]); melEnergy += (*filterBankIter++ * energyRep); } @@ -152,14 +153,14 @@ namespace audio { void MelSpectrogram::ConvertToLogarithmicScale(std::vector& melEnergies) { - for (size_t bin = 0; bin < melEnergies.size(); ++bin) { - melEnergies[bin] = logf(melEnergies[bin]); + for (float& melEnergy : melEnergies) { + melEnergy = logf(melEnergy); } } - void MelSpectrogram::_ConvertToPowerSpectrum() + void MelSpectrogram::ConvertToPowerSpectrum() { - const uint32_t halfDim = this->_m_params.m_frameLenPadded / 2; + const uint32_t halfDim = this->_m_buffer.size() / 2; /* Handle this special case. */ float firstEnergy = this->_m_buffer[0] * this->_m_buffer[0]; @@ -188,22 +189,22 @@ namespace audio { return 1.f; } - void MelSpectrogram::_InitMelFilterBank() + void MelSpectrogram::InitMelFilterBank() { - if (!this->_IsMelFilterBankInited()) { - this->_m_melFilterBank = this->_CreateMelFilterBank(); + if (!this->IsMelFilterBankInited()) { + this->_m_melFilterBank = this->CreateMelFilterBank(); this->_m_filterBankInitialised = true; } } - bool MelSpectrogram::_IsMelFilterBankInited() + bool MelSpectrogram::IsMelFilterBankInited() const { return this->_m_filterBankInitialised; } std::vector MelSpectrogram::ComputeMelSpec(const std::vector& audioData, float trainingMean) { - this->_InitMelFilterBank(); + this->InitMelFilterBank(); /* TensorFlow way of normalizing .wav data to (-1, 1). */ constexpr float normaliser = 1.0/(1<<15); @@ -223,7 +224,7 @@ namespace audio { math::MathUtils::FftF32(this->_m_frame, this->_m_buffer, this->_m_fftInstance); /* Convert to power spectrum. */ - this->_ConvertToPowerSpectrum(); + this->ConvertToPowerSpectrum(); /* Apply mel filterbanks. */ if (!this->ApplyMelFilterBank(this->_m_buffer, @@ -245,7 +246,7 @@ namespace audio { return this->_m_melEnergies; } - std::vector> MelSpectrogram::_CreateMelFilterBank() + std::vector> MelSpectrogram::CreateMelFilterBank() { size_t numFftBins = this->_m_params.m_frameLenPadded / 2; float fftBinWidth = static_cast(this->_m_params.m_samplingFreq) / this->_m_params.m_frameLenPadded; @@ -260,17 +261,18 @@ namespace audio { std::vector> melFilterBank( this->_m_params.m_numFbankBins); this->_m_filterBankFilterFirst = - std::vector(this->_m_params.m_numFbankBins); + std::vector(this->_m_params.m_numFbankBins); this->_m_filterBankFilterLast = - std::vector(this->_m_params.m_numFbankBins); + std::vector(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; - int32_t firstIndex = -1; - int32_t lastIndex = -1; + 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) { @@ -287,8 +289,9 @@ namespace audio { } thisBin[i] = weight * normaliser; - if (firstIndex == -1) { + if (!firstIndexFound) { firstIndex = i; + firstIndexFound = true; } lastIndex = i; } @@ -298,7 +301,7 @@ namespace audio { this->_m_filterBankFilterLast[bin] = lastIndex; /* Copy the part we care about. */ - for (int32_t i = firstIndex; i <= lastIndex; ++i) { + for (uint32_t i = firstIndex; i <= lastIndex; ++i) { melFilterBank[bin].push_back(thisBin[i]); } } diff --git a/source/use_case/ad/src/UseCaseHandler.cc b/source/use_case/ad/src/UseCaseHandler.cc index 1c15595..8f86966 100644 --- a/source/use_case/ad/src/UseCaseHandler.cc +++ b/source/use_case/ad/src/UseCaseHandler.cc @@ -32,7 +32,7 @@ namespace app { * @brief Helper function to increment current audio clip index * @param[in/out] ctx pointer to the application context object **/ - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx); + static void IncrementAppCtxClipIdx(ApplicationContext& ctx); /** * @brief Helper function to set the audio clip index @@ -40,7 +40,7 @@ namespace app { * @param[in] idx value to be set * @return true if index is set, false otherwise **/ - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); /** * @brief Presents inference results using the data presentation @@ -50,7 +50,7 @@ namespace app { * @param[in] threhsold if larger than this value we have an anomaly * @return true if successful, false otherwise **/ - static bool _PresentInferenceResult(hal_platform& platform, float result, float threshold); + static bool PresentInferenceResult(hal_platform& platform, float result, float threshold); /** * @brief Returns a function to perform feature calculation and populates input tensor data with @@ -87,7 +87,7 @@ namespace app { /* If the request has a valid size, set the audio index */ if (clipIndex < NUMBER_OF_FILES) { - if (!_SetAppCtxClipIdx(ctx, clipIndex)) { + if (!SetAppCtxClipIdx(ctx, clipIndex)) { return false; } } @@ -216,20 +216,20 @@ namespace app { dataPsnTxtInfStartX, dataPsnTxtInfStartY, 0); ctx.Set("result", result); - if (!_PresentInferenceResult(platform, result, scoreThreshold)) { + if (!PresentInferenceResult(platform, result, scoreThreshold)) { return false; } profiler.PrintProfilingResult(); - _IncrementAppCtxClipIdx(ctx); + IncrementAppCtxClipIdx(ctx); } while (runAll && ctx.Get("clipIndex") != startClipIdx); return true; } - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx) + static void IncrementAppCtxClipIdx(ApplicationContext& ctx) { auto curAudioIdx = ctx.Get("clipIndex"); @@ -241,7 +241,7 @@ namespace app { ctx.Set("clipIndex", curAudioIdx); } - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, const uint32_t idx) + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx) { if (idx >= NUMBER_OF_FILES) { printf_err("Invalid idx %u (expected less than %u)\n", @@ -252,7 +252,7 @@ namespace app { return true; } - static bool _PresentInferenceResult(hal_platform& platform, float result, float threshold) + static bool PresentInferenceResult(hal_platform& platform, float result, float threshold) { constexpr uint32_t dataPsnTxtStartX1 = 20; constexpr uint32_t dataPsnTxtStartY1 = 30; @@ -275,7 +275,7 @@ namespace app { platform.data_psn->present_data_text( resultStr.c_str(), resultStr.size(), - dataPsnTxtStartX1, rowIdx1, 0); + dataPsnTxtStartX1, rowIdx1, false); info("%s\n", resultStr.c_str()); @@ -297,8 +297,8 @@ namespace app { */ template std::function&, size_t, bool, size_t, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize, - std::function (std::vector& )> compute) + FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize, + std::function (std::vector& )> compute) { /* Feature cache to be captured by lambda function*/ static std::vector> featureCache = std::vector>(cacheSize); @@ -335,24 +335,24 @@ namespace app { } template std::function&, size_t , bool, size_t, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector&)> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector&)> compute); template std::function&, size_t , bool, size_t, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector&)> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector&)> compute); template std::function&, size_t , bool, size_t, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector&)> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector&)> compute); template std::function&, size_t, bool, size_t, size_t)> - _FeatureCalc(TfLiteTensor *inputTensor, - size_t cacheSize, - std::function(std::vector&)> compute); + FeatureCalc(TfLiteTensor *inputTensor, + size_t cacheSize, + std::function(std::vector&)> compute); static std::function&, int, bool, size_t, size_t)> @@ -370,38 +370,41 @@ namespace app { switch (inputTensor->type) { case kTfLiteInt8: { - melSpecFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &melSpec](std::vector& audioDataWindow) { - return melSpec.MelSpecComputeQuant(audioDataWindow, - quantScale, - quantOffset, - trainingMean); - } + melSpecFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &melSpec](std::vector& audioDataWindow) { + return melSpec.MelSpecComputeQuant( + audioDataWindow, + quantScale, + quantOffset, + trainingMean); + } ); break; } case kTfLiteUInt8: { - melSpecFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &melSpec](std::vector& audioDataWindow) { - return melSpec.MelSpecComputeQuant(audioDataWindow, - quantScale, - quantOffset, - trainingMean); - } + melSpecFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &melSpec](std::vector& audioDataWindow) { + return melSpec.MelSpecComputeQuant( + audioDataWindow, + quantScale, + quantOffset, + trainingMean); + } ); break; } case kTfLiteInt16: { - melSpecFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &melSpec](std::vector& audioDataWindow) { - return melSpec.MelSpecComputeQuant(audioDataWindow, - quantScale, - quantOffset, - trainingMean); - } + melSpecFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &melSpec](std::vector& audioDataWindow) { + return melSpec.MelSpecComputeQuant( + audioDataWindow, + quantScale, + quantOffset, + trainingMean); + } ); break; } @@ -411,12 +414,14 @@ namespace app { } else { - melSpecFeatureCalc = melSpecFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &melSpec](std::vector& audioDataWindow) { - return melSpec.ComputeMelSpec(audioDataWindow, - trainingMean); - }); + melSpecFeatureCalc = melSpecFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &melSpec]( + std::vector& audioDataWindow) { + return melSpec.ComputeMelSpec( + audioDataWindow, + trainingMean); + }); } return melSpecFeatureCalc; } diff --git a/source/use_case/asr/include/AsrClassifier.hpp b/source/use_case/asr/include/AsrClassifier.hpp index 1a63814..2c97a39 100644 --- a/source/use_case/asr/include/AsrClassifier.hpp +++ b/source/use_case/asr/include/AsrClassifier.hpp @@ -51,9 +51,9 @@ namespace app { * @return true if successful, false otherwise. **/ template - bool _GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint); + bool GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint); }; } /* namespace app */ diff --git a/source/use_case/asr/include/Wav2LetterMfcc.hpp b/source/use_case/asr/include/Wav2LetterMfcc.hpp index 3cb43b9..b5a21d3 100644 --- a/source/use_case/asr/include/Wav2LetterMfcc.hpp +++ b/source/use_case/asr/include/Wav2LetterMfcc.hpp @@ -60,8 +60,8 @@ namespace audio { bool ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) override; /** diff --git a/source/use_case/asr/include/Wav2LetterModel.hpp b/source/use_case/asr/include/Wav2LetterModel.hpp index b801e10..4c62578 100644 --- a/source/use_case/asr/include/Wav2LetterModel.hpp +++ b/source/use_case/asr/include/Wav2LetterModel.hpp @@ -49,10 +49,10 @@ namespace app { private: /* Maximum number of individual operations that can be enlisted. */ - static constexpr int _ms_maxOpCnt = 5; + static constexpr int ms_maxOpCnt = 5; /* A mutable op resolver instance. */ - tflite::MicroMutableOpResolver<_ms_maxOpCnt> _m_opResolver; + tflite::MicroMutableOpResolver _m_opResolver; }; } /* namespace app */ diff --git a/source/use_case/asr/include/Wav2LetterPostprocess.hpp b/source/use_case/asr/include/Wav2LetterPostprocess.hpp index 69567a3..e16d35b 100644 --- a/source/use_case/asr/include/Wav2LetterPostprocess.hpp +++ b/source/use_case/asr/include/Wav2LetterPostprocess.hpp @@ -72,33 +72,33 @@ namespace asr { * initialised. * @return true if valid, false otherwise. */ - bool _IsInputValid(TfLiteTensor* tensor, - uint32_t axisIdx) const; + bool IsInputValid(TfLiteTensor* tensor, + const uint32_t axisIdx) const; /** * @brief Gets the tensor data element size in bytes based * on the tensor type. * @return Size in bytes, 0 if not supported. */ - uint32_t _GetTensorElementSize(TfLiteTensor* tensor); + static uint32_t GetTensorElementSize(TfLiteTensor* tensor); /** * @brief Erases sections from the data assuming row-wise * arrangement along the context axis. * @return true if successful, false otherwise. */ - bool _EraseSectionsRowWise(uint8_t* ptrData, - uint32_t strideSzBytes, - bool lastIteration); + bool EraseSectionsRowWise(uint8_t* ptrData, + const uint32_t strideSzBytes, + const bool lastIteration); /** * @brief Erases sections from the data assuming col-wise * arrangement along the context axis. * @return true if successful, false otherwise. */ - bool _EraseSectionsColWise(uint8_t* ptrData, - uint32_t strideSzBytes, - bool lastIteration); + static bool EraseSectionsColWise(const uint8_t* ptrData, + const uint32_t strideSzBytes, + const bool lastIteration); }; } /* namespace asr */ diff --git a/source/use_case/asr/include/Wav2LetterPreprocess.hpp b/source/use_case/asr/include/Wav2LetterPreprocess.hpp index 8a4e0b7..10512b9 100644 --- a/source/use_case/asr/include/Wav2LetterPreprocess.hpp +++ b/source/use_case/asr/include/Wav2LetterPreprocess.hpp @@ -74,16 +74,16 @@ namespace asr { * @param[out] delta2 Result of the second diff computation. * @return true if successful, false otherwise. */ - static bool _ComputeDeltas(Array2d& mfcc, - Array2d& delta1, - Array2d& delta2); + static bool ComputeDeltas(Array2d& mfcc, + Array2d& delta1, + Array2d& delta2); /** * @brief Given a 2D vector of floats, computes the mean. * @param[in] vec Vctor of vector of floats. * @return Mean value. */ - static float _GetMean(Array2d& vec); + static float GetMean(Array2d& vec); /** * @brief Given a 2D vector of floats, computes the stddev. @@ -91,20 +91,20 @@ namespace asr { * @param[in] mean Mean value of the vector passed in. * @return stddev value. */ - static float _GetStdDev(Array2d& vec, - float mean); + static float GetStdDev(Array2d& vec, + const float mean); /** * @brief Given a 2D vector of floats, normalises it using * the mean and the stddev. * @param[in,out] vec Vector of vector of floats. */ - static void _NormaliseVec(Array2d& vec); + static void NormaliseVec(Array2d& vec); /** * @brief Normalises the MFCC and delta buffers. */ - void _Normalise(); + void Normalise(); /** * @brief Given the quantisation and data type limits, computes @@ -116,7 +116,7 @@ namespace asr { * @param[in] maxVal Numerical limit - maximum. * @return Floating point quantised value. */ - static float _GetQuantElem( + static float GetQuantElem( float elem, float quantScale, int quantOffset, @@ -137,7 +137,7 @@ namespace asr { * @param[in] quantOffset Quantisation offset. */ template - bool _Quantise( + bool Quantise( T * outputBuf, const uint32_t outputBufSz, const float quantScale, @@ -161,15 +161,15 @@ namespace asr { /* Need to transpose while copying and concatenating the tensor. */ for (uint32_t j = 0; j < this->_m_numFeatVectors; ++j) { for (uint32_t i = 0; i < this->_m_numMfccFeats; ++i) { - *outputBufMfcc++ = static_cast(Preprocess::_GetQuantElem( - this->_m_mfccBuf(i, j), quantScale, - quantOffset, minVal, maxVal)); - *outputBufD1++ = static_cast(Preprocess::_GetQuantElem( - this->_m_delta1Buf(i, j), quantScale, - quantOffset, minVal, maxVal)); - *outputBufD2++ = static_cast(Preprocess::_GetQuantElem( - this->_m_delta2Buf(i, j), quantScale, - quantOffset, minVal, maxVal)); + *outputBufMfcc++ = static_cast(Preprocess::GetQuantElem( + this->_m_mfccBuf(i, j), quantScale, + quantOffset, minVal, maxVal)); + *outputBufD1++ = static_cast(Preprocess::GetQuantElem( + this->_m_delta1Buf(i, j), quantScale, + quantOffset, minVal, maxVal)); + *outputBufD2++ = static_cast(Preprocess::GetQuantElem( + this->_m_delta2Buf(i, j), quantScale, + quantOffset, minVal, maxVal)); } outputBufMfcc += ptrIncr; outputBufD1 += ptrIncr; diff --git a/source/use_case/asr/src/AsrClassifier.cc b/source/use_case/asr/src/AsrClassifier.cc index 7377d30..df26a7f 100644 --- a/source/use_case/asr/src/AsrClassifier.cc +++ b/source/use_case/asr/src/AsrClassifier.cc @@ -21,13 +21,18 @@ #include "Wav2LetterModel.hpp" template -bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint) +bool arm::app::AsrClassifier::GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint) { const uint32_t nElems = tensor->dims->data[arm::app::Wav2LetterModel::ms_outputRowsIdx]; const uint32_t nLetters = tensor->dims->data[arm::app::Wav2LetterModel::ms_outputColsIdx]; + if (nLetters != labels.size()) { + printf("Output size doesn't match the labels' size\n"); + return false; + } + /* NOTE: tensor's size verification against labels should be * checked by the calling/public function. */ if (nLetters < 1) { @@ -58,12 +63,12 @@ bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, return true; } -template bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint); -template bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint); +template bool arm::app::AsrClassifier::GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint); +template bool arm::app::AsrClassifier::GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint); bool arm::app::AsrClassifier::GetClassificationResults( TfLiteTensor* outputTensor, @@ -104,16 +109,16 @@ bool arm::app::AsrClassifier::GetClassificationResults( switch (outputTensor->type) { case kTfLiteUInt8: - resultState = this->_GetTopResults( - outputTensor, vecResults, - labels, quantParams.scale, - quantParams.offset); + resultState = this->GetTopResults( + outputTensor, vecResults, + labels, quantParams.scale, + quantParams.offset); break; case kTfLiteInt8: - resultState = this->_GetTopResults( - outputTensor, vecResults, - labels, quantParams.scale, - quantParams.offset); + resultState = this->GetTopResults( + outputTensor, vecResults, + labels, quantParams.scale, + quantParams.offset); break; default: printf_err("Tensor type %s not supported by classifier\n", diff --git a/source/use_case/asr/src/UseCaseHandler.cc b/source/use_case/asr/src/UseCaseHandler.cc index 5d3157a..efaefc2 100644 --- a/source/use_case/asr/src/UseCaseHandler.cc +++ b/source/use_case/asr/src/UseCaseHandler.cc @@ -35,7 +35,7 @@ namespace app { * @brief Helper function to increment current audio clip index. * @param[in,out] ctx Pointer to the application context object. **/ - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx); + static void IncrementAppCtxClipIdx(ApplicationContext& ctx); /** * @brief Helper function to set the audio clip index. @@ -43,7 +43,7 @@ namespace app { * @param[in] idx Value to be set. * @return true if index is set, false otherwise. **/ - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); /** * @brief Presents inference results using the data presentation @@ -54,7 +54,7 @@ namespace app { * otherwise, this can be passed in as 0. * @return true if successful, false otherwise. **/ - static bool _PresentInferenceResult( + static bool PresentInferenceResult( hal_platform& platform, const std::vector& results); @@ -71,7 +71,7 @@ namespace app { /* If the request has a valid size, set the audio index. */ if (clipIndex < NUMBER_OF_FILES) { - if (!_SetAppCtxClipIdx(ctx, clipIndex)) { + if (!SetAppCtxClipIdx(ctx, clipIndex)) { return false; } } @@ -207,20 +207,20 @@ namespace app { ctx.Set>("results", results); - if (!_PresentInferenceResult(platform, results)) { + if (!PresentInferenceResult(platform, results)) { return false; } profiler.PrintProfilingResult(); - _IncrementAppCtxClipIdx(ctx); + IncrementAppCtxClipIdx(ctx); } while (runAll && ctx.Get("clipIndex") != startClipIdx); return true; } - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx) + static void IncrementAppCtxClipIdx(ApplicationContext& ctx) { auto curAudioIdx = ctx.Get("clipIndex"); @@ -232,7 +232,7 @@ namespace app { ctx.Set("clipIndex", curAudioIdx); } - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, const uint32_t idx) + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx) { if (idx >= NUMBER_OF_FILES) { printf_err("Invalid idx %u (expected less than %u)\n", @@ -244,8 +244,8 @@ namespace app { return true; } - static bool _PresentInferenceResult(hal_platform& platform, - const std::vector& results) + static bool PresentInferenceResult(hal_platform& platform, + const std::vector& results) { constexpr uint32_t dataPsnTxtStartX1 = 20; constexpr uint32_t dataPsnTxtStartY1 = 60; diff --git a/source/use_case/asr/src/Wav2LetterMfcc.cc b/source/use_case/asr/src/Wav2LetterMfcc.cc index 92c91bc..0eb152a 100644 --- a/source/use_case/asr/src/Wav2LetterMfcc.cc +++ b/source/use_case/asr/src/Wav2LetterMfcc.cc @@ -27,8 +27,8 @@ namespace audio { bool Wav2LetterMFCC::ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) { const size_t numBanks = melEnergies.size(); @@ -41,11 +41,14 @@ namespace audio { for (size_t bin = 0; bin < numBanks; ++bin) { auto filterBankIter = melFilterBank[bin].begin(); - float melEnergy = 1e-10; /* Avoid log of zero at later stages, same value used in librosa. */ - const int32_t firstIndex = filterBankFilterFirst[bin]; - const int32_t lastIndex = filterBankFilterLast[bin]; - - for (int32_t i = firstIndex; i <= lastIndex; ++i) { + auto end = melFilterBank[bin].end(); + /* Avoid log of zero at later stages, same value used in librosa. + * The number was used during our default wav2letter model training. */ + float melEnergy = 1e-10; + const uint32_t firstIndex = filterBankFilterFirst[bin]; + const uint32_t lastIndex = std::min(filterBankFilterLast[bin], fftVec.size() - 1); + + for (uint32_t i = firstIndex; i <= lastIndex && filterBankIter != end; ++i) { melEnergy += (*filterBankIter++ * fftVec[i]); } @@ -73,7 +76,7 @@ namespace audio { /* Scale the log values and get the max. */ for (auto iterM = melEnergies.begin(), iterL = vecLogEnergies.begin(); - iterM != melEnergies.end(); ++iterM, ++iterL) { + iterM != melEnergies.end() && iterL != vecLogEnergies.end(); ++iterM, ++iterL) { *iterM = *iterL * multiplier; @@ -86,8 +89,8 @@ namespace audio { /* Clamp the mel energies. */ constexpr float maxDb = 80.0; const float clampLevelLowdB = maxMelEnergy - maxDb; - for (auto iter = melEnergies.begin(); iter != melEnergies.end(); ++iter) { - *iter = std::max(*iter, clampLevelLowdB); + for (float& melEnergy : melEnergies) { + melEnergy = std::max(melEnergy, clampLevelLowdB); } } diff --git a/source/use_case/asr/src/Wav2LetterPostprocess.cc b/source/use_case/asr/src/Wav2LetterPostprocess.cc index 60ee51e..9157a6f 100644 --- a/source/use_case/asr/src/Wav2LetterPostprocess.cc +++ b/source/use_case/asr/src/Wav2LetterPostprocess.cc @@ -39,13 +39,13 @@ namespace asr { const bool lastIteration) { /* Basic checks. */ - if (!this->_IsInputValid(tensor, axisIdx)) { + if (!this->IsInputValid(tensor, axisIdx)) { return false; } /* Irrespective of tensor type, we use unsigned "byte" */ uint8_t* ptrData = tflite::GetTensorData(tensor); - const uint32_t elemSz = this->_GetTensorElementSize(tensor); + const uint32_t elemSz = this->GetTensorElementSize(tensor); /* Other sanity checks. */ if (0 == elemSz) { @@ -59,13 +59,15 @@ namespace asr { /* Which axis do we need to process? */ switch (axisIdx) { case arm::app::Wav2LetterModel::ms_outputRowsIdx: - return this->_EraseSectionsRowWise(ptrData, - elemSz * tensor->dims->data[arm::app::Wav2LetterModel::ms_outputColsIdx], - lastIteration); + return this->EraseSectionsRowWise(ptrData, + elemSz * + tensor->dims->data[arm::app::Wav2LetterModel::ms_outputColsIdx], + lastIteration); case arm::app::Wav2LetterModel::ms_outputColsIdx: - return this->_EraseSectionsColWise(ptrData, - elemSz * tensor->dims->data[arm::app::Wav2LetterModel::ms_outputRowsIdx], - lastIteration); + return this->EraseSectionsColWise(ptrData, + elemSz * + tensor->dims->data[arm::app::Wav2LetterModel::ms_outputRowsIdx], + lastIteration); default: printf_err("Unsupported axis index: %u\n", axisIdx); } @@ -73,8 +75,8 @@ namespace asr { return false; } - bool Postprocess::_IsInputValid(TfLiteTensor* tensor, - const uint32_t axisIdx) const + bool Postprocess::IsInputValid(TfLiteTensor* tensor, + const uint32_t axisIdx) const { if (nullptr == tensor) { return false; @@ -96,17 +98,15 @@ namespace asr { return true; } - uint32_t Postprocess::_GetTensorElementSize(TfLiteTensor* tensor) + uint32_t Postprocess::GetTensorElementSize(TfLiteTensor* tensor) { switch(tensor->type) { case kTfLiteUInt8: - return 1; case kTfLiteInt8: return 1; case kTfLiteInt16: return 2; case kTfLiteInt32: - return 4; case kTfLiteFloat32: return 4; default: @@ -117,7 +117,7 @@ namespace asr { return 0; } - bool Postprocess::_EraseSectionsRowWise( + bool Postprocess::EraseSectionsRowWise( uint8_t* ptrData, const uint32_t strideSzBytes, const bool lastIteration) @@ -154,8 +154,8 @@ namespace asr { return true; } - bool Postprocess::_EraseSectionsColWise( - uint8_t* ptrData, + bool Postprocess::EraseSectionsColWise( + const uint8_t* ptrData, const uint32_t strideSzBytes, const bool lastIteration) { diff --git a/source/use_case/asr/src/Wav2LetterPreprocess.cc b/source/use_case/asr/src/Wav2LetterPreprocess.cc index e46cca3..d65ea75 100644 --- a/source/use_case/asr/src/Wav2LetterPreprocess.cc +++ b/source/use_case/asr/src/Wav2LetterPreprocess.cc @@ -88,12 +88,12 @@ namespace asr { } /* Compute first and second order deltas from MFCCs. */ - this->_ComputeDeltas(this->_m_mfccBuf, - this->_m_delta1Buf, - this->_m_delta2Buf); + Preprocess::ComputeDeltas(this->_m_mfccBuf, + this->_m_delta1Buf, + this->_m_delta2Buf); /* Normalise. */ - this->_Normalise(); + this->Normalise(); /* Quantise. */ QuantParams quantParams = GetTensorQuantParams(tensor); @@ -105,11 +105,11 @@ namespace asr { switch(tensor->type) { case kTfLiteUInt8: - return this->_Quantise( + return this->Quantise( tflite::GetTensorData(tensor), tensor->bytes, quantParams.scale, quantParams.offset); case kTfLiteInt8: - return this->_Quantise( + return this->Quantise( tflite::GetTensorData(tensor), tensor->bytes, quantParams.scale, quantParams.offset); default: @@ -120,9 +120,9 @@ namespace asr { return false; } - bool Preprocess::_ComputeDeltas(Array2d& mfcc, - Array2d& delta1, - Array2d& delta2) + bool Preprocess::ComputeDeltas(Array2d& mfcc, + Array2d& delta1, + Array2d& delta2) { const std::vector delta1Coeffs = {6.66666667e-02, 5.00000000e-02, 3.33333333e-02, @@ -175,20 +175,20 @@ namespace asr { return true; } - float Preprocess::_GetMean(Array2d& vec) + float Preprocess::GetMean(Array2d& vec) { return math::MathUtils::MeanF32(vec.begin(), vec.totalSize()); } - float Preprocess::_GetStdDev(Array2d& vec, const float mean) + float Preprocess::GetStdDev(Array2d& vec, const float mean) { return math::MathUtils::StdDevF32(vec.begin(), vec.totalSize(), mean); } - void Preprocess::_NormaliseVec(Array2d& vec) + void Preprocess::NormaliseVec(Array2d& vec) { - auto mean = Preprocess::_GetMean(vec); - auto stddev = Preprocess::_GetStdDev(vec, mean); + auto mean = Preprocess::GetMean(vec); + auto stddev = Preprocess::GetStdDev(vec, mean); debug("Mean: %f, Stddev: %f\n", mean, stddev); if (stddev == 0) { @@ -204,14 +204,14 @@ namespace asr { } } - void Preprocess::_Normalise() + void Preprocess::Normalise() { - Preprocess::_NormaliseVec(this->_m_mfccBuf); - Preprocess::_NormaliseVec(this->_m_delta1Buf); - Preprocess::_NormaliseVec(this->_m_delta2Buf); + Preprocess::NormaliseVec(this->_m_mfccBuf); + Preprocess::NormaliseVec(this->_m_delta1Buf); + Preprocess::NormaliseVec(this->_m_delta2Buf); } - float Preprocess::_GetQuantElem( + float Preprocess::GetQuantElem( const float elem, const float quantScale, const int quantOffset, diff --git a/source/use_case/img_class/include/MobileNetModel.hpp b/source/use_case/img_class/include/MobileNetModel.hpp index f0521ce..2540564 100644 --- a/source/use_case/img_class/include/MobileNetModel.hpp +++ b/source/use_case/img_class/include/MobileNetModel.hpp @@ -43,10 +43,10 @@ namespace app { private: /* Maximum number of individual operations that can be enlisted. */ - static constexpr int _ms_maxOpCnt = 7; + static constexpr int ms_maxOpCnt = 7; /* A mutable op resolver instance. */ - tflite::MicroMutableOpResolver<_ms_maxOpCnt> _m_opResolver; + tflite::MicroMutableOpResolver _m_opResolver; }; } /* namespace app */ diff --git a/source/use_case/img_class/src/UseCaseHandler.cc b/source/use_case/img_class/src/UseCaseHandler.cc index f7e83f5..ffeb860 100644 --- a/source/use_case/img_class/src/UseCaseHandler.cc +++ b/source/use_case/img_class/src/UseCaseHandler.cc @@ -35,13 +35,13 @@ namespace app { * @param[out] inputTensor Pointer to the input tensor to be populated. * @return true if tensor is loaded, false otherwise. **/ - static bool _LoadImageIntoTensor(uint32_t imIdx, TfLiteTensor* inputTensor); + static bool LoadImageIntoTensor(uint32_t imIdx, TfLiteTensor* inputTensor); /** * @brief Helper function to increment current image index. * @param[in,out] ctx Pointer to the application context object. **/ - static void _IncrementAppCtxImageIdx(ApplicationContext& ctx); + static void IncrementAppCtxImageIdx(ApplicationContext& ctx); /** * @brief Helper function to set the image index. @@ -49,7 +49,7 @@ namespace app { * @param[in] idx Value to be set. * @return true if index is set, false otherwise. **/ - static bool _SetAppCtxImageIdx(ApplicationContext& ctx, uint32_t idx); + static bool SetAppCtxImageIdx(ApplicationContext& ctx, uint32_t idx); /** * @brief Presents inference results using the data presentation @@ -60,8 +60,8 @@ namespace app { * otherwise, this can be passed in as 0. * @return true if successful, false otherwise. **/ - static bool _PresentInferenceResult(hal_platform& platform, - const std::vector& results); + static bool PresentInferenceResult(hal_platform& platform, + const std::vector& results); /** * @brief Helper function to convert a UINT8 image to INT8 format. @@ -89,7 +89,7 @@ namespace app { /* If the request has a valid size, set the image index. */ if (imgIndex < NUMBER_OF_FILES) { - if (!_SetAppCtxImageIdx(ctx, imgIndex)) { + if (!SetAppCtxImageIdx(ctx, imgIndex)) { return false; } } @@ -124,7 +124,7 @@ namespace app { std::string str_inf{"Running inference... "}; /* Copy over the data. */ - _LoadImageIntoTensor(ctx.Get("imgIndex"), inputTensor); + LoadImageIntoTensor(ctx.Get("imgIndex"), inputTensor); /* Display this image on the LCD. */ platform.data_psn->present_data_image( @@ -164,20 +164,20 @@ namespace app { arm::app::DumpTensor(outputTensor); #endif /* VERIFY_TEST_OUTPUT */ - if (!_PresentInferenceResult(platform, results)) { + if (!PresentInferenceResult(platform, results)) { return false; } profiler.PrintProfilingResult(); - _IncrementAppCtxImageIdx(ctx); + IncrementAppCtxImageIdx(ctx); } while (runAll && ctx.Get("imgIndex") != curImIdx); return true; } - static bool _LoadImageIntoTensor(const uint32_t imIdx, TfLiteTensor* inputTensor) + static bool LoadImageIntoTensor(uint32_t imIdx, TfLiteTensor* inputTensor) { const size_t copySz = inputTensor->bytes < IMAGE_DATA_SIZE ? inputTensor->bytes : IMAGE_DATA_SIZE; @@ -193,7 +193,7 @@ namespace app { return true; } - static void _IncrementAppCtxImageIdx(ApplicationContext& ctx) + static void IncrementAppCtxImageIdx(ApplicationContext& ctx) { auto curImIdx = ctx.Get("imgIndex"); @@ -205,7 +205,7 @@ namespace app { ctx.Set("imgIndex", curImIdx); } - static bool _SetAppCtxImageIdx(ApplicationContext& ctx, const uint32_t idx) + static bool SetAppCtxImageIdx(ApplicationContext& ctx, uint32_t idx) { if (idx >= NUMBER_OF_FILES) { printf_err("Invalid idx %u (expected less than %u)\n", @@ -216,8 +216,8 @@ namespace app { return true; } - static bool _PresentInferenceResult(hal_platform& platform, - const std::vector& results) + static bool PresentInferenceResult(hal_platform& platform, + const std::vector& results) { constexpr uint32_t dataPsnTxtStartX1 = 150; constexpr uint32_t dataPsnTxtStartY1 = 30; diff --git a/source/use_case/kws/include/DsCnnModel.hpp b/source/use_case/kws/include/DsCnnModel.hpp index a4e7110..e9ac18c 100644 --- a/source/use_case/kws/include/DsCnnModel.hpp +++ b/source/use_case/kws/include/DsCnnModel.hpp @@ -47,10 +47,10 @@ namespace app { private: /* Maximum number of individual operations that can be enlisted. */ - static constexpr int _ms_maxOpCnt = 8; + static constexpr int ms_maxOpCnt = 8; /* A mutable op resolver instance. */ - tflite::MicroMutableOpResolver<_ms_maxOpCnt> _m_opResolver; + tflite::MicroMutableOpResolver _m_opResolver; }; } /* namespace app */ diff --git a/source/use_case/kws/src/UseCaseHandler.cc b/source/use_case/kws/src/UseCaseHandler.cc index d2cba55..4011df6 100644 --- a/source/use_case/kws/src/UseCaseHandler.cc +++ b/source/use_case/kws/src/UseCaseHandler.cc @@ -37,7 +37,7 @@ namespace app { * @brief Helper function to increment current audio clip index. * @param[in,out] ctx Pointer to the application context object. **/ - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx); + static void IncrementAppCtxClipIdx(ApplicationContext& ctx); /** * @brief Helper function to set the audio clip index. @@ -45,7 +45,7 @@ namespace app { * @param[in] idx Value to be set. * @return true if index is set, false otherwise. **/ - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); /** * @brief Presents inference results using the data presentation @@ -56,8 +56,8 @@ namespace app { * otherwise, this can be passed in as 0. * @return true if successful, false otherwise. **/ - static bool _PresentInferenceResult(hal_platform& platform, - const std::vector& results); + static bool PresentInferenceResult(hal_platform& platform, + const std::vector& results); /** * @brief Returns a function to perform feature calculation and populates input tensor data with @@ -96,7 +96,7 @@ namespace app { /* If the request has a valid size, set the audio index. */ if (clipIndex < NUMBER_OF_FILES) { - if (!_SetAppCtxClipIdx(ctx, clipIndex)) { + if (!SetAppCtxClipIdx(ctx, clipIndex)) { return false; } } @@ -240,20 +240,20 @@ namespace app { ctx.Set>("results", results); - if (!_PresentInferenceResult(platform, results)) { + if (!PresentInferenceResult(platform, results)) { return false; } profiler.PrintProfilingResult(); - _IncrementAppCtxClipIdx(ctx); + IncrementAppCtxClipIdx(ctx); } while (runAll && ctx.Get("clipIndex") != startClipIdx); return true; } - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx) + static void IncrementAppCtxClipIdx(ApplicationContext& ctx) { auto curAudioIdx = ctx.Get("clipIndex"); @@ -265,7 +265,7 @@ namespace app { ctx.Set("clipIndex", curAudioIdx); } - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, const uint32_t idx) + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx) { if (idx >= NUMBER_OF_FILES) { printf_err("Invalid idx %u (expected less than %u)\n", @@ -276,8 +276,8 @@ namespace app { return true; } - static bool _PresentInferenceResult(hal_platform& platform, - const std::vector& results) + static bool PresentInferenceResult(hal_platform& platform, + const std::vector& results) { constexpr uint32_t dataPsnTxtStartX1 = 20; constexpr uint32_t dataPsnTxtStartY1 = 30; @@ -345,8 +345,8 @@ namespace app { */ template std::function&, size_t, bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize, - std::function (std::vector& )> compute) + FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize, + std::function (std::vector& )> compute) { /* Feature cache to be captured by lambda function. */ static std::vector> featureCache = std::vector>(cacheSize); @@ -378,24 +378,24 @@ namespace app { } template std::function&, size_t , bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, + FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize, std::function (std::vector& )> compute); template std::function&, size_t , bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector& )> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector& )> compute); template std::function&, size_t , bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector& )> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector& )> compute); template std::function&, size_t, bool, size_t)> - _FeatureCalc(TfLiteTensor *inputTensor, - size_t cacheSize, - std::function(std::vector&)> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function(std::vector&)> compute); static std::function&, int, bool, size_t)> @@ -413,19 +413,19 @@ namespace app { switch (inputTensor->type) { case kTfLiteInt8: { - mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &mfcc](std::vector& audioDataWindow) { - return mfcc.MfccComputeQuant(audioDataWindow, - quantScale, - quantOffset); - } + mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &mfcc](std::vector& audioDataWindow) { + return mfcc.MfccComputeQuant(audioDataWindow, + quantScale, + quantOffset); + } ); break; } case kTfLiteUInt8: { - mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, + mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, [=, &mfcc](std::vector& audioDataWindow) { return mfcc.MfccComputeQuant(audioDataWindow, quantScale, @@ -435,13 +435,13 @@ namespace app { break; } case kTfLiteInt16: { - mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &mfcc](std::vector& audioDataWindow) { - return mfcc.MfccComputeQuant(audioDataWindow, - quantScale, - quantOffset); - } + mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &mfcc](std::vector& audioDataWindow) { + return mfcc.MfccComputeQuant(audioDataWindow, + quantScale, + quantOffset); + } ); break; } @@ -451,11 +451,11 @@ namespace app { } else { - mfccFeatureCalc = mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [&mfcc](std::vector& audioDataWindow) { - return mfcc.MfccCompute(audioDataWindow); - }); + mfccFeatureCalc = mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [&mfcc](std::vector& audioDataWindow) { + return mfcc.MfccCompute(audioDataWindow); + }); } return mfccFeatureCalc; } diff --git a/source/use_case/kws_asr/include/AsrClassifier.hpp b/source/use_case/kws_asr/include/AsrClassifier.hpp index de18aa8..7dbb6e9 100644 --- a/source/use_case/kws_asr/include/AsrClassifier.hpp +++ b/source/use_case/kws_asr/include/AsrClassifier.hpp @@ -53,9 +53,9 @@ namespace app { * @return true if successful, false otherwise. **/ template - bool _GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint); + bool GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint); }; } /* namespace app */ diff --git a/source/use_case/kws_asr/include/DsCnnModel.hpp b/source/use_case/kws_asr/include/DsCnnModel.hpp index 150a48c..f9d4357 100644 --- a/source/use_case/kws_asr/include/DsCnnModel.hpp +++ b/source/use_case/kws_asr/include/DsCnnModel.hpp @@ -55,10 +55,10 @@ namespace app { private: /* Maximum number of individual operations that can be enlisted. */ - static constexpr int _ms_maxOpCnt = 10; + static constexpr int ms_maxOpCnt = 10; /* A mutable op resolver instance. */ - tflite::MicroMutableOpResolver<_ms_maxOpCnt> _m_opResolver; + tflite::MicroMutableOpResolver _m_opResolver; }; } /* namespace app */ diff --git a/source/use_case/kws_asr/include/Wav2LetterMfcc.hpp b/source/use_case/kws_asr/include/Wav2LetterMfcc.hpp index 0852cbf..75d75da 100644 --- a/source/use_case/kws_asr/include/Wav2LetterMfcc.hpp +++ b/source/use_case/kws_asr/include/Wav2LetterMfcc.hpp @@ -60,8 +60,8 @@ namespace audio { bool ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) override; /** @@ -103,6 +103,7 @@ namespace audio { const float& leftMel, const float& rightMel, bool useHTKMethod) override; + }; } /* namespace audio */ diff --git a/source/use_case/kws_asr/include/Wav2LetterModel.hpp b/source/use_case/kws_asr/include/Wav2LetterModel.hpp index fb701ea..9a86bd9 100644 --- a/source/use_case/kws_asr/include/Wav2LetterModel.hpp +++ b/source/use_case/kws_asr/include/Wav2LetterModel.hpp @@ -55,10 +55,10 @@ namespace app { private: /* Maximum number of individual operations that can be enlisted. */ - static constexpr int _ms_maxOpCnt = 5; + static constexpr int ms_maxOpCnt = 5; /* A mutable op resolver instance. */ - tflite::MicroMutableOpResolver<_ms_maxOpCnt> _m_opResolver; + tflite::MicroMutableOpResolver _m_opResolver; }; } /* namespace app */ diff --git a/source/use_case/kws_asr/include/Wav2LetterPostprocess.hpp b/source/use_case/kws_asr/include/Wav2LetterPostprocess.hpp index 3a9d401..fe60923 100644 --- a/source/use_case/kws_asr/include/Wav2LetterPostprocess.hpp +++ b/source/use_case/kws_asr/include/Wav2LetterPostprocess.hpp @@ -72,24 +72,24 @@ namespace asr { * initialised. * @return true if valid, false otherwise. */ - bool _IsInputValid(TfLiteTensor* tensor, - uint32_t axisIdx) const; + bool IsInputValid(TfLiteTensor* tensor, + const uint32_t axisIdx) const; /** * @brief Gets the tensor data element size in bytes based * on the tensor type. * @return Size in bytes, 0 if not supported. */ - uint32_t _GetTensorElementSize(TfLiteTensor* tensor); + uint32_t GetTensorElementSize(TfLiteTensor* tensor); /** * @brief Erases sections from the data assuming row-wise * arrangement along the context axis. * @return true if successful, false otherwise. */ - bool _EraseSectionsRowWise(uint8_t* ptrData, - uint32_t strideSzBytes, - bool lastIteration); + bool EraseSectionsRowWise(uint8_t* ptrData, + const uint32_t strideSzBytes, + const bool lastIteration); }; diff --git a/source/use_case/kws_asr/include/Wav2LetterPreprocess.hpp b/source/use_case/kws_asr/include/Wav2LetterPreprocess.hpp index 3ffabb4..cf40fa8 100644 --- a/source/use_case/kws_asr/include/Wav2LetterPreprocess.hpp +++ b/source/use_case/kws_asr/include/Wav2LetterPreprocess.hpp @@ -75,16 +75,16 @@ namespace asr { * * @return true if successful, false otherwise. */ - static bool _ComputeDeltas(Array2d& mfcc, - Array2d& delta1, - Array2d& delta2); + static bool ComputeDeltas(Array2d& mfcc, + Array2d& delta1, + Array2d& delta2); /** * @brief Given a 2D vector of floats, computes the mean. * @param[in] vec Vector of vector of floats. * @return Mean value. */ - static float _GetMean(Array2d& vec); + static float GetMean(Array2d& vec); /** * @brief Given a 2D vector of floats, computes the stddev. @@ -92,20 +92,20 @@ namespace asr { * @param[in] mean Mean value of the vector passed in. * @return stddev value. */ - static float _GetStdDev(Array2d& vec, - float mean); + static float GetStdDev(Array2d& vec, + const float mean); /** * @brief Given a 2D vector of floats, normalises it using * the mean and the stddev * @param[in,out] vec Vector of vector of floats. */ - static void _NormaliseVec(Array2d& vec); + static void NormaliseVec(Array2d& vec); /** * @brief Normalises the MFCC and delta buffers. */ - void _Normalise(); + void Normalise(); /** * @brief Given the quantisation and data type limits, computes @@ -117,7 +117,7 @@ namespace asr { * @param[in] maxVal Numerical limit - maximum. * @return Floating point quantised value. */ - static float _GetQuantElem( + static float GetQuantElem( float elem, float quantScale, int quantOffset, @@ -138,7 +138,7 @@ namespace asr { * @param[in] quantOffset Quantisation offset. */ template - bool _Quantise( + bool Quantise( T * outputBuf, const uint32_t outputBufSz, const float quantScale, @@ -163,15 +163,15 @@ namespace asr { * the tensor. */ for (uint32_t j = 0; j < this->_m_numFeatVectors; ++j) { for (uint32_t i = 0; i < this->_m_numMfccFeats; ++i) { - *outputBufMfcc++ = static_cast(this->_GetQuantElem( - this->_m_mfccBuf(i, j), quantScale, - quantOffset, minVal, maxVal)); - *outputBufD1++ = static_cast(this->_GetQuantElem( - this->_m_delta1Buf(i, j), quantScale, - quantOffset, minVal, maxVal)); - *outputBufD2++ = static_cast(this->_GetQuantElem( - this->_m_delta2Buf(i, j), quantScale, - quantOffset, minVal, maxVal)); + *outputBufMfcc++ = static_cast(this->GetQuantElem( + this->_m_mfccBuf(i, j), quantScale, + quantOffset, minVal, maxVal)); + *outputBufD1++ = static_cast(this->GetQuantElem( + this->_m_delta1Buf(i, j), quantScale, + quantOffset, minVal, maxVal)); + *outputBufD2++ = static_cast(this->GetQuantElem( + this->_m_delta2Buf(i, j), quantScale, + quantOffset, minVal, maxVal)); } outputBufMfcc += ptrIncr; outputBufD1 += ptrIncr; diff --git a/source/use_case/kws_asr/src/AsrClassifier.cc b/source/use_case/kws_asr/src/AsrClassifier.cc index bc86e09..f1fa6f1 100644 --- a/source/use_case/kws_asr/src/AsrClassifier.cc +++ b/source/use_case/kws_asr/src/AsrClassifier.cc @@ -21,13 +21,17 @@ #include "Wav2LetterModel.hpp" template -bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint) +bool arm::app::AsrClassifier::GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint) { const uint32_t nElems = tensor->dims->data[arm::app::Wav2LetterModel::ms_outputRowsIdx]; const uint32_t nLetters = tensor->dims->data[arm::app::Wav2LetterModel::ms_outputColsIdx]; + if (nLetters != labels.size()) { + printf("Output size doesn't match the labels' size\n"); + return false; + } /* NOTE: tensor's size verification against labels should be * checked by the calling/public function. */ @@ -42,7 +46,7 @@ bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, /* Get the top 1 results. */ for (uint32_t i = 0, row = 0; i < nElems; ++i, row+=nLetters) { - std::pair top_1 = std::make_pair(tensorData[row + 0], 0); + std::pair top_1 = std::make_pair(tensorData[row], 0); for (uint32_t j = 1; j < nLetters; ++j) { if (top_1.first < tensorData[row + j]) { @@ -59,12 +63,12 @@ bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, return true; } -template bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint); -template bool arm::app::AsrClassifier::_GetTopResults(TfLiteTensor* tensor, - std::vector& vecResults, - const std::vector & labels, double scale, double zeroPoint); +template bool arm::app::AsrClassifier::GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint); +template bool arm::app::AsrClassifier::GetTopResults(TfLiteTensor* tensor, + std::vector& vecResults, + const std::vector & labels, double scale, double zeroPoint); bool arm::app::AsrClassifier::GetClassificationResults( TfLiteTensor* outputTensor, @@ -105,16 +109,16 @@ bool arm::app::AsrClassifier::GetClassificationResults( switch (outputTensor->type) { case kTfLiteUInt8: - resultState = this->_GetTopResults( - outputTensor, vecResults, - labels, quantParams.scale, - quantParams.offset); + resultState = this->GetTopResults( + outputTensor, vecResults, + labels, quantParams.scale, + quantParams.offset); break; case kTfLiteInt8: - resultState = this->_GetTopResults( - outputTensor, vecResults, - labels, quantParams.scale, - quantParams.offset); + resultState = this->GetTopResults( + outputTensor, vecResults, + labels, quantParams.scale, + quantParams.offset); break; default: printf_err("Tensor type %s not supported by classifier\n", diff --git a/source/use_case/kws_asr/src/UseCaseHandler.cc b/source/use_case/kws_asr/src/UseCaseHandler.cc index a428210..1edc7c4 100644 --- a/source/use_case/kws_asr/src/UseCaseHandler.cc +++ b/source/use_case/kws_asr/src/UseCaseHandler.cc @@ -52,13 +52,7 @@ namespace app { * @brief Helper function to increment current audio clip index * @param[in,out] ctx pointer to the application context object **/ - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx); - - /** - * @brief Helper function to increment current audio clip index - * @param[in,out] ctx pointer to the application context object - **/ - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx); + static void IncrementAppCtxClipIdx(ApplicationContext& ctx); /** * @brief Helper function to set the audio clip index @@ -66,7 +60,7 @@ namespace app { * @param[in] idx value to be set * @return true if index is set, false otherwise **/ - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx); /** * @brief Presents kws inference results using the data presentation @@ -77,7 +71,7 @@ namespace app { * Otherwise, this can be passed in as 0. * @return true if successful, false otherwise **/ - static bool _PresentInferenceResult(hal_platform& platform, std::vector& results); + static bool PresentInferenceResult(hal_platform& platform, std::vector& results); /** * @brief Presents asr inference results using the data presentation @@ -88,7 +82,7 @@ namespace app { * Otherwise, this can be passed in as 0. * @return true if successful, false otherwise **/ - static bool _PresentInferenceResult(hal_platform& platform, std::vector& results); + static bool PresentInferenceResult(hal_platform& platform, std::vector& results); /** * @brief Returns a function to perform feature calculation and populates input tensor data with @@ -212,7 +206,7 @@ namespace app { std::string str_inf{"Running KWS inference... "}; platform.data_psn->present_data_text( str_inf.c_str(), str_inf.size(), - dataPsnTxtInfStartX, dataPsnTxtInfStartY, 0); + dataPsnTxtInfStartX, dataPsnTxtInfStartY, false); info("Running KWS inference on audio clip %u => %s\n", currentIndex, get_filename(currentIndex)); @@ -279,9 +273,9 @@ namespace app { str_inf = std::string(str_inf.size(), ' '); platform.data_psn->present_data_text( str_inf.c_str(), str_inf.size(), - dataPsnTxtInfStartX, dataPsnTxtInfStartY, 0); + dataPsnTxtInfStartX, dataPsnTxtInfStartY, false); - if (!_PresentInferenceResult(platform, kwsResults)) { + if (!PresentInferenceResult(platform, kwsResults)) { return output; } @@ -375,7 +369,7 @@ namespace app { std::string str_inf{"Running ASR inference... "}; platform.data_psn->present_data_text( str_inf.c_str(), str_inf.size(), - dataPsnTxtInfStartX, dataPsnTxtInfStartY, 0); + dataPsnTxtInfStartX, dataPsnTxtInfStartY, false); size_t asrInferenceWindowLen = asrAudioParamsWinLen; @@ -425,7 +419,7 @@ namespace app { str_inf.c_str(), str_inf.size(), dataPsnTxtInfStartX, dataPsnTxtInfStartY, false); } - if (!_PresentInferenceResult(platform, asrResults)) { + if (!PresentInferenceResult(platform, asrResults)) { return false; } @@ -442,7 +436,7 @@ namespace app { /* If the request has a valid size, set the audio index. */ if (clipIndex < NUMBER_OF_FILES) { - if (!_SetAppCtxClipIdx(ctx, clipIndex)) { + if (!SetAppCtxClipIdx(ctx, clipIndex)) { return false; } } @@ -463,14 +457,14 @@ namespace app { } } - _IncrementAppCtxClipIdx(ctx); + IncrementAppCtxClipIdx(ctx); } while (runAll && ctx.Get("clipIndex") != startClipIdx); return true; } - static void _IncrementAppCtxClipIdx(ApplicationContext& ctx) + static void IncrementAppCtxClipIdx(ApplicationContext& ctx) { auto curAudioIdx = ctx.Get("clipIndex"); @@ -482,7 +476,7 @@ namespace app { ctx.Set("clipIndex", curAudioIdx); } - static bool _SetAppCtxClipIdx(ApplicationContext& ctx, const uint32_t idx) + static bool SetAppCtxClipIdx(ApplicationContext& ctx, uint32_t idx) { if (idx >= NUMBER_OF_FILES) { printf_err("Invalid idx %u (expected less than %u)\n", @@ -493,8 +487,8 @@ namespace app { return true; } - static bool _PresentInferenceResult(hal_platform& platform, - std::vector& results) + static bool PresentInferenceResult(hal_platform& platform, + std::vector& results) { constexpr uint32_t dataPsnTxtStartX1 = 20; constexpr uint32_t dataPsnTxtStartY1 = 30; @@ -510,7 +504,7 @@ namespace app { std::string topKeyword{""}; float score = 0.f; - if (results[i].m_resultVec.size()) { + if (!results[i].m_resultVec.empty()) { topKeyword = results[i].m_resultVec[0].m_label; score = results[i].m_resultVec[0].m_normalisedVal; } @@ -538,7 +532,7 @@ namespace app { return true; } - static bool _PresentInferenceResult(hal_platform& platform, std::vector& results) + static bool PresentInferenceResult(hal_platform& platform, std::vector& results) { constexpr uint32_t dataPsnTxtStartX1 = 20; constexpr uint32_t dataPsnTxtStartY1 = 80; @@ -587,8 +581,8 @@ namespace app { **/ template std::function&, size_t, bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize, - std::function (std::vector& )> compute) + FeatureCalc(TfLiteTensor* inputTensor, size_t cacheSize, + std::function (std::vector& )> compute) { /* Feature cache to be captured by lambda function. */ static std::vector> featureCache = std::vector>(cacheSize); @@ -621,24 +615,24 @@ namespace app { } template std::function&, size_t , bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector& )> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector& )> compute); template std::function&, size_t , bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector& )> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector& )> compute); template std::function&, size_t , bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function (std::vector& )> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function (std::vector& )> compute); template std::function&, size_t, bool, size_t)> - _FeatureCalc(TfLiteTensor* inputTensor, - size_t cacheSize, - std::function(std::vector&)> compute); + FeatureCalc(TfLiteTensor* inputTensor, + size_t cacheSize, + std::function(std::vector&)> compute); static std::function&, int, bool, size_t)> @@ -656,35 +650,35 @@ namespace app { switch (inputTensor->type) { case kTfLiteInt8: { - mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &mfcc](std::vector& audioDataWindow) { - return mfcc.MfccComputeQuant(audioDataWindow, - quantScale, - quantOffset); - } + mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &mfcc](std::vector& audioDataWindow) { + return mfcc.MfccComputeQuant(audioDataWindow, + quantScale, + quantOffset); + } ); break; } case kTfLiteUInt8: { - mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &mfcc](std::vector& audioDataWindow) { - return mfcc.MfccComputeQuant(audioDataWindow, - quantScale, - quantOffset); - } + mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &mfcc](std::vector& audioDataWindow) { + return mfcc.MfccComputeQuant(audioDataWindow, + quantScale, + quantOffset); + } ); break; } case kTfLiteInt16: { - mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [=, &mfcc](std::vector& audioDataWindow) { - return mfcc.MfccComputeQuant(audioDataWindow, - quantScale, - quantOffset); - } + mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [=, &mfcc](std::vector& audioDataWindow) { + return mfcc.MfccComputeQuant(audioDataWindow, + quantScale, + quantOffset); + } ); break; } @@ -694,11 +688,11 @@ namespace app { } else { - mfccFeatureCalc = mfccFeatureCalc = _FeatureCalc(inputTensor, - cacheSize, - [&mfcc](std::vector& audioDataWindow) { - return mfcc.MfccCompute(audioDataWindow); - }); + mfccFeatureCalc = mfccFeatureCalc = FeatureCalc(inputTensor, + cacheSize, + [&mfcc](std::vector& audioDataWindow) { + return mfcc.MfccCompute(audioDataWindow); + }); } return mfccFeatureCalc; } diff --git a/source/use_case/kws_asr/src/Wav2LetterMfcc.cc b/source/use_case/kws_asr/src/Wav2LetterMfcc.cc index 80e4a26..ae9e57a 100644 --- a/source/use_case/kws_asr/src/Wav2LetterMfcc.cc +++ b/source/use_case/kws_asr/src/Wav2LetterMfcc.cc @@ -27,8 +27,8 @@ namespace audio { bool Wav2LetterMFCC::ApplyMelFilterBank( std::vector& fftVec, std::vector>& melFilterBank, - std::vector& filterBankFilterFirst, - std::vector& filterBankFilterLast, + std::vector& filterBankFilterFirst, + std::vector& filterBankFilterLast, std::vector& melEnergies) { const size_t numBanks = melEnergies.size(); @@ -41,11 +41,14 @@ namespace audio { for (size_t bin = 0; bin < numBanks; ++bin) { auto filterBankIter = melFilterBank[bin].begin(); - float melEnergy = 1e-10; /* Avoid log of zero at later stages, same value used in librosa. */ - const int32_t firstIndex = filterBankFilterFirst[bin]; - const int32_t lastIndex = filterBankFilterLast[bin]; - - for (int32_t i = firstIndex; i <= lastIndex; ++i) { + auto end = melFilterBank[bin].end(); + /* Avoid log of zero at later stages, same value used in librosa. + * The number was used during our default wav2letter model training. */ + float melEnergy = 1e-10; + const uint32_t firstIndex = filterBankFilterFirst[bin]; + const uint32_t lastIndex = std::min(filterBankFilterLast[bin], fftVec.size() - 1); + + for (uint32_t i = firstIndex; i <= lastIndex && filterBankIter != end; ++i) { melEnergy += (*filterBankIter++ * fftVec[i]); } @@ -73,7 +76,7 @@ namespace audio { /* Scale the log values and get the max. */ for (auto iterM = melEnergies.begin(), iterL = vecLogEnergies.begin(); - iterM != melEnergies.end(); ++iterM, ++iterL) { + iterM != melEnergies.end() && iterL != vecLogEnergies.end(); ++iterM, ++iterL) { *iterM = *iterL * multiplier; @@ -86,8 +89,8 @@ namespace audio { /* Clamp the mel energies. */ constexpr float maxDb = 80.0; const float clampLevelLowdB = maxMelEnergy - maxDb; - for (auto iter = melEnergies.begin(); iter != melEnergies.end(); ++iter) { - *iter = std::max(*iter, clampLevelLowdB); + for (float & melEnergie : melEnergies) { + melEnergie = std::max(melEnergie, clampLevelLowdB); } } diff --git a/source/use_case/kws_asr/src/Wav2LetterPostprocess.cc b/source/use_case/kws_asr/src/Wav2LetterPostprocess.cc index b173968..ee3aba0 100644 --- a/source/use_case/kws_asr/src/Wav2LetterPostprocess.cc +++ b/source/use_case/kws_asr/src/Wav2LetterPostprocess.cc @@ -38,13 +38,13 @@ namespace asr { const bool lastIteration) { /* Basic checks. */ - if (!this->_IsInputValid(tensor, axisIdx)) { + if (!this->IsInputValid(tensor, axisIdx)) { return false; } /* Irrespective of tensor type, we use unsigned "byte" */ uint8_t* ptrData = tflite::GetTensorData(tensor); - const uint32_t elemSz = this->_GetTensorElementSize(tensor); + const uint32_t elemSz = this->GetTensorElementSize(tensor); /* Other sanity checks. */ if (0 == elemSz) { @@ -58,9 +58,10 @@ namespace asr { /* Which axis do we need to process? */ switch (axisIdx) { case arm::app::Wav2LetterModel::ms_outputRowsIdx: - return this->_EraseSectionsRowWise(ptrData, - elemSz * tensor->dims->data[arm::app::Wav2LetterModel::ms_outputColsIdx], - lastIteration); + return this->EraseSectionsRowWise(ptrData, + elemSz * + tensor->dims->data[arm::app::Wav2LetterModel::ms_outputColsIdx], + lastIteration); default: printf_err("Unsupported axis index: %u\n", axisIdx); } @@ -68,8 +69,8 @@ namespace asr { return false; } - bool Postprocess::_IsInputValid(TfLiteTensor* tensor, - const uint32_t axisIdx) const + bool Postprocess::IsInputValid(TfLiteTensor* tensor, + const uint32_t axisIdx) const { if (nullptr == tensor) { return false; @@ -91,7 +92,7 @@ namespace asr { return true; } - uint32_t Postprocess::_GetTensorElementSize(TfLiteTensor* tensor) + uint32_t Postprocess::GetTensorElementSize(TfLiteTensor* tensor) { switch(tensor->type) { case kTfLiteUInt8: @@ -112,7 +113,7 @@ namespace asr { return 0; } - bool Postprocess::_EraseSectionsRowWise( + bool Postprocess::EraseSectionsRowWise( uint8_t* ptrData, const uint32_t strideSzBytes, const bool lastIteration) diff --git a/source/use_case/kws_asr/src/Wav2LetterPreprocess.cc b/source/use_case/kws_asr/src/Wav2LetterPreprocess.cc index 613ddb0..8251396 100644 --- a/source/use_case/kws_asr/src/Wav2LetterPreprocess.cc +++ b/source/use_case/kws_asr/src/Wav2LetterPreprocess.cc @@ -88,12 +88,12 @@ namespace asr { } /* Compute first and second order deltas from MFCCs. */ - this->_ComputeDeltas(this->_m_mfccBuf, - this->_m_delta1Buf, - this->_m_delta2Buf); + this->ComputeDeltas(this->_m_mfccBuf, + this->_m_delta1Buf, + this->_m_delta2Buf); /* Normalise. */ - this->_Normalise(); + this->Normalise(); /* Quantise. */ QuantParams quantParams = GetTensorQuantParams(tensor); @@ -105,11 +105,11 @@ namespace asr { switch(tensor->type) { case kTfLiteUInt8: - return this->_Quantise( + return this->Quantise( tflite::GetTensorData(tensor), tensor->bytes, quantParams.scale, quantParams.offset); case kTfLiteInt8: - return this->_Quantise( + return this->Quantise( tflite::GetTensorData(tensor), tensor->bytes, quantParams.scale, quantParams.offset); default: @@ -120,9 +120,9 @@ namespace asr { return false; } - bool Preprocess::_ComputeDeltas(Array2d& mfcc, - Array2d& delta1, - Array2d& delta2) + bool Preprocess::ComputeDeltas(Array2d& mfcc, + Array2d& delta1, + Array2d& delta2) { const std::vector delta1Coeffs = {6.66666667e-02, 5.00000000e-02, 3.33333333e-02, @@ -175,20 +175,20 @@ namespace asr { return true; } - float Preprocess::_GetMean(Array2d& vec) + float Preprocess::GetMean(Array2d& vec) { return math::MathUtils::MeanF32(vec.begin(), vec.totalSize()); } - float Preprocess::_GetStdDev(Array2d& vec, const float mean) + float Preprocess::GetStdDev(Array2d& vec, const float mean) { return math::MathUtils::StdDevF32(vec.begin(), vec.totalSize(), mean); } - void Preprocess::_NormaliseVec(Array2d& vec) + void Preprocess::NormaliseVec(Array2d& vec) { - auto mean = Preprocess::_GetMean(vec); - auto stddev = Preprocess::_GetStdDev(vec, mean); + auto mean = Preprocess::GetMean(vec); + auto stddev = Preprocess::GetStdDev(vec, mean); debug("Mean: %f, Stddev: %f\n", mean, stddev); if (stddev == 0) { @@ -204,14 +204,14 @@ namespace asr { } } - void Preprocess::_Normalise() + void Preprocess::Normalise() { - Preprocess::_NormaliseVec(this->_m_mfccBuf); - Preprocess::_NormaliseVec(this->_m_delta1Buf); - Preprocess::_NormaliseVec(this->_m_delta2Buf); + Preprocess::NormaliseVec(this->_m_mfccBuf); + Preprocess::NormaliseVec(this->_m_delta1Buf); + Preprocess::NormaliseVec(this->_m_delta2Buf); } - float Preprocess::_GetQuantElem( + float Preprocess::GetQuantElem( const float elem, const float quantScale, const int quantOffset, diff --git a/tests/common/ClassifierTests.cc b/tests/common/ClassifierTests.cc index f08a09a..a04e4c2 100644 --- a/tests/common/ClassifierTests.cc +++ b/tests/common/ClassifierTests.cc @@ -18,6 +18,31 @@ #include + +template +void test_classifier_result(std::vector>& selectedResults, T defaultTensorValue) { + const int dimArray[] = {1, 1001}; + std::vector labels(1001); + std::vector outputVec(1001, defaultTensorValue); + TfLiteIntArray* dims= tflite::testing::IntArrayFromInts(dimArray); + TfLiteTensor tfTensor = tflite::testing::CreateQuantizedTensor(outputVec.data(), dims, 1, 0); + TfLiteTensor* outputTensor = &tfTensor; + + std::vector resultVec; + + for (auto& selectedResult : selectedResults) { + outputVec[selectedResult.first] = selectedResult.second; + } + + arm::app::Classifier classifier; + REQUIRE(classifier.GetClassificationResults(outputTensor, resultVec, labels, 5)); + REQUIRE(5 == resultVec.size()); + + for (size_t i = 0; i < resultVec.size(); ++i) { + REQUIRE(resultVec[i].m_labelIdx == selectedResults[i].first); + } +} + TEST_CASE("Common classifier") { SECTION("Test invalid classifier") @@ -28,49 +53,31 @@ TEST_CASE("Common classifier") REQUIRE(!classifier.GetClassificationResults(outputTens, resultVec, {}, 5)); } - SECTION("Test valid classifier UINT8") + SECTION("Test classification results") { - const int dimArray[] = {1, 1001}; - std::vector labels(1001); - std::vector outputVec(1001); - TfLiteIntArray* dims= tflite::testing::IntArrayFromInts(dimArray); - TfLiteTensor tfTensor = tflite::testing::CreateQuantizedTensor( - outputVec.data(), dims, 1, 0, "test"); - TfLiteTensor* outputTensor = &tfTensor; - std::vector resultVec; - arm::app::Classifier classifier; - REQUIRE(classifier.GetClassificationResults(outputTensor, resultVec, labels, 5)); - REQUIRE(5 == resultVec.size()); - } + SECTION("uint8") { + /* Set the top five results . */ + std::vector> selectedResults { + {1000, 10}, {15, 9}, {0, 8}, {20, 7}, {10, 7} }; - SECTION("Get classification results") - { - const int dimArray[] = {1, 1001}; - std::vector labels(1001); - std::vector outputVec(1001, static_cast(5)); - TfLiteIntArray* dims= tflite::testing::IntArrayFromInts(dimArray); - TfLiteTensor tfTensor = tflite::testing::CreateQuantizedTensor( - outputVec.data(), dims, 1, 0, "test"); - TfLiteTensor* outputTensor = &tfTensor; - - std::vector resultVec; + test_classifier_result(selectedResults, static_cast(5)); + } - /* Set the top five results. */ - std::vector> selectedResults { - {0, 8}, {20, 7}, {10, 7}, {15, 9}, {1000, 10}}; + SECTION("int8") { + /* Set the top five results . */ + std::vector> selectedResults { + {1000, 10}, {15, 9}, {0, 8}, {20, -7}, {10, -7} }; - for (size_t i = 0; i < selectedResults.size(); ++i) { - outputVec[selectedResults[i].first] = selectedResults[i].second; + test_classifier_result(selectedResults, static_cast(-100)); } - arm::app::Classifier classifier; - REQUIRE(classifier.GetClassificationResults(outputTensor, resultVec, labels, 5)); - REQUIRE(5 == resultVec.size()); + SECTION("float") { + /* Set the top five results . */ + std::vector> selectedResults { + {1000, 10.9f}, {15, 9.8f}, {0, 8.7f}, {20, -7.0f}, {10, -7.1f} }; + + test_classifier_result(selectedResults, -100.0f); + } - REQUIRE(resultVec[0].m_labelIdx == 1000); - REQUIRE(resultVec[1].m_labelIdx == 15); - REQUIRE(resultVec[2].m_labelIdx == 0); - REQUIRE(resultVec[3].m_labelIdx == 20); - REQUIRE(resultVec[4].m_labelIdx == 10); } } diff --git a/tests/use_case/asr/AsrClassifierTests.cc b/tests/use_case/asr/AsrClassifierTests.cc index 7c71912..12523aa 100644 --- a/tests/use_case/asr/AsrClassifierTests.cc +++ b/tests/use_case/asr/AsrClassifierTests.cc @@ -35,7 +35,7 @@ TEST_CASE("Test valid classifier UINT8") { std::vector outputVec(7134); TfLiteIntArray* dims= tflite::testing::IntArrayFromInts(dimArray); TfLiteTensor tfTensor = tflite::testing::CreateQuantizedTensor( - outputVec.data(), dims, 1, 0, "test"); + outputVec.data(), dims, 1, 0); TfLiteTensor* outputTensor = &tfTensor; std::vector resultVec; arm::app::AsrClassifier classifier; @@ -51,7 +51,7 @@ TEST_CASE("Get classification results") { std::vector outputVec(150, static_cast(1)); TfLiteIntArray* dims= tflite::testing::IntArrayFromInts(dimArray); TfLiteTensor tfTensor = tflite::testing::CreateQuantizedTensor( - outputVec.data(), dims, 1, 0, "test"); + outputVec.data(), dims, 1, 0); TfLiteTensor* outputTensor = &tfTensor; std::vector resultVec(10); diff --git a/tests/use_case/asr/AsrFeaturesTests.cc b/tests/use_case/asr/AsrFeaturesTests.cc index 9401f40..59fe29b 100644 --- a/tests/use_case/asr/AsrFeaturesTests.cc +++ b/tests/use_case/asr/AsrFeaturesTests.cc @@ -25,30 +25,27 @@ class TestPreprocess : public arm::app::audio::asr::Preprocess { public: - TestPreprocess() - : arm::app::audio::asr::Preprocess(0,0,0,0) - {} - bool ComputeDeltas(arm::app::Array2d& mfcc, + static bool ComputeDeltas(arm::app::Array2d& mfcc, arm::app::Array2d& delta1, arm::app::Array2d& delta2) { - return this->_ComputeDeltas(mfcc, delta1, delta2); + return Preprocess::ComputeDeltas(mfcc, delta1, delta2); } - float GetMean(arm::app::Array2d& vec) + static float GetMean(arm::app::Array2d& vec) { - return this->_GetMean(vec); + return Preprocess::GetMean(vec); } - float GetStdDev(arm::app::Array2d& vec, const float mean) + static float GetStdDev(arm::app::Array2d& vec, const float mean) { - return this->_GetStdDev(vec, mean); + return Preprocess::GetStdDev(vec, mean); } - void NormaliseVec(arm::app::Array2d& vec) + static void NormaliseVec(arm::app::Array2d& vec) { - return this->_NormaliseVec(vec); + return Preprocess::NormaliseVec(vec); } }; @@ -86,7 +83,6 @@ void populateArray2dWithVectorOfVector(std::vector> vec, arm: TEST_CASE("Floating point asr features calculation", "[ASR]") { - TestPreprocess tp; SECTION("First and second diff") { @@ -109,7 +105,7 @@ TEST_CASE("Floating point asr features calculation", "[ASR]") std::fill(delta1Buf.begin(), delta1Buf.end(), 0.f); std::fill(delta2Buf.begin(), delta2Buf.end(), 0.f); - tp.ComputeDeltas(mfccBuf, delta1Buf, delta2Buf); + TestPreprocess::ComputeDeltas(mfccBuf, delta1Buf, delta2Buf); /* First 4 and last 4 values are different because we pad AFTER diff calculated. */ for (size_t i = 0; i < numMfccFeats; ++i) { @@ -136,37 +132,37 @@ TEST_CASE("Floating point asr features calculation", "[ASR]") {-1, -2}}; arm::app::Array2d mean1(2,2); /* {{1, 2},{-1, -2}} */ populateArray2dWithVectorOfVector(mean1vec, mean1); - REQUIRE(0 == Approx(tp.GetMean(mean1))); + REQUIRE(0 == Approx(TestPreprocess::GetMean(mean1))); arm::app::Array2d mean2(2, 2); std::fill(mean2.begin(), mean2.end(), 0.f); - REQUIRE(0 == Approx(tp.GetMean(mean2))); + REQUIRE(0 == Approx(TestPreprocess::GetMean(mean2))); arm::app::Array2d mean3(3,3); std::fill(mean3.begin(), mean3.end(), 1.f); - REQUIRE(1 == Approx(tp.GetMean(mean3))); + REQUIRE(1 == Approx(TestPreprocess::GetMean(mean3))); } SECTION("Std") { arm::app::Array2d std1(2, 2); std::fill(std1.begin(), std1.end(), 0.f); /* {{0, 0}, {0, 0}} */ - REQUIRE(0 == Approx(tp.GetStdDev(std1, 0))); + REQUIRE(0 == Approx(TestPreprocess::GetStdDev(std1, 0))); std::vector> std2vec{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 0}}; arm::app::Array2d std2(2,5); populateArray2dWithVectorOfVector(std2vec, std2); - const float mean = tp.GetMean(std2); - REQUIRE(2.872281323 == Approx(tp.GetStdDev(std2, mean))); + const float mean = TestPreprocess::GetMean(std2); + REQUIRE(2.872281323 == Approx(TestPreprocess::GetStdDev(std2, mean))); arm::app::Array2d std3(2,2); std::fill(std3.begin(), std3.end(), 1.f); /* std3{{1, 1}, {1, 1}}; */ - REQUIRE(0 == Approx(tp.GetStdDev(std3, 1))); + REQUIRE(0 == Approx(TestPreprocess::GetStdDev(std3, 1))); } SECTION("Norm") { auto checker = [&](arm::app::Array2d& d, std::vector& g) { - tp.NormaliseVec(d); + TestPreprocess::NormaliseVec(d); std::vector d_vec(d.begin(), d.end()); REQUIRE_THAT(g, Catch::Approx(d_vec)); }; -- cgit v1.2.1