• AVR Freaks

Hot!AGC library not working?

Author
rweiser
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2018/09/18 21:52:47
  • Location: 0
  • Status: offline
2019/08/20 21:54:31 (permalink)
0

AGC library not working?

Hello,
 
I am using the AGC library to amplify small signals picked by the mic and attenuate loud signals so they can be processed by the FFT function from the DSP library.
 
I have initialized the AGC and set the amplitude target to 0.5f. I know from testing and documentation that if you pass anything to the DSP library outside of the range -0.5 to 0.5 fractcomplex format it will output garbage.
 
Is the 0.5f of the AGC equivalent to the -0.5 to 0.5 range for the DSP library? I am finding that if I pass values from the ADC that are near clipping my frequency detection stops working and get wrong results. My code is as follows:
 
void initAGC(void)
{
    AGC_init(AGCstate);
    AGC_setAmplitudeTarget(AGCstate,Q15(0.5f));
}

void readMic(void)//Sample microphone input
{
        ADC1_ChannelSelectSet(ADC1_AI_MIC);
        ix_MicADCbuff=0;
        for(ix_MicADCbuff=0;ix_MicADCbuff<FFT_BLOCK_LENGTH;ix_MicADCbuff++)
            {
                Delay_us(100);
                ADC1_SamplingStop();
                while(!ADC1_IsConversionComplete()){}
                //micADCbuff[ix_MicADCbuff]=ADC1_Channel0ConversionResultGet();
                sigCmpx[ix_MicADCbuff].real = ADC1_Channel0ConversionResultGet();
                sigCmpx[ix_MicADCbuff].imag = 0;
            }
}

void alarmFreq(void)//Detect the dominant frequency of the audio picked by the microphone
{
    readMic();
    fractional maxValue = sigCmpx[0].real;
    for(ix_MicADCbuff=0;ix_MicADCbuff<FFT_BLOCK_LENGTH;ix_MicADCbuff++)
        {
            if (sigCmpx[ix_MicADCbuff].real>maxValue)
            {
                maxValue = sigCmpx[ix_MicADCbuff].real;
            }
        }
    if(maxValue>16384)
    {
        VectorScale(FFT_BLOCK_LENGTH, &sigCmpx[0].real, &sigCmpx[0].real, 0.5);
    }
    AGC_apply(AGCstate,&sigCmpx[0].real,AGC_TRUE,AGC_PROC_FRAME);
 FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0]));// Perform FFT operation
    BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx[0]);// Store output samples in bit-reversed order of their addresses
 SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);//Compute the square magnitude of the complex FFT output array so we have a Real output vector
    VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin);//Find the frequency Bin ( = index into the SigCmpx[] array) that has the largest energy
 peakFrequency = peakFrequencyBin*(AUDIO_FS/FFT_BLOCK_LENGTH); //Compute the frequency (in Hz) of the largest spectral component
    fillFreqEnergy();
}

 
Right now my solution was to use the DSP function VectorScale() when the signal is bigger than 0.5 in combination with the AGC to amplify small signals.
#1
Jump to:
© 2019 APG vNext Commercial Version 4.5