Reply by September 2, 20152015-09-02
It does not matter what you multiply it by for the purpose of this discussion. I was checking the noise floor of the FFT function. As it stands, CMSIS Q15 FFT with length of 512 can produce spurious peaks up to 11 counts. That is equivalent of taking away 3-4 bits from your 16-bit ADC. BTW, this high noise floor seems to affect only mixed radix FFTs. Radix4 FFTs with length of 256 or 1024 are much better. I guess extra ops in mixed radix causes more errors.
Reply by AndyR August 25, 20152015-08-25
>Hi, >Sanity check here. Using ARM arm_cfft_q15() with 512 length. Seeing >noticeable roundoff errors. For a simulated input pure sine wave (first >harmonic) the magnitudes of the first nine FFT harmonics look as
follows:
> >Input H1 10 bits: >11.3 5.7 0.0 5.7 5.7 5.7 2.0 4.0 5.7 > >Input H1 1000 bits: >992.0 5.7 2.0 5.7 7.2 5.7 5.7 5.7 5.7 > >Input H1 10000 bits: >9992.0 5.7 5.7 5.7 5.7 5.7 5.7 5.7 4.5 > >Computed as: > arm_cfft_q15(cfft, Data0, 0, 1); > fi = Data0[2*i]; > fq = Data0[2*i+1]; > mag = sqrtf(fi*fi + fq*fq); > >Does this look OK or the errors are too high? I recall getting lower >roundoff errors with custom FFT256 routine in the past. Would appreciate
if
>somebody can provide any insight. >Regards, >Sergei
Hi, just wondering, but does the fft function expect the data to be in q15 format?. If so, then when you create sine data you should multiply by 32767, not 10, not 100, not 10000. I've not used arm fixed lib, so not really sure it this is the problem you are seeing. --------------------------------------- Posted through http://www.DSPRelated.com
Reply by August 20, 20152015-08-20
Block floating point is implemented in fixed-point. You just shift-left all the outputs of a given column of the fft by the maximum amount that does not cause the largest value to overflow. You keep track of the shifts and undo it all at the end. If you don't have access into the fft code you can just process the input buffer before calling the fft and then do the opposite shift in the output buffer. This will get you part of the way there. 

Bob
Reply by August 20, 20152015-08-20
On Thursday, August 20, 2015 at 5:46:24 AM UTC-5, radam...@gmail.com wrote:
> Don't know if this could be your problem ... > > http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/399448/1412979
Thank you for the pointer. I grepped Freescale sources and it seems the (above referenced problematic) definition is fine there: core_cmSimd.h:#define __SMUSDX __smusdx
> Also I'm not sure if the Q15 fft alg uses block floating point.
I am trying to stay away from floats to get the best speed from FFT. The floats are only used to compute ideal test signal. I am pretty sure Q15 routines do not use floats and/or FPU. Regards, Sergei
Reply by August 20, 20152015-08-20
Don't know if this could be your problem ...

http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/399448/1412979

Also I'm not sure if the Q15 fft alg uses block floating point. You could manually do input/output floating point by finding the max of your input array, scaling the input to map the max value to the max of the q15 format and then scaling down the output array by the same factor. Of course this will eat mips. 

Bob
Reply by Steve Pope August 19, 20152015-08-19
<sergei.sharonov@gmail.com> wrote:

>On Wednesday, August 19, 2015 at 3:57:16 PM UTC-5, Steve Pope wrote:
>> ...ARM says to use its library function vcvt() to convert >> between floats and Q-notation although, the man page for >> this function never uses the phrase "Q-notation" or "Q-format". >> Once you read it, however, it's clear that is what it's for. >> Maybe somebody copyrighted "Q-format", or something....
>I presumed that I can just assign (smaller than 2^15 and rounded) floats >to Q15s, feed that to fft, get result back. Then I can skip mental >exercise of round trip conversion and get the same value back? The test >seems to support that.
Based on peering at the ARM documentation, you are right and you can safely do this. vcvt() might be more portable, or something. Steve
Reply by August 19, 20152015-08-19
On Wednesday, August 19, 2015 at 3:57:16 PM UTC-5, Steve Pope wrote:
> ...ARM says to use its library function vcvt() to convert > between floats and Q-notation although, the man page for > this function never uses the phrase "Q-notation" or "Q-format". > Once you read it, however, it's clear that is what it's for. > Maybe somebody copyrighted "Q-format", or something....
I presumed that I can just assign (smaller than 2^15 and rounded) floats to Q15s, feed that to fft, get result back. Then I can skip mental exercise of round trip conversion and get the same value back? The test seems to support that. Regards, Sergei
Reply by August 19, 20152015-08-19
On Wednesday, August 19, 2015 at 11:13:55 AM UTC-5, Steve Pope wrote:
> To convert a number from floating point to Qm.n format: > Multiply the floating point number by 2^n > Round to the nearest integer
That is what I am trying to do with: Data0[2*i] = roundf(1000 * cosf(ph)); Data0[2*i+1] = roundf(1000 * sinf(ph)); I expect magnitude of the first harmonic after FFT to be about 1000 "counts" (ok, they are counts, not bits ;-) And I do get a value of 992. A bit less accurate than I expected. Regards, Sergei
Reply by August 19, 20152015-08-19
On Tuesday, August 18, 2015 at 8:25:35 PM UTC-5, Steve Pope wrote:
> ...It my be expected for this ARM library, but if so I'd call it an > underdesign (that is, over-compromised design) within the library. > Library (and coprocessor) designers should strive to obtain less than > 1 LSB of roundoff due to internal precisions.
That is what I am trying to find out. What sort of errors (e.g. noise floor) can I expect from ARM CMSIS DSP library function arm_cfft_q15() with FFT length of 512? I see 5-7 counts and that seems a bit high. I understand that this is a very specific question but with abundance of ARM chips out there I can't believe nobody is using ARM Q15 FFT routines. If somebody on this list does, could you please run it with ideal input data and see what the noise floor is? Thanks, Sergei
Reply by Steve Pope August 19, 20152015-08-19
glen herrmannsfeldt  <gah@ugcs.caltech.edu> wrote:

>Steve Pope <spope33@speedymail.org> wrote: > >(snip, I wrote) >>>I never liked the Q notation, either. > >> I like it even less now that I have looked at its Wikipedia >> page. > >> Probably, my previous post was incorrect. >> According to the Wikipedia editors: > >> Float to Q > >> To convert a number from floating point to Qm.n format: >> Multiply the floating point number by 2^n >> Round to the nearest integer > >Computer tradition is to truncate. If you want rounded, correct >the value before converting.
Well, this is the problem. Q-notation is not a standard, so one is reduced to consulting Wikipedia pages. Actually, not quite that bad ... ARM has some documentation on its use of Q-notation.
>> Q to float > >> To convert a number from Qm.n format to floating point: >> Convert the number to floating point as if it were an integer >> Multiply by 2^n > >> That is, you cannot simply assign between Q's and floats, or >> Q's and Q's, and get the right answer. You have to re-scale >> each time you do this.
>But we learned how to do that in 2nd or 3rd grade. The process >is the same in decimal and binary, except decimal digits in >one, binary bits in the other.
ARM says to use its library function vcvt() to convert between floats and Q-notation although, the man page for this function never uses the phrase "Q-notation" or "Q-format". Once you read it, however, it's clear that is what it's for. Maybe somebody copyrighted "Q-format", or something. It looks like it does not support fixed point words wider than 32 bits. IEEE 1666 is System C, which is a large language, one useful feature of which is the fixed-point format; lots of ASIC projects use this, because it is understandable by chip designers and is a standard. Steve