forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Audio: Use generic saturation logic for improved efficiency
This check-in refactors saturation functions to use bitwise operations for handling overflow and underflow, improving efficiency. - Replaced if-else checks with bitwise masks to handle overflow and underflow for int32, int24, int16, and int8 saturation functions. - For each bit width, created masks by shifting the results of comparisons (x - MIN_VAL) and (MAX_VAL - x) to the respective overflow/underflow detection bits. - Mask >> 31 or >> 63 results in either 0 (no overflow/underflow) or -1 (overflow/underflow occurred). - Applied bitwise operations to conditionally replace original values with boundary values (MIN or MAX) based on the computed masks. - This approach avoids branching, improves efficiency, and ensures accurate saturation within specified bit-width limits. Signed-off-by: Shriram Shastry <[email protected]>
- Loading branch information
1 parent
d01320a
commit cc0ef9a
Showing
1 changed file
with
67 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
/* SPDX-License-Identifier: BSD-3-Clause | ||
* | ||
* Copyright(c) 2021 Intel Corporation. All rights reserved. | ||
* | ||
* Author: Shriram Shastry <[email protected]> | ||
*/ | ||
|
||
#ifndef __SOF_AUDIO_FORMAT_GENERIC_H__ | ||
|
@@ -9,45 +11,85 @@ | |
#include <stdint.h> | ||
|
||
/* Saturation inline functions */ | ||
|
||
/** | ||
* @brief Saturate an int64_t value to fit within the range of int32_t. | ||
* | ||
* This function ensures that the input value 'x' fits within the range of | ||
* int32_t. If 'x' exceeds this range, it will be bound to INT32_MAX or INT32_MIN | ||
* accordingly. | ||
* | ||
* @param x The input value to saturate. | ||
* @return int32_t The saturated int32_t value. | ||
*/ | ||
static inline int32_t sat_int32(int64_t x) | ||
{ | ||
if (x > INT32_MAX) | ||
return INT32_MAX; | ||
else if (x < INT32_MIN) | ||
return INT32_MIN; | ||
else | ||
return (int32_t)x; | ||
int64_t mask_overflow = (INT32_MAX - x) >> 63; | ||
int64_t mask_underflow = (x - INT32_MIN) >> 63; | ||
|
||
x = (x & ~mask_overflow) | (INT32_MAX & mask_overflow); | ||
x = (x & ~mask_underflow) | (INT32_MIN & mask_underflow); | ||
return (int32_t)x; | ||
|
||
} | ||
|
||
/** | ||
* @brief Saturate an int32_t value to fit within the range of a 24-bit integer. | ||
* | ||
* This function ensures that the input value 'x' fits within the range of a | ||
* 24-bit integer. If 'x' exceeds this range, it will be bound to INT24_MAXVALUE | ||
* or INT24_MINVALUE accordingly. | ||
* | ||
* @param x The input value to saturate. | ||
* @return int32_t The saturated int32_t value. | ||
*/ | ||
static inline int32_t sat_int24(int32_t x) | ||
{ | ||
if (x > INT24_MAXVALUE) | ||
return INT24_MAXVALUE; | ||
else if (x < INT24_MINVALUE) | ||
return INT24_MINVALUE; | ||
else | ||
return x; | ||
int32_t mask_overflow = (INT24_MAXVALUE - x) >> 31; | ||
int32_t mask_underflow = (x - INT24_MINVALUE) >> 31; | ||
|
||
x = (x & ~mask_overflow) | (INT24_MAXVALUE & mask_overflow); | ||
x = (x & ~mask_underflow) | (INT24_MINVALUE & mask_underflow); | ||
return x; | ||
} | ||
|
||
/** | ||
* @brief Saturate an int32_t value to fit within the range of a 16-bit integer. | ||
* | ||
* This function ensures that the input value 'x' fits within the range of a | ||
* 16-bit integer. If 'x' exceeds this range, it will be bound to INT16_MAX or INT16_MIN | ||
* accordingly. | ||
* | ||
* @param x The input value to saturate. | ||
* @return int16_t The saturated int16_t value. | ||
*/ | ||
static inline int16_t sat_int16(int32_t x) | ||
{ | ||
if (x > INT16_MAX) | ||
return INT16_MAX; | ||
else if (x < INT16_MIN) | ||
return INT16_MIN; | ||
else | ||
return (int16_t)x; | ||
int32_t mask_overflow = (INT16_MAX - x) >> 31; | ||
int32_t mask_underflow = (x - INT16_MIN) >> 31; | ||
|
||
x = (x & ~mask_overflow) | (INT16_MAX & mask_overflow); | ||
x = (x & ~mask_underflow) | (INT16_MIN & mask_underflow); | ||
return (int16_t)x; | ||
} | ||
|
||
/** | ||
* @brief Saturate an int32_t value to fit within the range of an 8-bit integer. | ||
* | ||
* This function ensures that the input value 'x' fits within the range of an | ||
* 8-bit integer. If 'x' exceeds this range, it will be bound to INT8_MAX or INT8_MIN | ||
* accordingly. | ||
* | ||
* @param x The input value to saturate. | ||
* @return int8_t The saturated int8_t value. | ||
*/ | ||
static inline int8_t sat_int8(int32_t x) | ||
{ | ||
if (x > INT8_MAX) | ||
return INT8_MAX; | ||
else if (x < INT8_MIN) | ||
return INT8_MIN; | ||
else | ||
return (int8_t)x; | ||
int32_t mask_overflow = (INT8_MAX - x) >> 31; | ||
int32_t mask_underflow = (x - INT8_MIN) >> 31; | ||
|
||
x = (x & ~mask_overflow) | (INT8_MAX & mask_overflow); | ||
x = (x & ~mask_underflow) | (INT8_MIN & mask_underflow); | ||
return (int8_t)x; | ||
} | ||
|
||
#endif /* __SOF_AUDIO_FORMAT_GENERIC_H__ */ |