Problem when realizing DSP algorithm:LMS on xCORE-200 MC Audio

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

The numbers you will have in the software raw from the MC audio ADC are Q31.


User avatar
CousinItt
Respected Member
Posts: 360
Joined: Wed May 31, 2017 6:55 pm

Post by CousinItt »

...So if you are using (e.g.) Q24 format you need to divide (not shift) by 128 (== 2 to the power (31-24)). Similarly you'll need to convert from this format to whatever format your output devices expect.
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

@CousinItt, can you give me a 2 second explanation why arithmetic shift right by 7 isn't advisable vs divide by 128 -- I take that to be your meaning. I appreciate that the rounding of the last bit will be different for negative numbers using ASR 7 vs / 128, but it seems to me that the substantially faster computation of an ASR is probably desirable compared to a slight difference in the LSbit of 24 bit audio. That's beyond the capability of ADCs and DACs which are really only good to about 21 bits best case.
User avatar
CousinItt
Respected Member
Posts: 360
Joined: Wed May 31, 2017 6:55 pm

Post by CousinItt »

I was in the process of replying when I realised that XC might support right shift of signed quantities. I would expect the compiler to generate an arithmetic shift whether the shift or divide operator is used. I'd better check this.

[follow-up] In C the right-shift of a signed quantity is undefined. The XC specification doesn't say what happens when right-shifting a signed quantity.

[follow-up 2] The XC specification just says
The value of the >> operator is the left operand right-shifted by the number of bits specified by the right operand.
However, a quick test of the values 8 and -8 shows that XC does use handle signed and unsigned operands appropriately:
signed integer value 0x00000008, right shifted 2 is 0x00000002
unsigned integer value 0x00000008, right shifted 2 is 0x00000002

signed integer value 0xFFFFFFF8, right shifted 2 is 0xFFFFFFFE
unsigned integer value 0xFFFFFFF8, right shifted 2 is 0x3FFFFFFE
Sorry, I guess I'm just used to implementations where right shifting negative numbers doesn't work. I'll get my coat.
Last edited by CousinItt on Wed Apr 25, 2018 3:11 pm, edited 1 time in total.
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

In xc a >> of a signed value (e.g. int32_t or signed integer) yields arithmetic shift right, retaining the sign bit. The XMOS assembly language provides ashr (arithmetic shift right) and divs (signed division). The ashr instruction takes 1 thread-cycle whereas divs takes up to 32 thread-cycles, but perhaps not that many when it is dividing by 128?
User avatar
CousinItt
Respected Member
Posts: 360
Joined: Wed May 31, 2017 6:55 pm

Post by CousinItt »

Hi akp,

see above. I wasn't recommending using divs directly, just using division in XC which (as I said) I'd expect would generate an arithmetic shift when dividing by a power of 2. It does do that (at least for optimisation level 2 and above) if the divisor is a constant, but not (for example) if the divisor is defined as (1 << x). However, as we've seen, right shifting seems to be better. Thanks - I've learned something today.
cjf1699
Active Member
Posts: 48
Joined: Fri Mar 16, 2018 2:30 pm

Post by cjf1699 »

akp wrote:The numbers you will have in the software raw from the MC audio ADC are Q31.
Thank you! Sorry for late to answer. However,I found this in the i2s.h:

Image
Is that mean the converted data is stored in the top-24 bit? If I want to apply some dsp (for example feed a fir filter) to the data, do I need to give the raw data a right-shift 8 bit operation to get the real value?
Thanks!
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

I advise you to look up fixed precision Q format to understand that isn't what the text is intending to convey. You need to really understand fixed precision number formats and associated risks (i.e. overflow) to doing math on them before you do your own DSP code. One other tip is that a very good audio ADC or DAC might have an SNR of 120dB whereas the SQNR of a 24bit number is more than 20dB better than that, so you really do not need to worry about the last ~10 bits of a 32 bit audio sample. That's why @CousinItt's suggestion of using Q7.24 to avoid overflow is so useful for doing DSP (or similar, e.g. you might get away with fewer guard bits).
User avatar
CousinItt
Respected Member
Posts: 360
Joined: Wed May 31, 2017 6:55 pm

Post by CousinItt »

@cjf1699 If you're using the analogue inputs of the MC audio board, then the CS5368 data sheet shows that the conversion results do appear at the most significant end of each I2S data word. In other words it is logical to treat the data received from the I2S handler as Q31 format, and it would make sense for you to shift the data before feeding it to the DSP code.

The CS4384 DAC uses the same I2S formatting, so it's likely you'll need to shift up before transferring your output data to the I2S handler - again, assuming you're using the analogue outputs.
cjf1699
Active Member
Posts: 48
Joined: Fri Mar 16, 2018 2:30 pm

Post by cjf1699 »

CousinItt wrote:@cjf1699 If you're using the analogue inputs of the MC audio board, then the CS5368 data sheet shows that the conversion results do appear at the most significant end of each I2S data word. In other words it is logical to treat the data received from the I2S handler as Q31 format, and it would make sense for you to shift the data before feeding it to the DSP code.

The CS4384 DAC uses the same I2S formatting, so it's likely you'll need to shift up before transferring your output data to the I2S handler - again, assuming you're using the analogue outputs.
Thank you very much! One more question, it seems that Q value doesn't matter so much because the data I receive and send is just a 32-bit stream. So to avoid overflow, could I just use Q31 format and doing no shifting? Besides , I see this on function dsp_filters_fir's log:
* The FIR algorithm involves multiplication between 32-bit filter
* coefficients and 32-bit state data producing a 64-bit result for each
* coeffient and state data pair.
* Multiplication results are accumulated in a 64-bit accumulator.
* If overflow occurs in the final 64-bit result, it is saturated at the minimum/maximum value
* given the fixed-point format and finally shifted right by ``q_format`` bits.
* The saturation is only done after the last multiplication.
* To avoid 64-bit overflow in the intermediate results, the fixed point format must be chosen
* according to num_taps.
What does the last item mean? The larger num_taps, the smaller fixed point format?
Thank you again!
Post Reply