⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_test.c

📁 ADI Blackfin BF51X 範例程式
💻 C
📖 第 1 页 / 共 2 页
字号:

	/* 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 + -