Repository navigation
audio: math: add RISC-V SIMD, vector, and DSP optimizations #11300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lgirdwood
wants to merge
7
commits into
thesofproject:main
Choose a base branch
from
lgirdwood:topic/riscv-simd
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,242
−760
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
0792a74
include: common: introduce RISC-V SIMD configuration macros
lgirdwood 81815ad
math: iir: add RISC-V SIMD cascaded DF1 and DF2T biquad filtering
lgirdwood 9d5c1d7
include: math: add ESP32-P4 PIE 128-bit vector SIMD definitions
lgirdwood 5b89e12
audio: volume: add RISC-V SIMD and contiguous vector streaming
lgirdwood f8c6a97
audio: eq_iir: add RISC-V block-accelerated processing and branchless…
lgirdwood 6cf6477
audio: drc: add RISC-V SIMD and fast polynomial math optimizations
lgirdwood 83265b9
audio: modules: optimize loop unrolling and guards for RISC-V dual-is…
lgirdwood File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
| // | ||
| // Copyright(c) 2026 Sound Open Firmware. All rights reserved. | ||
|
|
||
| #include <sof/audio/format.h> | ||
| #include <sof/math/decibels.h> | ||
| #include <sof/math/exp_fcn.h> | ||
| #include <sof/math/numbers.h> | ||
| #include <sof/math/trig.h> | ||
| #include <sof/common.h> | ||
|
|
||
| #include "drc_math.h" | ||
|
|
||
| #if SOF_USE_RISCV_SIMD(DRC) | ||
|
|
||
| #define ONE_OVER_SQRT2_Q30 759250112 /* Q_CONVERT_FLOAT(0.70710678118654752f, 30); 1/sqrt(2) */ | ||
| #define SQRT2_Q30 1518500224 /* Q_CONVERT_FLOAT(1.4142135623730950488f, 30); sqrt(2) */ | ||
| #define LOG10_FUNC_A5_Q26 75959200 /* Q_CONVERT_FLOAT(1.131880283355712890625f, 26) */ | ||
| #define LOG10_FUNC_A4_Q26 -285795039 /* Q_CONVERT_FLOAT(-4.258677959442138671875f, 26) */ | ||
| #define LOG10_FUNC_A3_Q26 457435200 /* Q_CONVERT_FLOAT(6.81631565093994140625f, 26) */ | ||
| #define LOG10_FUNC_A2_Q26 -410610303 /* Q_CONVERT_FLOAT(-6.1185703277587890625f, 26) */ | ||
| #define LOG10_FUNC_A1_Q26 244982704 /* Q_CONVERT_FLOAT(3.6505267620086669921875f, 26) */ | ||
| #define LOG10_FUNC_A0_Q26 -81731487 /* Q_CONVERT_FLOAT(-1.217894077301025390625f, 26) */ | ||
| #define HALF_Q25 16777216 /* Q_CONVERT_FLOAT(0.5, 25) */ | ||
| #define LOG10_2_Q26 20201782 /* Q_CONVERT_FLOAT(0.301029995663981195214f, 26) */ | ||
| #define NEG_1K_Q21 -2097151999 /* Q_CONVERT_FLOAT(-1000.0f, 21) */ | ||
| #define LOG_10_Q29 1236190976 /* Q_CONVERT_FLOAT(2.3025850929940457f, 29) */ | ||
| #define NEG_30_Q26 -2013265919 /* Q_CONVERT_FLOAT(-30.0f, 26) */ | ||
| #define DRC_TWENTY_Q26 1342177280 /* Q_CONVERT_FLOAT(20, 26) */ | ||
|
|
||
| #define ASIN_FUNC_A7L_Q30 126897672 /* Q_CONVERT_FLOAT(0.1181826665997505187988281f, 30) */ | ||
| #define ASIN_FUNC_A5L_Q30 43190596 /* Q_CONVERT_FLOAT(4.0224377065896987915039062e-2f, 30) */ | ||
| #define ASIN_FUNC_A3L_Q30 184887136 /* Q_CONVERT_FLOAT(0.1721895635128021240234375f, 30) */ | ||
| #define ASIN_FUNC_A1L_Q30 1073495040 /* Q_CONVERT_FLOAT(0.99977016448974609375f, 30) */ | ||
| #define ASIN_FUNC_A7H_Q26 948097024 /* Q_CONVERT_FLOAT(14.12774658203125f, 26) */ | ||
| #define ASIN_FUNC_A5H_Q26 -2024625535 /* Q_CONVERT_FLOAT(-30.1692714691162109375f, 26) */ | ||
| #define ASIN_FUNC_A3H_Q26 1441234048 /* Q_CONVERT_FLOAT(21.4760608673095703125f, 26) */ | ||
| #define ASIN_FUNC_A1H_Q26 -261361631 /* Q_CONVERT_FLOAT(-3.894591808319091796875f, 26) */ | ||
|
|
||
| #define INV_FUNC_A5_Q25 -92027983 /* Q_CONVERT_FLOAT(-2.742647647857666015625f, 25) */ | ||
| #define INV_FUNC_A4_Q25 470207584 /* Q_CONVERT_FLOAT(14.01327800750732421875f, 25) */ | ||
| #define INV_FUNC_A3_Q25 -998064895 /* Q_CONVERT_FLOAT(-29.74465179443359375f, 25) */ | ||
| #define INV_FUNC_A2_Q25 1126492160 /* Q_CONVERT_FLOAT(33.57208251953125f, 25) */ | ||
| #define INV_FUNC_A1_Q25 -713042175 /* Q_CONVERT_FLOAT(-21.25031280517578125f, 25) */ | ||
| #define INV_FUNC_A0_Q25 239989712 /* Q_CONVERT_FLOAT(7.152250766754150390625f, 25) */ | ||
|
|
||
| static inline int32_t rexp_fixed_riscv(int32_t x, int32_t precision_x, int32_t *e) | ||
| { | ||
| int32_t bit = 31 - norm_int32(x); | ||
|
|
||
| *e = bit - precision_x; | ||
|
|
||
| if (bit > 30) | ||
| return (x + (1 << (bit - 31))) >> (bit - 30); | ||
| if (bit < 30) | ||
| return x << (30 - bit); | ||
| return x; | ||
| } | ||
|
|
||
| static inline int32_t log10_fixed(int32_t x) | ||
| { | ||
| int32_t e; | ||
| int32_t exp; | ||
| int32_t acc; | ||
| const int32_t lshift = drc_get_lshift(26, 30, 26); | ||
|
|
||
| x = rexp_fixed_riscv(x, 26, &e); | ||
| exp = e << 25; | ||
|
|
||
| if (x > ONE_OVER_SQRT2_Q30) { | ||
| x = drc_mult_lshift(x, ONE_OVER_SQRT2_Q30, drc_get_lshift(30, 30, 30)); | ||
| exp += HALF_Q25; | ||
| } | ||
|
|
||
| /* Horner's rule: A0 + x*(A1 + x*(A2 + x*(A3 + x*(A4 + x*A5)))) */ | ||
| acc = drc_mult_lshift(LOG10_FUNC_A5_Q26, x, lshift) + LOG10_FUNC_A4_Q26; | ||
| acc = drc_mult_lshift(acc, x, lshift) + LOG10_FUNC_A3_Q26; | ||
| acc = drc_mult_lshift(acc, x, lshift) + LOG10_FUNC_A2_Q26; | ||
| acc = drc_mult_lshift(acc, x, lshift) + LOG10_FUNC_A1_Q26; | ||
| acc = drc_mult_lshift(acc, x, lshift) + LOG10_FUNC_A0_Q26; | ||
|
|
||
| acc += drc_mult_lshift(exp, LOG10_2_Q26, drc_get_lshift(25, 26, 26)); | ||
| return acc; | ||
| } | ||
|
|
||
| int32_t drc_lin2db_fixed(int32_t linear) | ||
| { | ||
| int32_t log10_linear; | ||
|
|
||
| if (linear <= 0) | ||
| return NEG_1K_Q21; | ||
|
|
||
| log10_linear = log10_fixed(linear); | ||
| return drc_mult_lshift(DRC_TWENTY_Q26, log10_linear, drc_get_lshift(26, 26, 21)); | ||
| } | ||
|
|
||
| int32_t drc_log_fixed(int32_t x) | ||
| { | ||
| int32_t log10_x; | ||
|
|
||
| if (x <= 0) | ||
| return NEG_30_Q26; | ||
|
|
||
| log10_x = log10_fixed(x); | ||
| return drc_mult_lshift(LOG_10_Q29, log10_x, drc_get_lshift(29, 26, 26)); | ||
| } | ||
|
|
||
| #ifndef DRC_USE_CORDIC_ASIN | ||
| int32_t drc_asin_fixed(int32_t x) | ||
| { | ||
| int32_t lshift; | ||
| int32_t x_abs = x < 0 ? -x : x; | ||
| int32_t in2; | ||
| int32_t A7, A5, A3, A1; | ||
| int32_t qc; | ||
| int32_t acc; | ||
|
|
||
| in2 = drc_mult_lshift(x, x, drc_get_lshift(30, 30, 30)); | ||
|
|
||
| if (x_abs <= ONE_OVER_SQRT2_Q30) { | ||
| A7 = ASIN_FUNC_A7L_Q30; | ||
| A5 = ASIN_FUNC_A5L_Q30; | ||
| A3 = ASIN_FUNC_A3L_Q30; | ||
| A1 = ASIN_FUNC_A1L_Q30; | ||
| qc = 30; | ||
| } else { | ||
| A7 = ASIN_FUNC_A7H_Q26; | ||
| A5 = ASIN_FUNC_A5H_Q26; | ||
| A3 = ASIN_FUNC_A3H_Q26; | ||
| A1 = ASIN_FUNC_A1H_Q26; | ||
| qc = 26; | ||
| } | ||
|
|
||
| lshift = drc_get_lshift(qc, 30, qc); | ||
| acc = drc_mult_lshift(A7, in2, lshift) + A5; | ||
| acc = drc_mult_lshift(acc, in2, lshift) + A3; | ||
| acc = drc_mult_lshift(acc, in2, lshift) + A1; | ||
| acc = drc_mult_lshift(acc, x, lshift); | ||
|
|
||
| return drc_mult_lshift(acc, TWO_OVER_PI_Q30, drc_get_lshift(qc, 30, 30)); | ||
| } | ||
| #endif /* !DRC_USE_CORDIC_ASIN */ | ||
|
|
||
| int32_t drc_inv_fixed(int32_t x, int32_t precision_x, int32_t precision_y) | ||
|
lgirdwood marked this conversation as resolved.
|
||
| { | ||
| int32_t e; | ||
| int32_t precision_inv; | ||
| int32_t sqrt2_extracted = 0; | ||
| int32_t acc; | ||
| const int32_t lshift = drc_get_lshift(25, 30, 25); | ||
|
|
||
| x = rexp_fixed_riscv(x, precision_x, &e); | ||
|
|
||
| if ((x < 0 ? -x : x) < ONE_OVER_SQRT2_Q30) { | ||
| x = drc_mult_lshift(x, SQRT2_Q30, drc_get_lshift(30, 30, 30)); | ||
| sqrt2_extracted = 1; | ||
| } | ||
|
|
||
| /* Horner's rule for reciprocal */ | ||
| acc = drc_mult_lshift(INV_FUNC_A5_Q25, x, lshift) + INV_FUNC_A4_Q25; | ||
| acc = drc_mult_lshift(acc, x, lshift) + INV_FUNC_A3_Q25; | ||
| acc = drc_mult_lshift(acc, x, lshift) + INV_FUNC_A2_Q25; | ||
| acc = drc_mult_lshift(acc, x, lshift) + INV_FUNC_A1_Q25; | ||
| acc = drc_mult_lshift(acc, x, lshift) + INV_FUNC_A0_Q25; | ||
|
|
||
| if (sqrt2_extracted) | ||
| acc = drc_mult_lshift(acc, SQRT2_Q30, lshift); | ||
|
|
||
| precision_inv = e + 25; | ||
| if (precision_inv > precision_y) { | ||
| int shift = precision_inv - precision_y; | ||
| return (acc + (1 << (shift - 1))) >> shift; | ||
| } | ||
| if (precision_inv < precision_y) { | ||
| int shift = precision_y - precision_inv; | ||
| int64_t val = ((int64_t)acc) << shift; | ||
| if (val > INT32_MAX) | ||
| return INT32_MAX; | ||
| if (val < INT32_MIN) | ||
| return INT32_MIN; | ||
| return (int32_t)val; | ||
| } | ||
| return acc; | ||
| } | ||
|
|
||
| #endif /* SOF_USE_RISCV_SIMD(DRC) */ | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.