From 0d9f61e61224034356939199e826a7248c648e9b Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sun, 1 Dec 2019 10:10:45 +0100 Subject: [PATCH] Added the hiir oversampling library --- src/external/hiir/StageDataNeon.h | 95 ++++++++++++ src/external/hiir/StageDataSse.h | 67 ++++++++ src/external/hiir/StageProc4Neon.h | 100 ++++++++++++ src/external/hiir/StageProc4Neon.hpp | 174 +++++++++++++++++++++ src/external/hiir/StageProc4Sse.h | 102 ++++++++++++ src/external/hiir/StageProc4Sse.hpp | 205 +++++++++++++++++++++++++ src/external/hiir/StageProcFpu.h | 98 ++++++++++++ src/external/hiir/StageProcFpu.hpp | 165 ++++++++++++++++++++ src/external/hiir/Upsampler2x4Neon.h | 114 ++++++++++++++ src/external/hiir/Upsampler2x4Neon.hpp | 205 +++++++++++++++++++++++++ src/external/hiir/Upsampler2x4Sse.h | 113 ++++++++++++++ src/external/hiir/Upsampler2x4Sse.hpp | 197 ++++++++++++++++++++++++ src/external/hiir/Upsampler2xFpu.h | 106 +++++++++++++ src/external/hiir/Upsampler2xFpu.hpp | 205 +++++++++++++++++++++++++ src/external/hiir/def.h | 61 ++++++++ src/external/hiir/fnc.h | 57 +++++++ src/external/hiir/fnc.hpp | 85 ++++++++++ 17 files changed, 2149 insertions(+) create mode 100644 src/external/hiir/StageDataNeon.h create mode 100644 src/external/hiir/StageDataSse.h create mode 100644 src/external/hiir/StageProc4Neon.h create mode 100644 src/external/hiir/StageProc4Neon.hpp create mode 100644 src/external/hiir/StageProc4Sse.h create mode 100644 src/external/hiir/StageProc4Sse.hpp create mode 100644 src/external/hiir/StageProcFpu.h create mode 100644 src/external/hiir/StageProcFpu.hpp create mode 100644 src/external/hiir/Upsampler2x4Neon.h create mode 100644 src/external/hiir/Upsampler2x4Neon.hpp create mode 100644 src/external/hiir/Upsampler2x4Sse.h create mode 100644 src/external/hiir/Upsampler2x4Sse.hpp create mode 100644 src/external/hiir/Upsampler2xFpu.h create mode 100644 src/external/hiir/Upsampler2xFpu.hpp create mode 100644 src/external/hiir/def.h create mode 100644 src/external/hiir/fnc.h create mode 100644 src/external/hiir/fnc.hpp diff --git a/src/external/hiir/StageDataNeon.h b/src/external/hiir/StageDataNeon.h new file mode 100644 index 00000000..7ec6fded --- /dev/null +++ b/src/external/hiir/StageDataNeon.h @@ -0,0 +1,95 @@ +/***************************************************************************** + + StageDataNeon.h + Author: Laurent de Soras, 2016 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#pragma once +#if ! defined (hiir_StageDataNeon_HEADER_INCLUDED) +#define hiir_StageDataNeon_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma warning (4 : 4250) +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include + + + +namespace hiir +{ + + + +class StageDataNeon +{ + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +public: + + union + { + __attribute__ ((aligned (16))) float32x4_t + _coef4; + __attribute__ ((aligned (16))) float + _coef [4]; // a_{4n+1}, a_{4n}, a_{4n+3}, a_{4n+2} + }; + union + { + __attribute__ ((aligned (16))) float32x4_t + _mem4; + __attribute__ ((aligned (16))) float + _mem [4]; // y of the stage + }; + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +protected: + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + + +/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + +}; // class StageDataNeon + + + +} // namespace hiir + + + +//#include "hiir/StageDataNeon.hpp" + + + +#endif // hiir_StageDataNeon_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/StageDataSse.h b/src/external/hiir/StageDataSse.h new file mode 100644 index 00000000..a1dfe929 --- /dev/null +++ b/src/external/hiir/StageDataSse.h @@ -0,0 +1,67 @@ +/***************************************************************************** + + StageDataSse.h + Author: Laurent de Soras, 2005 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_StageDataSse_HEADER_INCLUDED) +#define hiir_StageDataSse_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma once + #pragma warning (4 : 4250) // "Inherits via dominance." +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include + + + +namespace hiir +{ + + + +class StageDataSse +{ + +public: + + union + { + __m128 _coef4; // Just to ensure alignement + float _coef [4]; // a_{4n+1}, a_{4n}, a_{4n+3}, a_{4n+2} + }; + union + { + __m128 _mem4; + float _mem [4]; // y of the stage + }; + +}; // class StageDataSse + + + +} // namespace hiir + + + +#endif // hiir_StageDataSse_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/StageProc4Neon.h b/src/external/hiir/StageProc4Neon.h new file mode 100644 index 00000000..534cb9c5 --- /dev/null +++ b/src/external/hiir/StageProc4Neon.h @@ -0,0 +1,100 @@ +/***************************************************************************** + + StageProc4Neon.h + Author: Laurent de Soras, 2016 + +Template parameters: + - REMAINING: Number of remaining coefficients to process, >= 0 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#pragma once +#if ! defined (hiir_StageProc4Neon_HEADER_INCLUDED) +#define hiir_StageProc4Neon_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma warning (4 : 4250) +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/def.h" + + + +namespace hiir +{ + + + +class StageDataNeon; + +template +class StageProc4Neon +{ + static_assert (REMAINING >= 0, "REMAINING must be >= 0."); + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +public: + + static hiir_FORCEINLINE void + process_sample_pos (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr); + static hiir_FORCEINLINE void + process_sample_neg (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr); + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +protected: + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + + +/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + StageProc4Neon () = delete; + StageProc4Neon (const StageProc4Neon &other) = delete; + ~StageProc4Neon () = delete; + StageProc4Neon & + operator = (const StageProc4Neon &other) = delete; + bool operator == (const StageProc4Neon &other) const = delete; + bool operator != (const StageProc4Neon &other) const = delete; + +}; // class StageProc4Neon + + + +} // namespace hiir + + + +#include "hiir/StageProc4Neon.hpp" + + + +#endif // hiir_StageProc4Neon_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/StageProc4Neon.hpp b/src/external/hiir/StageProc4Neon.hpp new file mode 100644 index 00000000..72ce50ea --- /dev/null +++ b/src/external/hiir/StageProc4Neon.hpp @@ -0,0 +1,174 @@ +/***************************************************************************** + + StageProc4Neon.hpp + Author: Laurent de Soras, 2016 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_StageProc4Neon_CODEHEADER_INCLUDED) +#define hiir_StageProc4Neon_CODEHEADER_INCLUDED + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/StageDataNeon.h" + + + +namespace hiir +{ + + + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +template <> +inline void StageProc4Neon <1>::process_sample_pos (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr) +{ + const int cnt = nbr_coefs + 2 - 1; + + const float32x4_t tmp_0 = vmlaq_f32 ( + stage_arr [cnt - 2]._mem4, + spl_0 - stage_arr [cnt ]._mem4, + stage_arr [cnt ]._coef4 + ); + + stage_arr [cnt - 2]._mem4 = spl_0; + stage_arr [cnt - 1]._mem4 = spl_1; + stage_arr [cnt ]._mem4 = tmp_0; + + spl_0 = tmp_0; +} + + + +template <> +inline void StageProc4Neon <0>::process_sample_pos (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr) +{ + const int cnt = nbr_coefs + 2; + + stage_arr [cnt - 2]._mem4 = spl_0; + stage_arr [cnt - 1]._mem4 = spl_1; +} + + + +template +void StageProc4Neon ::process_sample_pos (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr) +{ + const int cnt = nbr_coefs + 2 - REMAINING; + + const float32x4_t tmp_0 = vmlaq_f32 ( + stage_arr [cnt - 2]._mem4, + spl_0 - stage_arr [cnt ]._mem4, + stage_arr [cnt ]._coef4 + ); + const float32x4_t tmp_1 = vmlaq_f32 ( + stage_arr [cnt - 1]._mem4, + spl_1 - stage_arr [cnt + 1]._mem4, + stage_arr [cnt + 1]._coef4 + ); + + stage_arr [cnt - 2]._mem4 = spl_0; + stage_arr [cnt - 1]._mem4 = spl_1; + + spl_0 = tmp_0; + spl_1 = tmp_1; + + StageProc4Neon ::process_sample_pos ( + nbr_coefs, + spl_0, + spl_1, + stage_arr + ); +} + + + +template <> +inline void StageProc4Neon <1>::process_sample_neg (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr) +{ + const int cnt = nbr_coefs + 2 - 1; + + float32x4_t tmp_0 = spl_0; + tmp_0 += stage_arr [cnt ]._mem4; + tmp_0 *= stage_arr [cnt ]._coef4; + tmp_0 -= stage_arr [cnt - 2]._mem4; + + stage_arr [cnt - 2]._mem4 = spl_0; + stage_arr [cnt - 1]._mem4 = spl_1; + stage_arr [cnt ]._mem4 = tmp_0; + + spl_0 = tmp_0; +} + +template <> +inline void StageProc4Neon <0>::process_sample_neg (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr) +{ + const int cnt = nbr_coefs + 2; + + stage_arr [cnt - 2]._mem4 = spl_0; + stage_arr [cnt - 1]._mem4 = spl_1; +} + +template +void StageProc4Neon ::process_sample_neg (const int nbr_coefs, float32x4_t &spl_0, float32x4_t &spl_1, StageDataNeon *stage_arr) +{ + const int cnt = nbr_coefs + 2 - REMAINING; + + float32x4_t tmp_0 = spl_0; + tmp_0 += stage_arr [cnt ]._mem4; + tmp_0 *= stage_arr [cnt ]._coef4; + tmp_0 -= stage_arr [cnt - 2]._mem4; + + float32x4_t tmp_1 = spl_1; + tmp_1 += stage_arr [cnt + 1]._mem4; + tmp_1 *= stage_arr [cnt + 1]._coef4; + tmp_1 -= stage_arr [cnt - 1]._mem4; + + stage_arr [cnt - 2]._mem4 = spl_0; + stage_arr [cnt - 1]._mem4 = spl_1; + + spl_0 = tmp_0; + spl_1 = tmp_1; + + StageProc4Neon ::process_sample_neg ( + nbr_coefs, + spl_0, + spl_1, + stage_arr + ); +} + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +} // namespace hiir + + + +#endif // hiir_StageProc4Neon_CODEHEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/StageProc4Sse.h b/src/external/hiir/StageProc4Sse.h new file mode 100644 index 00000000..4b697aa7 --- /dev/null +++ b/src/external/hiir/StageProc4Sse.h @@ -0,0 +1,102 @@ +/***************************************************************************** + + StageProc4Sse.h + Author: Laurent de Soras, 2015 + +Template parameters: + - REMAINING: Number of remaining coefficients to process, >= 0 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_StageProc4Sse_HEADER_INCLUDED) +#define hiir_StageProc4Sse_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma once + #pragma warning (4 : 4250) // "Inherits via dominance." +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/def.h" + +#include + + + +namespace hiir +{ + + + +class StageDataSse; + +template +class StageProc4Sse +{ + + static_assert ((REMAINING >= 0), "REMAINING must be >= 0"); + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +public: + + static hiir_FORCEINLINE void + process_sample_pos (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr); + static hiir_FORCEINLINE void + process_sample_neg (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr); + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +protected: + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + + +/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + StageProc4Sse (); + StageProc4Sse (const StageProc4Sse &other); + StageProc4Sse & + operator = (const StageProc4Sse &other); + bool operator == (const StageProc4Sse &other); + bool operator != (const StageProc4Sse &other); + +}; // class StageProc4Sse + + + +} // namespace hiir + + + +#include "hiir/StageProc4Sse.hpp" + + + +#endif // hiir_StageProc4Sse_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/StageProc4Sse.hpp b/src/external/hiir/StageProc4Sse.hpp new file mode 100644 index 00000000..1419e826 --- /dev/null +++ b/src/external/hiir/StageProc4Sse.hpp @@ -0,0 +1,205 @@ +/***************************************************************************** + + StageProc4Sse.hpp + Author: Laurent de Soras, 2015 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if defined (hiir_StageProc4Sse_CURRENT_CODEHEADER) + #error Recursive inclusion of StageProc4Sse code header. +#endif +#define hiir_StageProc4Sse_CURRENT_CODEHEADER + +#if ! defined (hiir_StageProc4Sse_CODEHEADER_INCLUDED) +#define hiir_StageProc4Sse_CODEHEADER_INCLUDED + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/StageDataSse.h" + + + +#if defined (_MSC_VER) + #pragma inline_depth (255) +#endif + + + +namespace hiir +{ + + + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +template <> +hiir_FORCEINLINE void StageProc4Sse <1>::process_sample_pos (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr) +{ + const int cnt = nbr_coefs + 2 - 1; + + const __m128 tmp_0 = _mm_add_ps ( + _mm_mul_ps ( + _mm_sub_ps (spl_0, _mm_load_ps (stage_arr [cnt ]._mem)), + _mm_load_ps (stage_arr [cnt ]._coef) + ), + _mm_load_ps (stage_arr [cnt - 2]._mem) + ); + + _mm_store_ps (stage_arr [cnt - 2]._mem, spl_0); + _mm_store_ps (stage_arr [cnt - 1]._mem, spl_1); + _mm_store_ps (stage_arr [cnt ]._mem, tmp_0); + + spl_0 = tmp_0; +} + + + +template <> +hiir_FORCEINLINE void StageProc4Sse <0>::process_sample_pos (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr) +{ + const int cnt = nbr_coefs + 2; + + _mm_store_ps (stage_arr [cnt - 2]._mem, spl_0); + _mm_store_ps (stage_arr [cnt - 1]._mem, spl_1); +} + + + +template +void StageProc4Sse ::process_sample_pos (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr) +{ + const int cnt = nbr_coefs + 2 - REMAINING; + + const __m128 tmp_0 = _mm_add_ps ( + _mm_mul_ps ( + _mm_sub_ps (spl_0, _mm_load_ps (stage_arr [cnt ]._mem)), + _mm_load_ps (stage_arr [cnt ]._coef) + ), + _mm_load_ps (stage_arr [cnt - 2]._mem) + ); + const __m128 tmp_1 = _mm_add_ps ( + _mm_mul_ps ( + _mm_sub_ps (spl_1, _mm_load_ps (stage_arr [cnt + 1]._mem)), + _mm_load_ps (stage_arr [cnt + 1]._coef) + ), + _mm_load_ps (stage_arr [cnt - 1]._mem) + ); + + _mm_store_ps (stage_arr [cnt - 2]._mem, spl_0); + _mm_store_ps (stage_arr [cnt - 1]._mem, spl_1); + + spl_0 = tmp_0; + spl_1 = tmp_1; + + StageProc4Sse ::process_sample_pos ( + nbr_coefs, + spl_0, + spl_1, + stage_arr + ); +} + + + +template <> +hiir_FORCEINLINE void StageProc4Sse <1>::process_sample_neg (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr) +{ + const int cnt = nbr_coefs + 2 - 1; + + const __m128 tmp_0 = _mm_sub_ps ( + _mm_mul_ps ( + _mm_add_ps (spl_0, _mm_load_ps (stage_arr [cnt ]._mem)), + _mm_load_ps (stage_arr [cnt ]._coef) + ), + _mm_load_ps (stage_arr [cnt - 2]._mem) + ); + + _mm_store_ps (stage_arr [cnt - 2]._mem, spl_0); + _mm_store_ps (stage_arr [cnt - 1]._mem, spl_1); + _mm_store_ps (stage_arr [cnt ]._mem, tmp_0); + + spl_0 = tmp_0; +} + + + +template <> +hiir_FORCEINLINE void StageProc4Sse <0>::process_sample_neg (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr) +{ + const int cnt = nbr_coefs + 2; + + _mm_store_ps (stage_arr [cnt - 2]._mem, spl_0); + _mm_store_ps (stage_arr [cnt - 1]._mem, spl_1); +} + + + +template +void StageProc4Sse ::process_sample_neg (const int nbr_coefs, __m128 &spl_0, __m128 &spl_1, StageDataSse *stage_arr) +{ + const int cnt = nbr_coefs + 2 - REMAINING; + + const __m128 tmp_0 = _mm_sub_ps ( + _mm_mul_ps ( + _mm_add_ps (spl_0, _mm_load_ps (stage_arr [cnt ]._mem)), + _mm_load_ps (stage_arr [cnt ]._coef) + ), + _mm_load_ps (stage_arr [cnt - 2]._mem) + ); + const __m128 tmp_1 = _mm_sub_ps ( + _mm_mul_ps ( + _mm_add_ps (spl_1, _mm_load_ps (stage_arr [cnt + 1]._mem)), + _mm_load_ps (stage_arr [cnt + 1]._coef) + ), + _mm_load_ps (stage_arr [cnt - 1]._mem) + ); + + _mm_store_ps (stage_arr [cnt - 2]._mem, spl_0); + _mm_store_ps (stage_arr [cnt - 1]._mem, spl_1); + + spl_0 = tmp_0; + spl_1 = tmp_1; + + StageProc4Sse ::process_sample_neg ( + nbr_coefs, + spl_0, + spl_1, + stage_arr + ); +} + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +} // namespace hiir + + + +#endif // hiir_StageProc4Sse_CODEHEADER_INCLUDED + +#undef hiir_StageProc4Sse_CURRENT_CODEHEADER + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/StageProcFpu.h b/src/external/hiir/StageProcFpu.h new file mode 100644 index 00000000..8cdeab71 --- /dev/null +++ b/src/external/hiir/StageProcFpu.h @@ -0,0 +1,98 @@ +/***************************************************************************** + + StageProcFpu.h + Author: Laurent de Soras, 2005 + +Template parameters: + - REMAINING: Number of remaining coefficients to process, >= 0 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_StageProc_HEADER_INCLUDED) +#define hiir_StageProc_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma once + #pragma warning (4 : 4250) // "Inherits via dominance." +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/def.h" + + + +namespace hiir +{ + + + +template +class StageProcFpu +{ + + static_assert ((REMAINING >= 0), "REMAINING must be >= 0"); + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +public: + + static hiir_FORCEINLINE void + process_sample_pos (const int nbr_coefs, float &spl_0, float &spl_1, const float coef [], float x [], float y []); + static hiir_FORCEINLINE void + process_sample_neg (const int nbr_coefs, float &spl_0, float &spl_1, const float coef [], float x [], float y []); + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +protected: + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + + +/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + StageProcFpu (); + StageProcFpu (const StageProcFpu &other); + StageProcFpu & + operator = (const StageProcFpu &other); + bool operator == (const StageProcFpu &other); + bool operator != (const StageProcFpu &other); + +}; // class StageProcFpu + + + +} // namespace hiir + + + +#include "hiir/StageProcFpu.hpp" + + + +#endif // hiir_StageProc_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/StageProcFpu.hpp b/src/external/hiir/StageProcFpu.hpp new file mode 100644 index 00000000..9fc1c018 --- /dev/null +++ b/src/external/hiir/StageProcFpu.hpp @@ -0,0 +1,165 @@ +/***************************************************************************** + + StageProcFpu.hpp + Author: Laurent de Soras, 2005 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if defined (hiir_StageProc_CURRENT_CODEHEADER) + #error Recursive inclusion of StageProcFpu code header. +#endif +#define hiir_StageProc_CURRENT_CODEHEADER + +#if ! defined (hiir_StageProc_CODEHEADER_INCLUDED) +#define hiir_StageProc_CODEHEADER_INCLUDED + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#if defined (_MSC_VER) + #pragma inline_depth (255) +#endif + + + +namespace hiir +{ + + + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +template <> +hiir_FORCEINLINE void StageProcFpu <1>::process_sample_pos (const int nbr_coefs, float &spl_0, float &/*spl_1*/, const float coef [], float x [], float y []) +{ + const int last = nbr_coefs - 1; + const float temp = (spl_0 - y [last]) * coef [last] + x [last]; + x [last] = spl_0; + y [last] = temp; + spl_0 = temp; +} + + + +template <> +hiir_FORCEINLINE void StageProcFpu <0>::process_sample_pos (const int /*nbr_coefs*/, float &/*spl_0*/, float &/*spl_1*/, const float /*coef*/ [], float /*x*/ [], float /*y*/ []) +{ + // Nothing (stops recursion) +} + + + +template +void StageProcFpu ::process_sample_pos (const int nbr_coefs, float &spl_0, float &spl_1, const float coef [], float x [], float y []) +{ + const int cnt = nbr_coefs - REMAINING; + + const float temp_0 = + (spl_0 - y [cnt + 0]) * coef [cnt + 0] + x [cnt + 0]; + const float temp_1 = + (spl_1 - y [cnt + 1]) * coef [cnt + 1] + x [cnt + 1]; + + x [cnt + 0] = spl_0; + x [cnt + 1] = spl_1; + + y [cnt + 0] = temp_0; + y [cnt + 1] = temp_1; + + spl_0 = temp_0; + spl_1 = temp_1; + + StageProcFpu ::process_sample_pos ( + nbr_coefs, + spl_0, + spl_1, + &coef [0], + &x [0], + &y [0] + ); +} + + + +template <> +hiir_FORCEINLINE void StageProcFpu <1>::process_sample_neg (const int nbr_coefs, float &spl_0, float &/*spl_1*/, const float coef [], float x [], float y []) +{ + const int last = nbr_coefs - 1; + const float temp = (spl_0 + y [last]) * coef [last] - x [last]; + x [last] = spl_0; + y [last] = temp; + spl_0 = temp; +} + + + +template <> +hiir_FORCEINLINE void StageProcFpu <0>::process_sample_neg (const int /*nbr_coefs*/, float &/*spl_0*/, float &/*spl_1*/, const float /*coef*/ [], float /*x*/ [], float /*y*/ []) +{ + // Nothing (stops recursion) +} + + + +template +void StageProcFpu ::process_sample_neg (const int nbr_coefs, float &spl_0, float &spl_1, const float coef [], float x [], float y []) +{ + const int cnt = nbr_coefs - REMAINING; + + const float temp_0 = + (spl_0 + y [cnt + 0]) * coef [cnt + 0] - x [cnt + 0]; + const float temp_1 = + (spl_1 + y [cnt + 1]) * coef [cnt + 1] - x [cnt + 1]; + + x [cnt + 0] = spl_0; + x [cnt + 1] = spl_1; + + y [cnt + 0] = temp_0; + y [cnt + 1] = temp_1; + + spl_0 = temp_0; + spl_1 = temp_1; + + StageProcFpu ::process_sample_neg ( + nbr_coefs, + spl_0, + spl_1, + &coef [0], + &x [0], + &y [0] + ); +} + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +} // namespace hiir + + + +#endif // hiir_StageProc_CODEHEADER_INCLUDED + +#undef hiir_StageProc_CURRENT_CODEHEADER + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/Upsampler2x4Neon.h b/src/external/hiir/Upsampler2x4Neon.h new file mode 100644 index 00000000..aeb56751 --- /dev/null +++ b/src/external/hiir/Upsampler2x4Neon.h @@ -0,0 +1,114 @@ +/***************************************************************************** + + Upsampler2x4Neon.h + Author: Laurent de Soras, 2016 + +Upsamples vectors of 4 float by a factor 2 the input signal, using the NEON +instruction set. + +This object must be aligned on a 16-byte boundary! + +Template parameters: + - NC: number of coefficients, > 0 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#pragma once +#if ! defined (hiir_Upsampler2x4Neon_HEADER_INCLUDED) +#define hiir_Upsampler2x4Neon_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma warning (4 : 4250) +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/def.h" +#include "hiir/StageDataNeon.h" + +#include + +#include + + + +namespace hiir +{ + + + +template +class Upsampler2x4Neon +{ + + static_assert ((NC > 0), "Number of coefficient must be positive."); + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +public: + + enum { NBR_COEFS = NC }; + + Upsampler2x4Neon (); + + void set_coefs (const double coef_arr [NBR_COEFS]); + hiir_FORCEINLINE void + process_sample (float32x4_t &out_0, float32x4_t &out_1, float32x4_t input); + void process_block (float out_ptr [], const float in_ptr [], long nbr_spl); + void clear_buffers (); + + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +protected: + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + typedef std::array Filter; // Stages 0 and 1 contain only input memories + + Filter _filter; // Should be the first member (thus easier to align) + + + +/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + bool operator == (const Upsampler2x4Neon &other) const = delete; + bool operator != (const Upsampler2x4Neon &other) const = delete; + +}; // class Upsampler2x4Neon + + + +} // namespace hiir + + + +#include "hiir/Upsampler2x4Neon.hpp" + + + +#endif // hiir_Upsampler2x4Neon_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/Upsampler2x4Neon.hpp b/src/external/hiir/Upsampler2x4Neon.hpp new file mode 100644 index 00000000..6304ed15 --- /dev/null +++ b/src/external/hiir/Upsampler2x4Neon.hpp @@ -0,0 +1,205 @@ +/***************************************************************************** + + Upsampler2x4Neon.hpp + Author: Laurent de Soras, 2016 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_Upsampler2x4Neon_CODEHEADER_INCLUDED) +#define hiir_Upsampler2x4Neon_CODEHEADER_INCLUDED + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/StageProc4Neon.h" + +#include + + + +namespace hiir +{ + + + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/* +============================================================================== +Name: ctor +Throws: Nothing +============================================================================== +*/ + +template +Upsampler2x4Neon ::Upsampler2x4Neon () +: _filter () +{ + for (int i = 0; i < NBR_COEFS + 2; ++i) + { + _filter [i]._coef4 = vdupq_n_f32 (0); + } + + clear_buffers (); +} + + + +/* +============================================================================== +Name: set_coefs +Description: + Sets filter coefficients. Generate them with the PolyphaseIir2Designer + class. + Call this function before doing any processing. +Input parameters: + - coef_arr: Array of coefficients. There should be as many coefficients as + mentioned in the class template parameter. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Neon ::set_coefs (const double coef_arr [NBR_COEFS]) +{ + assert (coef_arr != 0); + + for (int i = 0; i < NBR_COEFS; ++i) + { + _filter [i + 2]._coef4 = vdupq_n_f32 (float (coef_arr [i])); + } +} + + + +/* +============================================================================== +Name: process_sample +Description: + Upsamples (x2) the input vector, generating two output vectors. +Input parameters: + - input: The input vector. +Output parameters: + - out_0: First output vector. + - out_1: Second output vector. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Neon ::process_sample (float32x4_t &out_0, float32x4_t &out_1, float32x4_t input) +{ + float32x4_t even = input; + float32x4_t odd = input; + StageProc4Neon ::process_sample_pos ( + NBR_COEFS, + even, + odd, + &_filter [0] + ); + out_0 = even; + out_1 = odd; +} + + + +/* +============================================================================== +Name: process_block +Description: + Upsamples (x2) the input vector block. + Input and output blocks may overlap, see assert() for details. +Input parameters: + - in_ptr: Input array, containing nbr_spl vector. + No alignment constraint. + - nbr_spl: Number of input vectors to process, > 0 +Output parameters: + - out_0_ptr: Output vector array, capacity: nbr_spl * 2 vectors. + No alignment constraint. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Neon ::process_block (float out_ptr [], const float in_ptr [], long nbr_spl) +{ + assert (out_ptr != 0); + assert (in_ptr != 0); + assert (out_ptr >= in_ptr + nbr_spl * 4 || in_ptr >= out_ptr + nbr_spl * 4); + assert (nbr_spl > 0); + + long pos = 0; + do + { + const float32x4_t src = vreinterpretq_f32_u8 ( + vld1q_u8 (reinterpret_cast (in_ptr + pos * 4)) + ); + float32x4_t dst_0; + float32x4_t dst_1; + process_sample (dst_0, dst_1, src); + vst1q_u8 ( + reinterpret_cast (out_ptr + pos * 8 ), + vreinterpretq_u8_f32 (dst_0) + ); + vst1q_u8 ( + reinterpret_cast (out_ptr + pos * 8 + 4), + vreinterpretq_u8_f32 (dst_1) + ); + ++ pos; + } + while (pos < nbr_spl); +} + + + +/* +============================================================================== +Name: clear_buffers +Description: + Clears filter memory, as if it processed silence since an infinite amount + of time. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Neon ::clear_buffers () +{ + for (int i = 0; i < NBR_COEFS + 2; ++i) + { + _filter [i]._mem4 = vdupq_n_f32 (0); + } +} + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +} // namespace hiir + + + +#endif // hiir_Upsampler2x4Neon_CODEHEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/Upsampler2x4Sse.h b/src/external/hiir/Upsampler2x4Sse.h new file mode 100644 index 00000000..629abc07 --- /dev/null +++ b/src/external/hiir/Upsampler2x4Sse.h @@ -0,0 +1,113 @@ +/***************************************************************************** + + Upsampler2x4Sse.h + Author: Laurent de Soras, 2015 + +Upsamples vectors of 4 float by a factor 2 the input signal, using the SSE +instruction set. + +This object must be aligned on a 16-byte boundary! + +Template parameters: + - NC: number of coefficients, > 0 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#pragma once +#if ! defined (hiir_Upsampler2x4Sse_HEADER_INCLUDED) +#define hiir_Upsampler2x4Sse_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma warning (4 : 4250) +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/def.h" +#include "hiir/StageDataSse.h" + +#include + +#include + + + +namespace hiir +{ + + + +template +class Upsampler2x4Sse +{ + + static_assert ((NC > 0), "Number of coefficient must be positive."); + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +public: + + enum { NBR_COEFS = NC }; + + Upsampler2x4Sse (); + + void set_coefs (const double coef_arr [NBR_COEFS]); + hiir_FORCEINLINE void + process_sample (__m128 &out_0, __m128 &out_1, __m128 input); + void process_block (float out_ptr [], const float in_ptr [], long nbr_spl); + void clear_buffers (); + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +protected: + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + typedef std::array Filter; // Stages 0 and 1 contain only input memories + + Filter _filter; // Should be the first member (thus easier to align) + + + +/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + bool operator == (const Upsampler2x4Sse &other) const; + bool operator != (const Upsampler2x4Sse &other) const; + +}; // class Upsampler2x4Sse + + + +} // namespace hiir + + + +#include "hiir/Upsampler2x4Sse.hpp" + + + +#endif // hiir_Upsampler2x4Sse_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/Upsampler2x4Sse.hpp b/src/external/hiir/Upsampler2x4Sse.hpp new file mode 100644 index 00000000..9228894a --- /dev/null +++ b/src/external/hiir/Upsampler2x4Sse.hpp @@ -0,0 +1,197 @@ +/***************************************************************************** + + Upsampler2x4Sse.hpp + Author: Laurent de Soras, 2015 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_Upsampler2x4Sse_CODEHEADER_INCLUDED) +#define hiir_Upsampler2x4Sse_CODEHEADER_INCLUDED + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/StageProc4Sse.h" + +#include + + + +namespace hiir +{ + + + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/* +============================================================================== +Name: ctor +Throws: Nothing +============================================================================== +*/ + +template +Upsampler2x4Sse ::Upsampler2x4Sse () +: _filter () +{ + for (int i = 0; i < NBR_COEFS + 2; ++i) + { + _mm_store_ps (_filter [i]._coef, _mm_setzero_ps ()); + } + + clear_buffers (); +} + + + +/* +============================================================================== +Name: set_coefs +Description: + Sets filter coefficients. Generate them with the PolyphaseIir2Designer + class. + Call this function before doing any processing. +Input parameters: + - coef_arr: Array of coefficients. There should be as many coefficients as + mentioned in the class template parameter. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Sse ::set_coefs (const double coef_arr [NBR_COEFS]) +{ + assert (coef_arr != 0); + + for (int i = 0; i < NBR_COEFS; ++i) + { + _mm_store_ps (_filter [i + 2]._coef, _mm_set1_ps (float (coef_arr [i]))); + } +} + + + +/* +============================================================================== +Name: process_sample +Description: + Upsamples (x2) the input vector, generating two output vectors. +Input parameters: + - input: The input vector. +Output parameters: + - out_0: First output vector. + - out_1: Second output vector. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Sse ::process_sample (__m128 &out_0, __m128 &out_1, __m128 input) +{ + __m128 even = input; + __m128 odd = input; + StageProc4Sse ::process_sample_pos ( + NBR_COEFS, + even, + odd, + &_filter [0] + ); + out_0 = even; + out_1 = odd; +} + + + +/* +============================================================================== +Name: process_block +Description: + Upsamples (x2) the input vector block. + Input and output blocks may overlap, see assert() for details. +Input parameters: + - in_ptr: Input array, containing nbr_spl vector. + No alignment constraint. + - nbr_spl: Number of input vectors to process, > 0 +Output parameters: + - out_0_ptr: Output vector array, capacity: nbr_spl * 2 vectors. + No alignment constraint. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Sse ::process_block (float out_ptr [], const float in_ptr [], long nbr_spl) +{ + assert (out_ptr != 0); + assert (in_ptr != 0); + assert (out_ptr >= in_ptr + nbr_spl * 4 || in_ptr >= out_ptr + nbr_spl * 4); + assert (nbr_spl > 0); + + long pos = 0; + do + { + __m128 dst_0; + __m128 dst_1; + const __m128 src = _mm_loadu_ps (in_ptr + pos * 4); + process_sample (dst_0, dst_1, src); + _mm_storeu_ps (out_ptr + pos * 8 , dst_0); + _mm_storeu_ps (out_ptr + pos * 8 + 4, dst_1); + ++ pos; + } + while (pos < nbr_spl); +} + + + +/* +============================================================================== +Name: clear_buffers +Description: + Clears filter memory, as if it processed silence since an infinite amount + of time. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2x4Sse ::clear_buffers () +{ + for (int i = 0; i < NBR_COEFS + 2; ++i) + { + _mm_store_ps (_filter [i]._mem, _mm_setzero_ps ()); + } +} + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +} // namespace hiir + + + +#endif // hiir_Upsampler2x4Sse_CODEHEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/Upsampler2xFpu.h b/src/external/hiir/Upsampler2xFpu.h new file mode 100644 index 00000000..78de9cd8 --- /dev/null +++ b/src/external/hiir/Upsampler2xFpu.h @@ -0,0 +1,106 @@ +/***************************************************************************** + + Upsampler2xFpu.h + Author: Laurent de Soras, 2005 + +Upsamples by a factor 2 the input signal, using FPU. + +Template parameters: + - NC: number of coefficients, > 0 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_Upsampler2xFpu_HEADER_INCLUDED) +#define hiir_Upsampler2xFpu_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma once + #pragma warning (4 : 4250) // "Inherits via dominance." +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include + + + +namespace hiir +{ + + + +template +class Upsampler2xFpu +{ + + static_assert ((NC > 0), "Number of coefficient must be positive."); + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +public: + + enum { NBR_COEFS = NC }; + + Upsampler2xFpu (); + + void set_coefs (const double coef_arr [NBR_COEFS]); + inline void process_sample (float &out_0, float &out_1, float input); + void process_block (float out_ptr [], const float in_ptr [], long nbr_spl); + void clear_buffers (); + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +protected: + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + typedef std::array HyperGluar; + + HyperGluar _coef; + HyperGluar _x; + HyperGluar _y; + + + +/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +private: + + bool operator == (const Upsampler2xFpu &other); + bool operator != (const Upsampler2xFpu &other); + +}; // class Upsampler2xFpu + + + +} // namespace hiir + + + +#include "hiir/Upsampler2xFpu.hpp" + + + +#endif // hiir_Upsampler2xFpu_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/Upsampler2xFpu.hpp b/src/external/hiir/Upsampler2xFpu.hpp new file mode 100644 index 00000000..79fb05ef --- /dev/null +++ b/src/external/hiir/Upsampler2xFpu.hpp @@ -0,0 +1,205 @@ +/***************************************************************************** + + Upsampler2xFpu.hpp + Author: Laurent de Soras, 2005 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if defined (hiir_Upsampler2xFpu_CURRENT_CODEHEADER) + #error Recursive inclusion of Upsampler2xFpu code header. +#endif +#define hiir_Upsampler2xFpu_CURRENT_CODEHEADER + +#if ! defined (hiir_Upsampler2xFpu_CODEHEADER_INCLUDED) +#define hiir_Upsampler2xFpu_CODEHEADER_INCLUDED + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include "hiir/StageProcFpu.h" + +#include + + + +namespace hiir +{ + + + +/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/* +============================================================================== +Name: ctor +Throws: Nothing +============================================================================== +*/ + +template +Upsampler2xFpu ::Upsampler2xFpu () +: _coef () +, _x () +, _y () +{ + for (int i = 0; i < NBR_COEFS; ++i) + { + _coef [i] = 0; + } + clear_buffers (); +} + + + +/* +============================================================================== +Name: set_coefs +Description: + Sets filter coefficients. Generate them with the PolyphaseIir2Designer + class. + Call this function before doing any processing. +Input parameters: + - coef_arr: Array of coefficients. There should be as many coefficients as + mentioned in the class template parameter. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2xFpu ::set_coefs (const double coef_arr [NBR_COEFS]) +{ + assert (coef_arr != 0); + + for (int i = 0; i < NBR_COEFS; ++i) + { + _coef [i] = float (coef_arr [i]); + } +} + + + +/* +============================================================================== +Name: process_sample +Description: + Upsamples (x2) the input sample, generating two output samples. +Input parameters: + - input: The input sample. +Output parameters: + - out_0: First output sample. + - out_1: Second output sample. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2xFpu ::process_sample (float &out_0, float &out_1, float input) +{ + float even = input; + float odd = input; + StageProcFpu ::process_sample_pos ( + NBR_COEFS, + even, + odd, + &_coef [0], + &_x [0], + &_y [0] + ); + out_0 = even; + out_1 = odd; +} + + + +/* +============================================================================== +Name: process_block +Description: + Upsamples (x2) the input sample block. + Input and output blocks may overlap, see assert() for details. +Input parameters: + - in_ptr: Input array, containing nbr_spl samples. + - nbr_spl: Number of input samples to process, > 0 +Output parameters: + - out_0_ptr: Output sample array, capacity: nbr_spl * 2 samples. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2xFpu ::process_block (float out_ptr [], const float in_ptr [], long nbr_spl) +{ + assert (out_ptr != 0); + assert (in_ptr != 0); + assert (out_ptr >= in_ptr + nbr_spl || in_ptr >= out_ptr + nbr_spl); + assert (nbr_spl > 0); + + long pos = 0; + do + { + process_sample ( + out_ptr [pos * 2 ], + out_ptr [pos * 2 + 1], + in_ptr [pos] + ); + ++ pos; + } + while (pos < nbr_spl); +} + + + +/* +============================================================================== +Name: clear_buffers +Description: + Clears filter memory, as if it processed silence since an infinite amount + of time. +Throws: Nothing +============================================================================== +*/ + +template +void Upsampler2xFpu ::clear_buffers () +{ + for (int i = 0; i < NBR_COEFS; ++i) + { + _x [i] = 0; + _y [i] = 0; + } +} + + + +/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +} // namespace hiir + + + +#endif // hiir_Upsampler2xFpu_CODEHEADER_INCLUDED + +#undef hiir_Upsampler2xFpu_CURRENT_CODEHEADER + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/def.h b/src/external/hiir/def.h new file mode 100644 index 00000000..f91e2bc0 --- /dev/null +++ b/src/external/hiir/def.h @@ -0,0 +1,61 @@ +/***************************************************************************** + + def.h + Author: Laurent de Soras, 2005 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_def_HEADER_INCLUDED) +#define hiir_def_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma once + #pragma warning (4 : 4250) // "Inherits via dominance." +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +namespace hiir +{ + + + +const double PI = 3.1415926535897932384626433832795; + + + +#if defined (_MSC_VER) + + #define hiir_FORCEINLINE __forceinline + +#else + + #define hiir_FORCEINLINE inline + +#endif + + + +} // namespace hiir + + + +#endif // hiir_def_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/fnc.h b/src/external/hiir/fnc.h new file mode 100644 index 00000000..f4825e74 --- /dev/null +++ b/src/external/hiir/fnc.h @@ -0,0 +1,57 @@ +/***************************************************************************** + + fnc.h + Author: Laurent de Soras, 2005 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if ! defined (hiir_fnc_HEADER_INCLUDED) +#define hiir_fnc_HEADER_INCLUDED + +#if defined (_MSC_VER) + #pragma once + #pragma warning (4 : 4250) // "Inherits via dominance." +#endif + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + + + +namespace hiir +{ + + + +inline int round_int (double x); +inline int ceil_int (double x); + +template +T ipowp (T x, long n); + + + +} // namespace hiir + + + +#include "hiir/fnc.hpp" + + + +#endif // hiir_fnc_HEADER_INCLUDED + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ diff --git a/src/external/hiir/fnc.hpp b/src/external/hiir/fnc.hpp new file mode 100644 index 00000000..76db475e --- /dev/null +++ b/src/external/hiir/fnc.hpp @@ -0,0 +1,85 @@ +/***************************************************************************** + + fnc.hpp + Author: Laurent de Soras, 2005 + +--- Legal stuff --- + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + +*Tab=3***********************************************************************/ + + + +#if defined (hiir_fnc_CURRENT_CODEHEADER) + #error Recursive inclusion of fnc code header. +#endif +#define hiir_fnc_CURRENT_CODEHEADER + +#if ! defined (hiir_fnc_CODEHEADER_INCLUDED) +#define hiir_fnc_CODEHEADER_INCLUDED + + + +/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +#include +#include + + + +namespace hiir +{ + + + +int round_int (double x) +{ + return int (floor (x + 0.5)); +} + + + +int ceil_int (double x) +{ + return int (ceil (x)); +} + + + +template +T ipowp (T x, long n) +{ + assert (n >= 0); + + T z (1); + while (n != 0) + { + if ((n & 1) != 0) + { + z *= x; + } + n >>= 1; + x *= x; + } + + return z; +} + + + +} // namespace hiir + + + +#endif // hiir_fnc_CODEHEADER_INCLUDED + +#undef hiir_fnc_CURRENT_CODEHEADER + + + +/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/