espressif / esp-dsp

DSP library for ESP-IDF
Apache License 2.0
442 stars 87 forks source link

esp-dsp library question (DSP-85) #41

Closed darwin1234 closed 11 months ago

darwin1234 commented 2 years ago

These marcros are from CIMSIS-DSP arm_cfft_sR_f32_len256 arm_cfft_instance_f32 arm_cfft_f32

My question is what is the equivalent of those macros with esp-dsp library?

Thanks,

dmitry1945 commented 2 years ago

Hi @darwin1234 , In CIMSIS-DSP you have to initialize FFT for every instance. In Esp-DSP you have to initialize FFT once for all instances. That's why we have no full analog of arm_cfft_instance_f32 and arm_cfft_sR_f32_len256. And arm_cfft_f32 is not one to one. In Esp-DSP you have to initialize FFT module once by calling:

dsps_fft2r_init_fc32(...) then, depends on what you plan to do, you can use: dsps_fft2r_fc32() and dsps_bit_rev_fc32(...) or you can use just dsps_fft2r_fc32(). That's it. You can look to the example here: https://github.com/espressif/esp-dsp/tree/master/examples/fft4real or here: https://github.com/espressif/esp-dsp/tree/master/examples/fft

darwin1234 commented 2 years ago

Hi @dmitry1945,

Thanks for the quick response! :) I modified the code. Check below.

This is the original code that uses CIMSIS-DSP library

` const static arm_cfft_instance_f32* maskS; ///<---- maskS = &arm_cfft_sR_f32_len256; ///<---- int ptr;

for (unsigned j = 0; j < np; j++)     
{
    memset(maskgen, 0, partitionsize * 16);  // zero out maskgen
    // take part of impulse response and fill into maskgen
    for (unsigned i = 0; i < partitionsize; i++)
    {
        // THIS IS FOR REAL IMPULSE RESPONSES OR FIR COEFFICIENTS
        // the position of the impulse response coeffs (right or left aligned)
        // determines the useable part of the audio in the overlap-and-save (left or right part of the iFFT buffer)
        ptr = i + j * partitionsize;
        if (ptr < size) {
            maskgen[i * 2 + partitionsize * 2] = g_cabinet[ptr];
        }
        else  // Impulse is smaller than the fixed (defined) filter length (taps)
        {
            maskgen[i * 2 + partitionsize * 2] = 0.0;  // pad the last part of filter mask with zeros
        } 
    }
        // perform complex FFT on maskgen
    arm_cfft_f32(maskS, maskgen, 0, 1);  ///<----
    // fill into fmask array
    for (unsigned i = 0; i < partitionsize * 4; i++)
    {
        fmask[j][i] = maskgen[i];
    }
}
enabled = 1;
Serial.println("Mask file generated");`

and this is ESP-DSP library

`float maskgen[N_SAMPLES*2];

ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
int ptr;

  if (ret  != ESP_OK)
  {
      ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret);
     return;
  }

 for (unsigned j = 0; j < np; j++)     
 {

    for (unsigned i = 0; i < partitionsize; i++)
    {
        // THIS IS FOR REAL IMPULSE RESPONSES OR FIR COEFFICIENTS
        // the position of the impulse response coeffs (right or left aligned)
        // determines the useable part of the audio in the overlap-and-save (left or right part of the iFFT buffer)
        ptr = i + j * partitionsize;
        if (ptr < size) {
            maskgen[i * 2 + partitionsize * 2] = g_cabinet[ptr];
        }
        else  // Impulse is smaller than the fixed (defined) filter length (taps)
        {
            maskgen[i * 2 + partitionsize * 2] = 0.0;  // pad the last part of filter mask with zeros
        } 
    }

    dsps_fft2r_fc32(fmask, maskgen);

    for (unsigned i = 0; i < partitionsize * 4; i++)
    {
        fmask[j][i] = maskgen[i];
    }
}
enabled = 1;`

Is this correct ?

Thanks,

dmitry1945 commented 2 years ago

Hi @darwin1234 I htink you have forgoten to call dsps_bit_rev_fc32() after dsps_fft2r_fc32();

I will look somethink like this:

dsps_fft2r_fc32(maskgen, N_SAMPLES); dsps_bit_rev_fc32(maskgen, N_SAMPLES);

...