/* SPDX-License-Identifier: BSD-3-Clause * * Copyright(c) 2016 - 2023 Intel Corporation. All rights reserved. * * Author: Seppo Ingalsuo * Liam Girdwood * Keyon Jie */ #ifndef __SOF_AUDIO_FORMAT_H__ #define __SOF_AUDIO_FORMAT_H__ #if defined __XCC__ #include #if XCHAL_HAVE_HIFI3 == 1 #define __AUDIO_FORMAT_GENERIC__ 0 #define __AUDIO_FORMAT_HIFI3__ 1 #else /* Generic build for e.g. hifi2 */ #define __AUDIO_FORMAT_GENERIC__ 1 #define __AUDIO_FORMAT_HIFI3__ 0 #endif /* !XCHAL_HAVE_HIFI3 */ #else /* GCC */ #define __AUDIO_FORMAT_GENERIC__ 1 #define __AUDIO_FORMAT_HIFI3__ 0 #endif /* !__XCC__ */ #include #include /* Maximum and minimum values for 24 bit */ #define INT24_MAXVALUE 8388607 #define INT24_MINVALUE -8388608 /* Collection of common fractional numbers */ #define ONE_Q2_30 1073741824 /* Q2.30 1.0 */ #define ONE_Q1_31 2147483647 /* Q1.31 ~1.0 */ #define MINUS_3DB_Q1_31 1520301996 /* 10^(-3/20) */ #define MINUS_6DB_Q1_31 1076291389 /* 10^(-6/20) */ #define MINUS_10DB_Q1_31 679093957 /* 10^(-10/20) */ #define MINUS_20DB_Q1_31 214748365 /* 10^(-20/20) */ #define MINUS_30DB_Q1_31 67909396 /* 10^(-30/20) */ #define MINUS_40DB_Q1_31 21474836 /* 10^(-40/20) */ #define MINUS_50DB_Q1_31 6790940 /* 10^(-50/20) */ #define MINUS_60DB_Q1_31 2147484 /* 10^(-60/20) */ #define MINUS_70DB_Q1_31 679094 /* 10^(-70/20) */ #define MINUS_80DB_Q1_31 214748 /* 10^(-80/20) */ #define MINUS_90DB_Q1_31 67909 /* 10^(-90/20) */ /* Compute the number of shifts * This will result in a compiler overflow error if shift bits are out of * range as INT64_MAX/MIN is greater than 32 bit Q shift parameter */ #define Q_SHIFT_BITS_64(qx, qy, qz) \ ((qx + qy - qz) <= 63 ? (((qx + qy - qz) >= 0) ? \ (qx + qy - qz) : INT64_MIN) : INT64_MAX) #define Q_SHIFT_BITS_32(qx, qy, qz) \ ((qx + qy - qz) <= 31 ? (((qx + qy - qz) >= 0) ? \ (qx + qy - qz) : INT32_MIN) : INT32_MAX) /* Convert a float number to fractional Qnx.ny format. Note that there is no * check for nx+ny number of bits to fit the word length of int. The parameter * qy must be 31 or less. */ #define Q_CONVERT_FLOAT(f, qy) \ ((int32_t)(((const double)f) * ((int64_t)1 << (const int)qy) + 0.5)) /* Convert fractional Qnx.ny number x to float */ #define Q_CONVERT_QTOF(x, ny) ((float)(x) / ((int64_t)1 << (ny))) /* A more clever macro for Q-shifts */ #define Q_SHIFT(x, src_q, dst_q) ((x) >> ((src_q) - (dst_q))) #define Q_SHIFT_RND(x, src_q, dst_q) \ ((((x) >> ((src_q) - (dst_q) - 1)) + 1) >> 1) /* Alternative version since compiler does not allow (x >> -1) */ #define Q_SHIFT_LEFT(x, src_q, dst_q) ((x) << ((dst_q) - (src_q))) /* Fractional multiplication with shift * Note that the parameters px and py must be cast to (int32_t) if other type. */ #define Q_MULTS_16X16(px, py, qx, qy, qp) \ ((px) * (py) >> (((qx) + (qy) - (qp)))) /* Fractional multiplication with shift and round * Note that the parameters px and py must be cast to (int32_t) if other type. */ #define Q_MULTSR_16X16(px, py, qx, qy, qp) \ ((((px) * (py) >> ((qx) + (qy) - (qp) - 1)) + 1) >> 1) /* Fractional multiplication with shift * Note that the parameters px and py must be cast to (int64_t) if other type. */ #define Q_MULTS_32X32(px, py, qx, qy, qp) \ ((px) * (py) >> (((qx) + (qy) - (qp)))) /* Fractional multiplication with shift and round * Note that the parameters px and py must be cast to (int64_t) if other type. */ #define Q_MULTSR_32X32(px, py, qx, qy, qp) \ ((((px) * (py) >> ((qx) + (qy) - (qp) - 1)) + 1) >> 1) /* Saturation */ #define SATP_INT32(x) (((x) > INT32_MAX) ? INT32_MAX : (x)) #define SATM_INT32(x) (((x) < INT32_MIN) ? INT32_MIN : (x)) /* Inline functions */ #if __AUDIO_FORMAT_GENERIC__ #include "format_generic.h" #endif #if __AUDIO_FORMAT_HIFI3__ #include "format_hifi3.h" #endif static inline int64_t q_mults_32x32(int32_t x, int32_t y, const int shift_bits) { return ((int64_t)x * y) >> shift_bits; } static inline int64_t q_multsr_32x32(int32_t x, int32_t y, const int shift_bits) { return ((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1; } static inline int32_t q_mults_16x16(int16_t x, int32_t y, const int shift_bits) { return ((int32_t)x * y) >> shift_bits; } static inline int16_t q_multsr_16x16(int16_t x, int32_t y, const int shift_bits) { return ((((int32_t)x * y) >> (shift_bits - 1)) + 1) >> 1; } /* Fractional multiplication with shift and saturation */ static inline int32_t q_multsr_sat_32x32(int32_t x, int32_t y, const int shift_bits) { return sat_int32(((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1); } static inline int32_t q_multsr_sat_32x32_24(int32_t x, int32_t y, const int shift_bits) { return sat_int24(((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1); } static inline int32_t q_multsr_sat_32x32_16(int32_t x, int32_t y, const int shift_bits) { return sat_int16(((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1); } static inline int16_t q_multsr_sat_16x16(int16_t x, int32_t y, const int shift_bits) { return sat_int16(((((int32_t)x * y) >> (shift_bits - 1)) + 1) >> 1); } static inline int32_t sign_extend_s24(int32_t x) { return (x << 8) >> 8; } #endif /* __SOF_AUDIO_FORMAT_H__ */