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.

[参考译文] TDA4VEN-Q1:当重复调用 FFTLIB 时、输出结果异常

Guru**** 2455360 points
Other Parts Discussed in Thread: FFTLIB

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1488120/tda4ven-q1-the-output-results-are-abnormal-when-fftlib-is-called-repeatedly

器件型号:TDA4VEN-Q1
主题中讨论的其他器件:FFTLIB

工具与软件:

尊敬的 TI 专家:

     在开发 DSP C7x 时、我遇到了一个问题、在持续调用 FFTLIB_fft1dBatched_i16sc_c16sc_o16sc_kernel 函数时、第一次 FFT 计算的结果是正常的、但第二次 FFT 计算的结果是异常的。 单独执行任一 FFT 计算(仅使用第一个 FFT 或仅使用第二个 FFT)时、结果都正确。 第一个 FFT 的输入阵列具有128个通道、具有1024个采样点、第二个 FFT 的输入阵列具有512个通道、具有128个采样点。 代码如下:

__attribute__((section(".l2mem"), aligned(64))) int16_t l2_user_array0[128][2048];   // 512k
__attribute__((section(".l2mem"), aligned(64))) int16_t l2_user_array1[128][2048];   // 512k
__attribute__((section(".l2mem"), aligned(64))) int16_t l2_user_array2[512][256];    // 256k
__attribute__((section(".l2mem"), aligned(64))) int16_t l2_user_array3[512][256];    // 256k

void func()
{
    battch_fft1d_info_type l_battch_fft1d_info = {0};
    
    l_battch_fft1d_info.num_shifts = 5;
    l_battch_fft1d_info.channel = 128;
    l_battch_fft1d_info.num_points = 1024;
    l_battch_fft1d_info.data_type = FFTLIB_INT16;
    bsp_dsppro_battch_fft1d((int16_t *)l2_user_array0, (int16_t *)l2_user_array1, &l_battch_fft1d_info);
   
    l_battch_fft1d_info.num_shifts = 3;
    l_battch_fft1d_info.channel = 512;
    l_battch_fft1d_info.num_points = 128;
    l_battch_fft1d_info.data_type = FFTLIB_INT16;
    bsp_dsppro_battch_fft1d((int16_t *)l2_user_array2, (int16_t *)l2_user_array3, &l_battch_fft1d_info);
}

uint8_t bsp_dsppro_battch_fft1d(int16_t *input, int16_t *output, battch_fft1d_info_type *battch_fft1d_info)
{
    uint8_t  l_u8_ret = 0;
    int16_t  *pX;
    int16_t  *pY;
    int16_t  *pW;
    uint32_t *pShift;
    FFTLIB_bufParams1D_t bufParamsData;
    FFTLIB_bufParams1D_t bufParamsShift;
    FFTLIB_bufParams1D_t bufParamsTw;

    FFTLIB_STATUS status_opt = FFTLIB_SUCCESS;

    uint32_t numShifts = battch_fft1d_info->num_shifts;      // 5:1024,   3:128
    uint32_t l_u32_channel = battch_fft1d_info->channel;     // 128 chirp,  1024 point
    uint32_t numPoints  = battch_fft1d_info->num_points;     // 1024 point,  128 chirp
    uint32_t dataMemSize = l_u32_channel * numPoints * 2;     /* Kernel requires input/output */
                                                              /* buffers to be atleast
                                                               * 128 elements long */

    uint8_t *pblock = NULL;
    pblock = FFTLIB_fft1dbatched_i16sc_c16sc_o16sc_pBlock;

    pX = (int16_t *)input;
    pY = (int16_t *)output;
    pW = malloc(numPoints * 2 * sizeof (int16_t));
    pShift = malloc(numShifts * sizeof (uint32_t));

    if ((pX == NULL) || (pY == NULL) || (pW == NULL) || (pShift == NULL))
    {
        DebugP_log("[info]pX is NULL!\r\n");
        l_u8_ret = 1;
        goto error;
    }

    bufParamsData.dim_x     = dataMemSize;
    bufParamsData.data_type = FFTLIB_INT16;

    bufParamsShift.dim_x     = numShifts;
    bufParamsShift.data_type = FFTLIB_UINT32;

    bufParamsTw.dim_x        = numPoints * 2;
    bufParamsTw.data_type    = FFTLIB_INT16;

    tw_gen (pW, numPoints);

    /* 批量fft变换 */
    /* 批量fft初始化 */
    status_opt = FFTLIB_fft1dBatched_i16sc_c16sc_o16sc_init((int16_t *) pX, &bufParamsData, (int16_t *) pW, &bufParamsTw,
                                                            (int16_t *) pY, &bufParamsData, (uint32_t *) pShift, &bufParamsShift, 
                                                            numPoints, l_u32_channel, pblock);
    if (status_opt != FFTLIB_SUCCESS)
    {
        l_u8_ret = 1;
        goto error;

    // /* 批量fft参数检查 */
    // status_opt = FFTLIB_fft1dBatched_i16sc_c16sc_o16sc_checkParams((int16_t *) pX, &bufParamsData, (int16_t *) pW, &bufParamsTw,
    //                                                                (int16_t *) pY, &bufParamsData, (uint32_t *) pShift, &bufParamsShift, 
    //                                                                numPoints, l_u32_channel, pblock);
    // if (status_opt != FFTLIB_SUCCESS)
    // {
    //     l_u8_ret = 2;
    //     goto error;
    // }
    
    /* 批量执行fft */
    status_opt = FFTLIB_fft1dBatched_i16sc_c16sc_o16sc_kernel((int16_t *) pX, &bufParamsData, (int16_t *) pW, &bufParamsTw,
                                                              (int16_t *) pY, &bufParamsData, (uint32_t *) pShift, &bufParamsShift, 
                                                              numPoints, l_u32_channel, pblock);
    if (status_opt != FFTLIB_SUCCESS)
    {
        l_u8_ret = 3;
        goto error;
    }

    error:
    /* 释放内存 */
    if (pW != NULL)
    {
        free(pW);
    }
    if (pShift != NULL)
    {
        free(pShift);
    }

    return l_u8_ret;
}

我是否错过了导致连续呼叫无法正常工作的任何步骤? 如果我想持续计算 FFT、应该如何修改代码? 希望 TI 的工程师能够帮忙解决这个问题。