diff --git a/include/rppdefs.h b/include/rppdefs.h index ff9130a52..58637be61 100644 --- a/include/rppdefs.h +++ b/include/rppdefs.h @@ -386,6 +386,16 @@ typedef enum TRIANGULAR } RpptInterpolationType; +/*! \brief RPPT Audio Border Type + * \ingroup group_rppdefs + */ +typedef enum +{ + ZERO = 0, + CLAMP, + REFLECT +} RpptAudioBorderType; + /*! \brief RPPT Tensor 2D ROI LTRB struct * \ingroup group_rppdefs */ diff --git a/include/rppt_tensor_audio_augmentations.h b/include/rppt_tensor_audio_augmentations.h index f8ce8899e..f82514c3a 100644 --- a/include/rppt_tensor_audio_augmentations.h +++ b/include/rppt_tensor_audio_augmentations.h @@ -77,6 +77,22 @@ RppStatus rppt_non_silent_region_detection_host(RppPtr_t srcPtr, RpptDescPtr src */ RppStatus rppt_to_decibels_host(RppPtr_t srcPtr, RpptDescPtr srcDescPtr, RppPtr_t dstPtr, RpptDescPtr dstDescPtr, RpptImagePatchPtr srcDims, Rpp32f cutOffDB, Rpp32f multiplier, Rpp32f referenceMagnitude, rppHandle_t rppHandle); +/*! \brief Pre Emphasis Filter augmentation on HOST backend + * \details Pre Emphasis Filter augmentation for audio data + * \param[in] srcPtr source tensor in HOST memory + * \param[in] srcDescPtr source tensor descriptor (Restrictions - numDims = 3, offsetInBytes >= 0, dataType = F32) + * \param[out] dstPtr destination tensor in HOST memory + * \param[in] dstDescPtr destination tensor descriptor (Restrictions - numDims = 3, offsetInBytes >= 0, dataType = F32) + * \param[in] srcLengthTensor source audio buffer length (1D tensor in HOST memory, of size batchSize) + * \param[in] coeffTensor preemphasis coefficient (1D tensor in HOST memory, of size batchSize) + * \param[in] borderType border value policy + * \param[in] rppHandle RPP HOST handle created with \ref rppCreateWithBatchSize() + * \return A \ref RppStatus enumeration. + * \retval RPP_SUCCESS Successful completion. + * \retval RPP_ERROR* Unsuccessful completion. + */ +RppStatus rppt_pre_emphasis_filter_host(RppPtr_t srcPtr, RpptDescPtr srcDescPtr, RppPtr_t dstPtr, RpptDescPtr dstDescPtr, Rpp32s *srcLengthTensor, Rpp32f *coeffTensor, RpptAudioBorderType borderType, rppHandle_t rppHandle); + #ifdef __cplusplus } #endif diff --git a/src/modules/cpu/host_tensor_audio_augmentations.hpp b/src/modules/cpu/host_tensor_audio_augmentations.hpp index 76c3193fc..29fa65b66 100644 --- a/src/modules/cpu/host_tensor_audio_augmentations.hpp +++ b/src/modules/cpu/host_tensor_audio_augmentations.hpp @@ -22,5 +22,6 @@ THE SOFTWARE. #include "kernel/non_silent_region_detection.hpp" #include "kernel/to_decibels.hpp" +#include "kernel/pre_emphasis_filter.hpp" #endif // HOST_TENSOR_AUDIO_AUGMENTATIONS_HPP \ No newline at end of file diff --git a/src/modules/cpu/kernel/pre_emphasis_filter.hpp b/src/modules/cpu/kernel/pre_emphasis_filter.hpp new file mode 100644 index 000000000..ffed17949 --- /dev/null +++ b/src/modules/cpu/kernel/pre_emphasis_filter.hpp @@ -0,0 +1,75 @@ +/* +Copyright (c) 2019 - 2023 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "rppdefs.h" +#include "rpp_cpu_simd.hpp" +#include "rpp_cpu_common.hpp" + +RppStatus pre_emphasis_filter_host_tensor(Rpp32f *srcPtr, + RpptDescPtr srcDescPtr, + Rpp32f *dstPtr, + RpptDescPtr dstDescPtr, + Rpp32s *srcLengthTensor, + Rpp32f *coeffTensor, + Rpp32u borderType, + rpp::Handle& handle) +{ + Rpp32u numThreads = handle.GetNumThreads(); + + omp_set_dynamic(0); +#pragma omp parallel for num_threads(numThreads) + for(int batchCount = 0; batchCount < srcDescPtr->n; batchCount++) + { + Rpp32f *srcPtrTemp = srcPtr + batchCount * srcDescPtr->strides.nStride; + Rpp32f *dstPtrTemp = dstPtr + batchCount * dstDescPtr->strides.nStride; + Rpp32s bufferLength = srcLengthTensor[batchCount]; + Rpp32f coeff = coeffTensor[batchCount]; + Rpp32f border = (borderType == RpptAudioBorderType::CLAMP) ? srcPtrTemp[0] : + (borderType == RpptAudioBorderType::REFLECT) ? srcPtrTemp[1] : 0; + dstPtrTemp[0] = srcPtrTemp[0] - coeff * border; + + Rpp32s vectorIncrement = 8; + Rpp32s alignedLength = (bufferLength / 8) * 8; + __m256 pCoeff = _mm256_set1_ps(coeff); + + Rpp32s vectorLoopCount = 1; + dstPtrTemp++; + srcPtrTemp++; + for(; vectorLoopCount < alignedLength; vectorLoopCount += vectorIncrement) + { + __m256 pSrc[2]; + pSrc[0] = _mm256_loadu_ps(srcPtrTemp); + pSrc[1] = _mm256_loadu_ps(srcPtrTemp - 1); + pSrc[1] = _mm256_sub_ps(pSrc[0], _mm256_mul_ps(pSrc[1], pCoeff)); + _mm256_storeu_ps(dstPtrTemp, pSrc[1]); + srcPtrTemp += vectorIncrement; + dstPtrTemp += vectorIncrement; + } + for(; vectorLoopCount < bufferLength; vectorLoopCount++) + { + *dstPtrTemp++ = *srcPtrTemp - coeff * (*(srcPtrTemp - 1)); + srcPtrTemp++; + } + } + + return RPP_SUCCESS; +} diff --git a/src/modules/rppt_tensor_audio_augmentations.cpp b/src/modules/rppt_tensor_audio_augmentations.cpp index adea384b5..35b9aa735 100644 --- a/src/modules/rppt_tensor_audio_augmentations.cpp +++ b/src/modules/rppt_tensor_audio_augmentations.cpp @@ -94,3 +94,33 @@ RppStatus rppt_to_decibels_host(RppPtr_t srcPtr, return RPP_ERROR_INVALID_SRC_OR_DST_DATATYPE; } } + +/******************** pre_emphasis_filter ********************/ + +RppStatus rppt_pre_emphasis_filter_host(RppPtr_t srcPtr, + RpptDescPtr srcDescPtr, + RppPtr_t dstPtr, + RpptDescPtr dstDescPtr, + Rpp32s *srcLengthTensor, + Rpp32f *coeffTensor, + RpptAudioBorderType borderType, + rppHandle_t rppHandle) +{ + if ((srcDescPtr->dataType == RpptDataType::F32) && (dstDescPtr->dataType == RpptDataType::F32)) + { + pre_emphasis_filter_host_tensor(static_cast(srcPtr), + srcDescPtr, + static_cast(dstPtr), + dstDescPtr, + srcLengthTensor, + coeffTensor, + borderType, + rpp::deref(rppHandle)); + + return RPP_SUCCESS; + } + else + { + return RPP_ERROR_NOT_IMPLEMENTED; + } +} diff --git a/utilities/test_suite/HOST/Tensor_host_audio.cpp b/utilities/test_suite/HOST/Tensor_host_audio.cpp index 46a47cdfe..5d3ea57a9 100644 --- a/utilities/test_suite/HOST/Tensor_host_audio.cpp +++ b/utilities/test_suite/HOST/Tensor_host_audio.cpp @@ -177,6 +177,23 @@ int main(int argc, char **argv) break; } + case 2: + { + testCaseName = "pre_emphasis_filter"; + Rpp32f coeff[batchSize]; + for (int i = 0; i < batchSize; i++) + { + coeff[i] = 0.97; + dstDims[i].height = srcLengthTensor[i]; + dstDims[i].width = 1; + } + RpptAudioBorderType borderType = RpptAudioBorderType::CLAMP; + + startWallTime = omp_get_wtime(); + rppt_pre_emphasis_filter_host(inputf32, srcDescPtr, outputf32, dstDescPtr, srcLengthTensor, coeff, borderType, handle); + + break; + } default: { missingFuncFlag = 1; diff --git a/utilities/test_suite/HOST/runAudioTests.py b/utilities/test_suite/HOST/runAudioTests.py index cb78ae000..6d8f654c9 100644 --- a/utilities/test_suite/HOST/runAudioTests.py +++ b/utilities/test_suite/HOST/runAudioTests.py @@ -31,7 +31,7 @@ scriptPath = os.path.dirname(os.path.realpath(__file__)) inFilePath = scriptPath + "/../TEST_AUDIO_FILES/three_samples_single_channel_src1" caseMin = 0 -caseMax = 1 +caseMax = 2 # Checks if the folder path is empty, or is it a root folder, or if it exists, and remove its contents def validate_and_remove_files(path): @@ -234,7 +234,7 @@ def rpp_test_suite_parser_and_validator(): run_performance_test(loggingFolder, srcPath, case, numRuns, testType, batchSize, outFilePath) # print the results of qa tests -supportedCaseList = ['0', '1'] +supportedCaseList = ['0', '1', '2'] nonQACaseList = [] # Add cases present in supportedCaseList, but without QA support if testType == 0: diff --git a/utilities/test_suite/REFERENCE_OUTPUTS_AUDIO/pre_emphasis_filter/pre_emphasis_filter.bin b/utilities/test_suite/REFERENCE_OUTPUTS_AUDIO/pre_emphasis_filter/pre_emphasis_filter.bin new file mode 100644 index 000000000..b4403608f Binary files /dev/null and b/utilities/test_suite/REFERENCE_OUTPUTS_AUDIO/pre_emphasis_filter/pre_emphasis_filter.bin differ diff --git a/utilities/test_suite/rpp_test_suite_audio.h b/utilities/test_suite/rpp_test_suite_audio.h index 9af277d55..d47adc939 100644 --- a/utilities/test_suite/rpp_test_suite_audio.h +++ b/utilities/test_suite/rpp_test_suite_audio.h @@ -36,6 +36,7 @@ std::map audioAugmentationMap = { {0, "non_silent_region_detection"}, {1, "to_decibels"}, + {2, "pre_emphasis_filter"}, }; // Golden outputs for Non Silent Region Detection