This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Windowing for RFFT_adc_f32 in FPU lib



I think it would be interesting to include the same windowing functions for the RFFT_adc_f32 as those found for the floating input functions as  RFFT_f32 .

If not, then a conversion from the ADC to floating point is needed, punishing performance.

  • Hi Pak,

    I've filed an enhancement request for this into our tracking system.

    Thank you!
    Lori
  • Thank you Lori.
    Is it included in the last release?

    Best Regards
  • Hi Pak,

    It is not in the last release (1.50). A ticket was filed against v1.50 so it will be put in the next version (2.00) - and this may take a while to complete as it is a major revision.  I cannot provide a timeline for you at the moment.

    I figure i would modify RFFT_f32_win.asm as follows, save it in RFFT_adc_f32_win.asm

    ;;#############################################################################
    ;;! \file source/fft/RFFT_adc_f32_win.asm
    ;;!
    ;;! \brief  Real FFT (ADC input) Windowing Function
    ;;! \author Vishal Coelho
    ;;! \date   Sep 30, 2016
    ;;
    ;;  Group:            C2000
    ;;  Target Family:    C28x+FPU32
    ;;
    ;; Copyright (C) $YEAR$ Texas Instruments Incorporated - http://www.ti.com/ 
    ;; ALL RIGHTS RESERVED
    ;;#############################################################################
    ;;$TI Release: $
    ;;$Release Date: $
    ;;#############################################################################
    ;;
    ;;*****************************************************************************
    ;; includes
    ;;*****************************************************************************
    ;;
    ;;*****************************************************************************
    ;; globals
    ;;*****************************************************************************
        ; Module definition for external reference
         .global      _RFFT_adc_f32_win
    ;;
    ;;=============================================================================
    ;;! \fn RFFT_f32_win
    ;;! \brief Real FFT (ADC input) Windowing Function
    ;;! \param pBuffer (XAR4), pointer to the ADC buffer that needs to be windowed
    ;;! \param pWindow (XAR5), pointer to the windowing table
    ;;! \param size    (AL),   size of the buffer (size of the RFFT)
    ;;
    ;; This function windows a 2N-point real valued data sequence stored as an 
    ;; N point complex sequence in the location pointed to by "pBuffer". It is to
    ;; be used with the real FFT module
    ;;
    ;; A 2N-pt real FFT is carried out by first doing an N point complex FFT 
    ;; followed by post processing (unwrapping) to get the correct answer. The 
    ;; windows are of size N (they are symmetrical).
    ;;
    ;; This routine will apply the window in two steps
    ;;
    ;; Step 1: Forward walk through win
    ;;    Loop for i = 0 to N - 1 {
    ;;      p -> pBuffer,  q -> win
    ;;      a = *p (u16->float) , b = *q (float)
    ;;      c = *(p+1) (u16->float), d = *(q+1)(float)
    ;;        temp1 = A x B (float)
    ;;        temp2 = C x D (float)
    ;;      *p   = temp1 , *(p+1) = temp2
    ;;      p    = p + 1 
    ;;      q    = q + 1
    ;;     }
    ;;
    ;; Step 2: Backward walk through win
    ;;    Loop for i = N to 2N - 1 {
    ;;      p -> pBuffer(from the last step),  q -> win(N/2)
    ;;      a = *p (u16->float) , b = *q (float)
    ;;      c = *(p+1) (u16->float), d = *(q+1)(float)
    ;;        temp1 = A x B (float)
    ;;        temp2 = C x D (float)
    ;;      *p   = temp1 , *(p+1) = temp2
    ;;      p    = p + 1 
    ;;      q    = q - 1
    ;;     }
    ;;
    ;; Register Usage
    ;; XAR4 -> pBuffer
    ;; XAR5 -> pWindow
    ;; AL   =  size
    ;; AR7  =  loop counter 1/2
    ;; R0H  =  window element
    ;; R1H  =  buffer element
    ;; R2H  =  window element
    ;; R3H  =  buffer element
    ;; Registers Save on Entry = 0
    ;;=============================================================================
    ;; 
        .text
    _RFFT_adc_f32_win:
        ; size -> size of RFFT i.e. 2N-point
        LSR       AL, #2                     ; AL   = (size/4)
        MOVZ      AR7, AL                    ; AR7  = (size/2)
        SUBB      XAR7,#1                    ; AR7  = (size/2)-1
    
        .align    2
        RPTB      _RFFT_adc_f32_win_loop1, AR7
        MOV32     R0H, *XAR5++               ; R0H   = win[i++]
        UI16TOF32 R1H, *XAR4                 ; R1H   = (float)d[i].real
        MPYF32    R0H, R0H, R1H              ;   |R0H   = (win[i]*d[i].real)
     || MOV32     R2H, *XAR5++               ;   |R2H   = win[i]      | i++
        UI16TOF32 R3H, *+XAR4[2]             ; +1|R3H   = (float)d[i].imag
        MPYF32    R2H, R2H, R3H              ;   |R2H   = (win[i]*d[i].imag)
        MOV32     *XAR4++, R0H               ; +1|*XAR4.real = R0H    | i++
        MOV32     *XAR4++, R2H               ; *XAR4.imag = R2H       | ARP = 4
    _RFFT_adc_f32_win_loop1:                        
        ; At the end of this loop, XAR5 points to the
        ; N/2 th element of the real input
        .align    2
        RPTB      _RFFT_adc_f32_win_loop2, AR7
        MOV32     R0H, *--XAR5               ; R0H   = win[i]         | i--
        UI16TOF32 R1H, *XAR4                 ; R1H   = (float)d[i].real
        MPYF32    R0H, R0H, R1H              ;   |R0H   = (win[i]*d[i].real)
     || MOV32     R2H, *--XAR5               ;   |R2H   = win[i]
        UI16TOF32 R3H, *+XAR4[2]             ; +1|R3H   = (float)d[i].imag
        MPYF32    R2H, R2H, R3H              ;   |R2H   = (win[i]*d[i].imag)
        MOV32     *XAR4++, R0H               ; +1|*XAR4.real = R0H    | i++
        MOV32     *XAR4++, R2H               ; *XAR4.imag = R2H       | ARP = 4
    _RFFT_adc_f32_win_loop2:
        LRETR
    
    ;;#############################################################################
    ;;  End of File
    ;;#############################################################################
    

    Add the function prototype to the header file, fpu_rfft.h

    extern void RFFT_f32_adc_win(uint16_t *pBuffer, float *pWindow, uint16_t size);

    This function should read the u16 adc input, convert to float and then window it. You would then call the regular RFFT_F32() and not the adc variant of the function, since the windowed input is already in float. Now i have not built or tested this function, but the change is minimal (MOV32 -> UI16TOF32 and label renaming) to the extent that i am sure that it will work. Can you try this and let me know if it works for you?

  • Thank you....will try it as soon as possible.
    Regards