AnsweredAssumed Answered

F407VGT6 Audio DSP, ARM DSP-Library, unstable Biquad

Question asked by noll.markus on Jan 21, 2016
Latest reply on Feb 13, 2016 by vasilius
Hey guys,

I'm planning to make a 4 in 4 out audio dsp with f407vgt6 and two sgtl5000 codecs
One i2s is master, the other is slave. They're both used in bidirectional mode.
Dataformat is 24 bit left justified.

My PCB is still in production, so I'm testing with the f407 eval board and only on sgtl5000.


I got it already to work to get an audio playthrough.
But of course I want to do some filtering with biquads.
/*
 * dsp.h
 *
 *  Created on: 03.01.2016
 *      Author: Markus
 */
#ifndef APPLICATION_USER_DSP_H_
#define APPLICATION_USER_DSP_H_
 
#define ARM_MATH_CM4
 
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_i2s.h"
#include "stm32f4xx_hal_i2s_ex.h"
#include "arm_math.h"
 
 
I2S_HandleTypeDef * i2sHandle;
 
q31_t RxBuffer[256];
q31_t TxBuffer[256];
uint8_t State=2;
uint8_t EnableExchange = 0;
 
q31_t InputBuffer[4][64];
q31_t OutputBuffer[4][64];
 
q31_t BiquadCoeffTable[4][5*5];
q63_t BiquadStateTable[4][4*5];
arm_biquad_cas_df1_32x64_ins_q31  biquad0, biquad1;
 
void DSP_SetI2SHandle(I2S_HandleTypeDef * in) {
    i2sHandle = in;
}
 
void DSP_Start(void) {
 
    BiquadCoeffTable[0][0] = 30298;
    BiquadCoeffTable[0][1] = 60595;
    BiquadCoeffTable[0][2] = 30298;
    BiquadCoeffTable[0][3] = -1065764899;
    BiquadCoeffTable[0][4] = 529015178;
 
    arm_biquad_cas_df1_32x64_init_q31(&biquad0,1,&BiquadCoeffTable[0],&BiquadStateTable[0],2);
    arm_biquad_cas_df1_32x64_init_q31(&biquad1,1,&BiquadCoeffTable[0],&BiquadStateTable[1],2);
 
    EnableExchange=0;
    HAL_I2SEx_TransmitReceive_DMA(i2sHandle,&TxBuffer,&RxBuffer,256);
 
    biquad0.numStages=1;
}
 
void DSP_DoWork(void) {
    if (State==2) return;
 
    //Copy first segment to InputBuffers
    if (State==0) {
        uint16_t i = 0;
        uint16_t j = 0;
        while (i < 64) {
            InputBuffer[0][i] = RxBuffer[j];
            InputBuffer[1][i] = RxBuffer[j+1];
            i++;
            j=j+2;
        }
    }
    //Copy second segment to InputBuffers
    if (State==1) {
            uint16_t i = 0;
            uint16_t j = 128;
            while (i < 64) {
                InputBuffer[0][i] = RxBuffer[j];
                InputBuffer[1][i] = RxBuffer[j+1];
                i++;
                j=j+2;
            }
        }
 
    //DSP Code here!
 
    arm_biquad_cas_df1_32x64_q31(&biquad0,&InputBuffer[0],&OutputBuffer[0],64);
    arm_biquad_cas_df1_32x64_q31(&biquad1,&InputBuffer[1],&OutputBuffer[1],64);
 
 
 
 
    //Copy first segment to output buffers
    if (State==0) {
        uint16_t i = 0;
        uint16_t j = 0;
        while (i < 64) {
            TxBuffer[j] = OutputBuffer[0][i];
            TxBuffer[j+1] = OutputBuffer[1][i];
            i++;
            j=j+2;
        }
    }
    //Copy second segment to output buffers
    if (State==1) {
            uint16_t i = 0;
            uint16_t j = 128;
            while (i < 64) {
                TxBuffer[j] = OutputBuffer[0][i];
                TxBuffer[j+1] = OutputBuffer[1][i];
                i++;
                j=j+2;
            }
        }
 
    State=2;
}
 
void DSP_EnableExchange(void) {
    EnableExchange = 1;
 
}
 
void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) {
    if (EnableExchange==0) return;
    State=0;
    return;
}
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s){
    if (EnableExchange==0) return;
    State=1;
    return;
}
void HAL_I2S_TxCpltCallback (I2S_HandleTypeDef *hi2s) {
    return;
}
void HAL_I2STxHalfCpltCallback (I2S_HandleTypeDef *hi2s) {
    return;
}
void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) {
    return;
}
 
 
 
 
 
#endif /* APPLICATION_USER_DSP_H_ */

The parameters were calculated by this site:
http://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/
Pay attention. The a-parameters on this website are the b-paramter and reverse.
I took the values and multiplied them with 2^29 to get Q29 format (I used 2 as post shift)
Of course I took also attention to multiply the a0 and a1 with -1 because the biquad used by these arm function works as in this picture https://www.keil.com/pack/doc/CMSIS/DSP/html/BiquadPostshift.gif

Thank you.
I hope someone can help me.
If I copy the inputbuffer directly to output buffer there's no problem.
But with the biquads they crush the sound and it becomes a very very very loud white noise.




Outcomes