📄 audio_test.c
字号:
/* configure DMA4 */
*pDMA4_CONFIG = WDSIZE_32 |FLOW_1; /* 32-bit transfers, autobuffer mode */
*pDMA4_START_ADDR = iTxBuffer1; /* start address of data buffer */
*pDMA4_X_COUNT = 4; /* DMA loop count */
*pDMA4_X_MODIFY = 4; /* DMA loop address increment */
}
/****************************************************************************
* Function: Enable_SPORT0_DMA_TDM_Streams
* Description: Enable DMA3, DMA4, Sport0 TX and Sport0 RX
******************************************************************************/
void Enable_DMA_Sport0(void)
{
/* enable DMAs */
*pDMA4_CONFIG = (*pDMA4_CONFIG | DMAEN);
*pDMA3_CONFIG = (*pDMA3_CONFIG | DMAEN);
/* enable sport0 TX and RX */
*pSPORT0_TCR1 = (*pSPORT0_TCR1 | TSPEN);
*pSPORT0_RCR1 = (*pSPORT0_RCR1 | RSPEN);
}
/****************************************************************************
* Function: Sport0_RX_ISR
* Description: This ISR is executed after a complete frame of input data
* has been received. The ISR will output the sine wave data
* and when the data is received it is stored in a buffer
******************************************************************************/
EX_INTERRUPT_HANDLER(Sport0_RX_ISR)
{
/* confirm interrupt handling */
*pDMA3_IRQ_STATUS = 0x0001;
*pDMA4_IRQ_STATUS = 0x0001;
if( bMicInLineOut )
{
/* copy input data from dma input buffer into variables */
iChannel1LeftIn = iRxBuffer1[INTERNAL_ADC_L1];
iChannel1RightIn = iRxBuffer1[INTERNAL_ADC_R1];
g_fSineWaveIn_Right[g_iSampleIndex] = (short)(iChannel1RightIn>>16);
g_fSineWaveIn_Left[g_iSampleIndex] = (short)(iChannel1LeftIn>>16);
iChannel1LeftOut = g_sInput[g_iIndex]<<16;
iChannel1RightOut = g_sInput[g_iIndex++]<<16;
/* copy processed data from variables into dma output buffer */
iTxBuffer1[INTERNAL_DAC_L1] = iChannel1LeftOut;
iTxBuffer1[INTERNAL_DAC_R1] = iChannel1RightOut;
}
else
{
/* copy input data from dma input buffer into variables */
iChannel0LeftIn = iRxBuffer1[INTERNAL_ADC_L0];
iChannel0RightIn = iRxBuffer1[INTERNAL_ADC_R0];
iChannel1LeftIn = iRxBuffer1[INTERNAL_ADC_L1];
iChannel1RightIn = iRxBuffer1[INTERNAL_ADC_R1];
g_fSineWaveIn_Right[g_iSampleIndex] = (short)(iChannel0RightIn>>16);
g_fSineWaveIn_Left[g_iSampleIndex++] = (short)(iChannel0LeftIn>>16);
g_fSineWaveIn_Right[g_iSampleIndex] = (short)(iChannel1RightIn>>16);
g_fSineWaveIn_Left[g_iSampleIndex] = (short)(iChannel1LeftIn>>16);
iChannel0LeftOut = g_sInput[g_iIndex]<<16;
iChannel0RightOut = g_sInput[g_iIndex++]<<16;
iChannel1LeftOut = g_sInput[g_iIndex]<<16;
iChannel1RightOut = g_sInput[g_iIndex++]<<16;
/* copy processed data from variables into dma output buffer */
iTxBuffer1[INTERNAL_DAC_L0] = iChannel0LeftOut;
iTxBuffer1[INTERNAL_DAC_R0] = iChannel0RightOut;
iTxBuffer1[INTERNAL_DAC_L1] = iChannel1LeftOut;
iTxBuffer1[INTERNAL_DAC_R1] = iChannel1RightOut;
}
/* check if we should reset index */
if( g_iIndex == 256 )
g_iIndex = 0;
g_iSampleIndex++;
/* check if we should reset index */
if( g_iSampleIndex > MAX_SAMPLES-1 )
g_iSampleIndex = 0;
g_iSampleCount++;
}
/****************************************************************************
* Function: Test_Channel
* Description: Takes a buffer of data and determines if the frequency
* and amplitude are within acceptable limits
******************************************************************************/
int Test_Channel(short* psRealIn)
{
short nSampleNumber;
short nHighestFreqIndex;
float fSampledFrequency;
float fSigStrengthMaxFreq = 0.0;
float fSigStrengthNoise = 0.0;
int i = 0;
/* FFT magnitude (includes Nyquist) */
fract16 mag[(MAX_SAMPLES / 2) + 1];
/* twiddle factors */
complex_fract16 w[MAX_SAMPLES];
complex_fract16 out[MAX_SAMPLES];
fract16 in[MAX_SAMPLES];
int BlockExponent;
/* create the input sinewave 3000 hz at 48000 sample rate amplitude is 24-bit's max */
for( nSampleNumber = 0; nSampleNumber < MAX_SAMPLES; nSampleNumber++ )
{
in[nSampleNumber] = (short)psRealIn[nSampleNumber];
}
/* generate twiddle factors */
twidfftrad2_fr16(w, MAX_SAMPLES);
/* perform real fft */
rfft_fr16( in, out, w, 1, MAX_SAMPLES, &BlockExponent, 1 );
/* expect one of the indexes of the array to contain a spike or high value such that
frequency == [index * (SAMPLE_RATE/MAX_SAMPLES)] == 3000 */
for( nSampleNumber = 0; nSampleNumber <= (MAX_SAMPLES / 2); nSampleNumber++ )
{
mag[nSampleNumber] = cabs_fr16(out[nSampleNumber]);
}
nHighestFreqIndex = vecmaxloc_fr16(mag,(MAX_SAMPLES / 2) + 1);
/* multiply the index of the array of the highest value with the sample rate value */
fSampledFrequency = nHighestFreqIndex * (SAMPLE_RATE / MAX_SAMPLES);
/* make sure frequency is within acceptable ranges */
if( (fSampledFrequency < MAX_DESIRED_FREQ) && (fSampledFrequency > MIN_DESIRED_FREQ) )
{
/* check the signal strength */
float fDB = 10 * log10( (float)mag[nHighestFreqIndex] );
if( fDB < MIN_SIGNAL_STRENGTH )
{
return 0; /* test failed */
}
float fSigStrength = 0.0;
for( i = 1; i <= (MAX_SAMPLES / 2); i++)
{
fSigStrength = 10 * log10( (float)mag[i] );
/* track max value */
if ( i == nHighestFreqIndex)
{
fSigStrengthMaxFreq = fSigStrength;
}
else
{
if (fSigStrength > fSigStrengthNoise)
fSigStrengthNoise = fSigStrength;
}
if( (fSigStrength > MAX_NOISE_THRESHOLD) && (i != nHighestFreqIndex) )
return 0; /* test failed */
}
return 1; /* test passed */
}
return 0; /* test failed */
}
/*******************************************************************
* Function: TEST_AUDIO
* Description: Main test routine will get launched from the POST
* framework.
*******************************************************************/
int TEST_AUDIO(void)
{
int nResult = 1;
int i = 0, n = 0;
/* allocate storage for our buffers */
g_sInput = malloc(sizeof(short) * MAX_SAMPLES);
g_fSineWaveIn_Left = malloc(sizeof(short) * MAX_SAMPLES);
g_fSineWaveIn_Right = malloc(sizeof(short) * MAX_SAMPLES);
/* make sure the buffers were allocated */
if( (g_sInput == NULL) || (g_fSineWaveIn_Left == NULL) || (g_fSineWaveIn_Right == NULL) )
{
/* free any allocated memory */
if ( g_sInput ) free(g_sInput);
if ( g_fSineWaveIn_Left ) free(g_fSineWaveIn_Left);
if ( g_fSineWaveIn_Right ) free(g_fSineWaveIn_Right);
return 0;
}
/* clear the buffers that will hold our sine wave data to make
sure we are always getting new data */
for( i = 0; i < MAX_SAMPLES; i++ )
{
g_fSineWaveIn_Left[i] = 0;
g_fSineWaveIn_Right[i] = 0;
}
/* create out sine wave */
for( i = 0; i < MAX_SAMPLES; i++ )
{
g_sInput[i] = (int)(AMPLITUDE * sin( (2.0 * PI * DESIRED_FREQ * ( ((float)(i+1)) / SAMPLE_RATE))) );
}
for(n = 0; ((n < 2) && nResult); n++)
{
/* initialize some global variables */
g_iIndex = 0;
g_iSampleCount = 0;
g_iSampleIndex = 1;
Init_Timers();
Init_Timer_Interrupts();
Init_Flags();
Init_Codec();
Init_Sport0();
Init_DMA();
Init_Interrupts();
iTxBuffer1[0]=0x30303030;
iTxBuffer1[1]=0x30303030;
Enable_DMA_Sport0();
unsigned int nTimer = SetTimeout(0x50000);
if( ((unsigned int)-1) != nTimer )
{
/* once the required number of samples has been collected,
process the signal */
do
{
asm("nop;");
asm("nop;");
asm("nop;");
asm("nop;");
}while( (g_iSampleCount < REQUIRED_SAMPLES) && (!IsTimedout(nTimer)) );
}
ClearTimeout(nTimer);
/* turn off interrupts so that the data is stable */
interrupt(ik_ivg9, SIG_IGN);
/* disable DMA and SPORT TX/RX */
*pDMA0_CONFIG &= ~0x1;
*pDMA1_CONFIG &= ~0x1;
*pSPORT0_TCR1 &= ~0x1;
*pSPORT0_RCR1 &= ~0x1;
/* test the left channel */
nResult = Test_Channel(g_fSineWaveIn_Left);
if( 1 == nResult ) /* left channel was good, test right channel */
{
nResult = Test_Channel(g_fSineWaveIn_Right);
}
if( bMicInLineOut )
{
bMicInLineOut = false;
/* INSEL = Line Input Select to ADC */
sCodecTxRegs[4] &= 0xFFFB;
}
else
{
bMicInLineOut = true;
/* INSEL = Microphone Input Select to ADC */
sCodecTxRegs[4] |= 0x4;
}
}
/* free allocated memory */
free(g_sInput);
free(g_fSineWaveIn_Left);
free(g_fSineWaveIn_Right);
/* invalidate our buffers */
g_sInput = NULL;
g_fSineWaveIn_Left = NULL;
g_fSineWaveIn_Right = NULL;
/* return result */
return nResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -