diff --git a/src/common.h b/src/common.h index 751e845..4275c4e 100644 --- a/src/common.h +++ b/src/common.h @@ -29,11 +29,16 @@ #include #include +#ifdef __ARM_ARCH +#include +#endif + /** * Macros * MIN/MAX Minimum and maximum between 2 values * CLIP Clip a value between low and high limits + * SATXX Saturation on 'xx' bits * ABS Return the absolute value */ @@ -41,9 +46,18 @@ #define LC3_MAX(a, b) ( (a) > (b) ? (a) : (b) ) #define LC3_CLIP(v, min, max) LC3_MIN(LC3_MAX(v, min), max) +#ifdef __ARM_FEATURE_SAT +#define LC3_SAT16(v) __ssat(v, 16) +#define LC3_SAT24(v) __ssat(v, 24) +#else +#define LC3_SAT16(v) LC3_CLIP(v, -(1 << 15), (1 << 15) - 1) +#define LC3_SAT24(v) LC3_CLIP(v, -(1 << 23), (1 << 23) - 1) +#endif + #define LC3_ABS(n) ( (n) < 0 ? -(n) : (n) ) + /** * Convert `dt` in us and `sr` in KHz */ diff --git a/src/lc3.c b/src/lc3.c index b98ab71..394a78f 100644 --- a/src/lc3.c +++ b/src/lc3.c @@ -366,8 +366,8 @@ static void store_s16( int ns = LC3_NS(dt, sr); for ( ; ns > 0; ns--, xs++, pcm += stride) { - int s = *xs >= 0 ? (int)(*xs + 0.5f) : (int)(*xs - 0.5f); - *pcm = LC3_CLIP(s, INT16_MIN, INT16_MAX); + int32_t s = *xs >= 0 ? (int)(*xs + 0.5f) : (int)(*xs - 0.5f); + *pcm = LC3_SAT16(s); } } @@ -380,8 +380,6 @@ static void store_s24( struct lc3_decoder *decoder, void *_pcm, int stride) { int32_t *pcm = _pcm; - const int32_t int24_max = (1 << 23) - 1; - const int32_t int24_min = -(1 << 23); enum lc3_dt dt = decoder->dt; enum lc3_srate sr = decoder->sr_pcm; @@ -392,7 +390,7 @@ static void store_s24( for ( ; ns > 0; ns--, xs++, pcm += stride) { int32_t s = *xs >= 0 ? (int32_t)(ldexpf(*xs, 8) + 0.5f) : (int32_t)(ldexpf(*xs, 8) - 0.5f); - *pcm = LC3_CLIP(s, int24_min, int24_max); + *pcm = LC3_SAT24(s); } }