📄 audio_test.c
字号:
*pSIC_IMASK = 0x00000200;
ssync();
}
//--------------------------------------------------------------------------//
// Function: Enable_DMA_Sport //
// //
// Description: Enable DMA1, DMA2, Sport0 TX and Sport0 RX //
//--------------------------------------------------------------------------//
void Enable_DMA_Sport0(void)
{
// enable DMAs
*pDMA2_CONFIG = (*pDMA2_CONFIG | DMAEN);
*pDMA1_CONFIG = (*pDMA1_CONFIG | DMAEN);
// enable Sport0 TX and RX
*pSPORT0_TCR1 = (*pSPORT0_TCR1 | TSPEN);
*pSPORT0_RCR1 = (*pSPORT0_RCR1 | RSPEN);
}
//--------------------------------------------------------------------------//
// Function: Disable_DMA_Sport //
// //
// Description: Disable DMA1, DMA2, Sport0 TX and Sport0 RX //
//--------------------------------------------------------------------------//
void Disable_DMA_Sport0(void)
{
// disable Sport0 TX and RX
*pSPORT0_TCR1 = (*pSPORT0_TCR1 & ~TSPEN);
*pSPORT0_RCR1 = (*pSPORT0_RCR1 & ~RSPEN);
// disable DMAs
*pDMA2_CONFIG = (*pDMA2_CONFIG & ~DMAEN);
*pDMA1_CONFIG = (*pDMA1_CONFIG & ~DMAEN);
}
//--------------------------------------------------------------------------//
// Function: Sport0_RX_ISR //
// //
// Description: This ISR is executed after a complete frame of input data //
// has been received. The new samples are stored in //
// iChannel0LeftIn, iChannel0RightIn, iChannel1LeftIn and //
// iChannel1RightIn respectively. Then the function //
// Process_Data() is called in which user code can be executed.//
// After that the processed values are copied from the //
// variables iChannel0LeftOut, iChannel0RightOut, //
// iChannel1LeftOut and iChannel1RightOut into the dma //
// transmit buffer. //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(Sport0_RX_ISR_AUDIO)
{
int iChannelX0_Left, iChannelX0_Right;
int iChannelX1_Left, iChannelX1_Right;
int iChannelX;
float fIn;
// confirm interrupt handling
*pDMA1_IRQ_STATUS |= DMA_DONE;
if(g_bTestDAC3_ADC2)
{
// copy input data from dma input buffer into variables
iChannelX1_Left = iRxBuffer1[INTERNAL_ADC_L1];
iChannelX1_Right = iRxBuffer1[INTERNAL_ADC_R1];
g_fSineWaveIn_Left2[g_iSampleIndexAudio] = (short)(iChannelX1_Left >> 16);
g_fSineWaveIn_Right2[g_iSampleIndexAudio] = (short)(iChannelX1_Right >> 16);
}else
{
// copy input data from dma input buffer into variables
iChannelX0_Left = iRxBuffer1[INTERNAL_ADC_L0];
iChannelX0_Right = iRxBuffer1[INTERNAL_ADC_R0];
iChannelX1_Left = iRxBuffer1[INTERNAL_ADC_L1];
iChannelX1_Right = iRxBuffer1[INTERNAL_ADC_R1];
g_fSineWaveIn_Left0[g_iSampleIndexAudio] = (short)(iChannelX0_Left >> 16);
g_fSineWaveIn_Right0[g_iSampleIndexAudio] = (short)(iChannelX0_Right >> 16);
g_fSineWaveIn_Left1[g_iSampleIndexAudio] = (short)(iChannelX1_Left >> 16);
g_fSineWaveIn_Right1[g_iSampleIndexAudio] = (short)(iChannelX1_Right >> 16);
}
// send data to output
iChannelX = (int)(AMPLITUDE * sin( (2.0 * PI * DESIRED_FREQ * ( ((float)(g_iSampleCount+1)) / SAMPLE_RATE))) );
if(g_bTestDAC3_ADC2)
{
// copy processed data from variables into dma output buffer
iTxBuffer1[INTERNAL_DAC_L2] = iChannelX;
iTxBuffer1[INTERNAL_DAC_R2] = iChannelX;
}else
{
// copy processed data from variables into dma output buffer
iTxBuffer1[INTERNAL_DAC_L0] = iChannelX;
iTxBuffer1[INTERNAL_DAC_R0] = iChannelX;
iTxBuffer1[INTERNAL_DAC_L1] = iChannelX;
iTxBuffer1[INTERNAL_DAC_R1] = iChannelX;
}
g_iSampleIndexAudio++; // only increment the index when both channels have been sent.
if( g_iSampleIndexAudio > MAX_SAMPLES-1 )
g_iSampleIndexAudio = 0;
g_iSampleCount++;
}
//--------------------------------------------------------------------------//
// Function: Test_Channel //
// //
// Description: Takes a buffer of data and determines if the frequecny is
// and amplitude are within acceptable limits
//--------------------------------------------------------------------------//
int Test_Channel_AUDIO(short* psRealIn)
{
short nSampleNumber;
short iTempFreq;
short nHighestFreqIndex;
float fSampledFrequency;
// twiddle factors
complex_fract16 w[MAX_SAMPLES];
complex_fract16 out[MAX_SAMPLES];
complex_fract16 t[MAX_SAMPLES];
fract16 in[MAX_SAMPLES];
// 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, t, out, w, 1, MAX_SAMPLES, 0, 0 );
// expect one of the index's of the array to contain a
// 'spike' or high value such that frequency == index * (SAMPLE_RATE/MAX_SAMPLES) == 3000
iTempFreq = (short)sqrt(out[0].re*out[0].re+out[0].im*out[0].im);
for( nSampleNumber = 1; nSampleNumber < (MAX_SAMPLES / 2); nSampleNumber++ )
{
if( ((short)sqrt(out[nSampleNumber].re*out[nSampleNumber].re+out[nSampleNumber].im*out[nSampleNumber].im)) > iTempFreq )
{
iTempFreq = (short)sqrt(out[nSampleNumber].re*out[nSampleNumber].re+out[nSampleNumber].im*out[nSampleNumber].im);
nHighestFreqIndex = nSampleNumber;
}
}
// 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 streangth
float fDB = 10 * log10( (float)iTempFreq );
if( fDB < MIN_SIGNAL_STRENGTH )
{
return 0;
}
return 1;
}
return 0; // test failed
}
int TEST_AUDIO(void)
{
int nResult = 0;
//clean up global buffer
memset(iTxBuffer1, '\0', sizeof(iTxBuffer1));
memset(iRxBuffer1, '\0', sizeof(iRxBuffer1));
memset(g_fSineWaveIn_Left0, '\0', sizeof(g_fSineWaveIn_Left0));
memset(g_fSineWaveIn_Left1, '\0', sizeof(g_fSineWaveIn_Left1));
memset(g_fSineWaveIn_Left2, '\0', sizeof(g_fSineWaveIn_Left2));
memset(g_fSineWaveIn_Right0, '\0', sizeof(g_fSineWaveIn_Right0));
memset(g_fSineWaveIn_Right1, '\0', sizeof(g_fSineWaveIn_Right1));
memset(g_fSineWaveIn_Right2, '\0', sizeof(g_fSineWaveIn_Right2));
g_iSampleCount = 0;
g_bTestDAC3_ADC2 = false;
Init_Timers();
Init_Timer_Interrupts();
Init_EBIU();
Init_Flash();
Init1836();
Init_Sport0_AUDIO();
Init_DMA();
Init_Sport_Interrupts();
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;");
}while( (g_iSampleCount < REQUIRED_SAMPLES) && (!IsTimedout(nTimer)) );
}
ClearTimeout(nTimer);
//start test DAC3_ADC2;
g_bTestDAC3_ADC2 = true;
g_iSampleCount = 0;
g_iSampleIndexAudio = 1;
nTimer = SetTimeout(0x50000);
if( ((unsigned int)-1) != nTimer )
{
// once the required number of samples has been collected,
// process the signal.
do{
asm("nop;");
}while( (g_iSampleCount < REQUIRED_SAMPLES) && (!IsTimedout(nTimer)) );
}
ClearTimeout(nTimer);
Disable_DMA_Sport0();
// turn off interrupts so that the data is stable.
interrupt(ik_ivg9, SIG_IGN);
// disable Sport0 RX interrupt
*pSIC_IMASK &= (~IRQ_SPORT0_RX);
// test the right channel 0
nResult = Test_Channel_AUDIO(g_fSineWaveIn_Right0);
if( 1 != nResult )
{
return false;
}
// Right channel was OK, test left channel 0
nResult = Test_Channel_AUDIO(g_fSineWaveIn_Left0);
if( 1 != nResult )
{
return false;
}
// test the right channel 1
nResult = Test_Channel_AUDIO(g_fSineWaveIn_Right1);
if( 1 != nResult )
{
return false;
}
// Right channel was OK, test left channel 1
nResult = Test_Channel_AUDIO(g_fSineWaveIn_Left1);
if( 1 != nResult )
{
return false;
}
// test the right channel 2
nResult = Test_Channel_AUDIO(g_fSineWaveIn_Right2);
if( 1 != nResult )
{
return false;
}
// Right channel was OK, test left channel 2
nResult = Test_Channel_AUDIO(g_fSineWaveIn_Left2);
if( 1 != nResult )
{
return false;
}
return true;
}
//--------------------------------------------------------------------------//
// Function: main //
// //
// Description: After calling a few initalization routines, main() just //
// waits in a loop forever. The code to process the incoming //
// data can be placed in the function Process_Data() in the //
// file "Process_Data.c". //
//--------------------------------------------------------------------------//
#ifdef _STANDALONE_ // use this to run standalone tests
void main(void)
{
do{
if( 0 == TEST_AUDIO() )
{
asm("emuexcpt;");
}
}while(1);
}
#endif //_STANDALONE_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -