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