When I use function dsp_lib dsp_adaptive_nlms() to operate the voice sample, it will output below problem when it run (building is ok). and use same parameter in function dsp_lib dsp_adaptive_lms() is good.
return_sample = dsp_adaptive_nlms(sample0, sample1, (int32_t)&error_sample, coeff, state, 100, Q28(0.01), 28);
xrun: Program received signal ET_ARITHMETIC, Arithmetic exception.
[Switching to tile[1] core[4] (dual issue)]
0x00047c24 in dsp_math_divide ()
Problem about dsp_lib dsp_adaptive_nlms() Topic is solved
-
- Member++
- Posts: 26
- Joined: Tue Jul 02, 2019 8:38 am
-
- Member++
- Posts: 26
- Joined: Tue Jul 02, 2019 8:38 am
Anybody know that ? please help.
-
- Respected Member
- Posts: 367
- Joined: Wed May 31, 2017 6:55 pm
dsp_math_divide uses the ldivu instrution. According to the xCORE-200 architecture manual, the ET_ARITHMETIC exception is raised if the divisor is zero, or if the result of the division will not fit into a 32-bit word.
-
- Member++
- Posts: 26
- Joined: Tue Jul 02, 2019 8:38 am
Hi, in official example code(AN00209), the parameter source_sample and reference_sample is use Q31 format data to test. And if I use Q31(0.01) instead of the 32-bit parameters, there is also not any error when running.But I2S data is use 32-bit to operate not Q31 data. There is a other strange thing is that dsp_math_divide in dsp_adaptive_nlms does not use these two parameter( source_sample and reference_sample).
-
- Member++
- Posts: 26
- Joined: Tue Jul 02, 2019 8:38 am
Hi, you are right, the error is because the divisor is zero when beginning. And another question is what is your mean about"if the result of the division will not fit into a 32-bit word". I found that even thought I filter the zero sample data , the function sometimes is still output ET_ARITHMETIC. It maybe is because the second cause what you said. Look forward to your reply, thank you very much.
-
- Respected Member
- Posts: 367
- Joined: Wed May 31, 2017 6:55 pm
Q31 is a 32-bit data format, at least in the dsp_lib convention: 31 bits to represent the fraction after the fixed point, plus the sign bit. The I2S specification doesn't specify the format for data.But I2S data is use 32-bit to operate not Q31 data
-
- Respected Member
- Posts: 367
- Joined: Wed May 31, 2017 6:55 pm
Regarding ET_ARITHMETIC, see the description for ldivu in the xmos document xCORE-200: The XMOS XS2 Architecture.
-
- Member++
- Posts: 26
- Joined: Tue Jul 02, 2019 8:38 am
Thank you. And back to the first question. if I input a voice data to the dsp_adaptive_nlms,the energy is maybe zero sometimes, so that it still will cause the ET_ARITHMETIC error. How to solve this?
In this code " if( energy < (1 << (31-(31-qq)*2)) ) energy = (1 << (31-(31-qq)*2)) + 0", if when "qq" is less than 16, (31-(31-qq)*2) will output a negative and then energy will be zero or negative. right?
Code: Select all
int32_t dsp_adaptive_nlms
(
int32_t source_sample,
int32_t reference_sample,
int32_t* error_sample,
const int32_t* filter_coeffs,
int32_t* state_data,
const int32_t num_taps,
const int32_t mu,
const int32_t q_format
) {
int32_t output_sample, energy, adjustment, ee, qq;
output_sample = dsp_filters_fir( source_sample, filter_coeffs, state_data, num_taps, q_format );
// Error equals difference between reference and filter output:
// e[n] = d[n] - y[n]
*error_sample = reference_sample - output_sample;
energy = dsp_vector_power( state_data, num_taps, q_format );
// Adjust energy q_format to account for range of reciprocal
for( qq = q_format, ee = energy; qq >= 0 && !(ee & 0x80000000); --qq ) ee <<= 1;
energy = energy >> (q_format - qq);
// Saturate the reciprocal value to max value for the given q_format
[highlight=yellow]if( energy < (1 << (31-(31-qq)*2)) ) energy = (1 << (31-(31-qq)*2)) + 0;[/highlight]
energy = dsp_math_divide( (1 << qq), energy, qq );
adjustment = dsp_math_multiply( *error_sample, mu, q_format );
adjustment = dsp_math_multiply( energy, adjustment, qq + q_format - q_format );
dsp_vector_muls_addv( state_data, adjustment, (int32_t*) filter_coeffs, (int32_t*) filter_coeffs, num_taps, q_format );
return output_sample;
}
-
- Respected Member
- Posts: 367
- Joined: Wed May 31, 2017 6:55 pm
I don't know enough about the algorithm to comment in much detail, but it looks like the saturation operation...
... is supposed to ensure that if the energy is too small a minimum value is used instead. It should never be negative because it's the sum of squares of the state_data vector elements.
Code: Select all
// Saturate the reciprocal value to max value for the given q_format
if( energy < (1 << (31-(31-qq)*2)) ) energy = (1 << (31-(31-qq)*2)) + 0;
-
- Member++
- Posts: 26
- Joined: Tue Jul 02, 2019 8:38 am
Thank you. I don't know enough about algorithm too. It is the function in the dsp lib, maybe only XMOS's algorithm engineer can solve it..CousinItt wrote: ↑Fri Jul 12, 2019 2:00 pm I don't know enough about the algorithm to comment in much detail, but it looks like the saturation operation...... is supposed to ensure that if the energy is too small a minimum value is used instead. It should never be negative because it's the sum of squares of the state_data vector elements.Code: Select all
// Saturate the reciprocal value to max value for the given q_format if( energy < (1 << (31-(31-qq)*2)) ) energy = (1 << (31-(31-qq)*2)) + 0;