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

📄 mp3encoder2.c

📁 合众达6713DSP开发板mp3低通滤波
💻 C
字号:
/*
 *  ======== main.c ========
 * 
 *  This example demonstrates the use of IOM drivers with SIOs and tasks by 
 *  using the DIO class driver with a user defined device mini-driver 
 *  called "codec" and a class driver DIO instance called "dio_codec". This is 
 *  the loopback application where audio is read from an input SIO, then sent 
 *  back via an output SIO.

 *  The following objects need to be created in the DSP/BIOS
 *  configuration for this application:
 *
 *  * A UDEV object, which links in a user device driver. In this
 *    case the UDEV is a codec based IOM device driver.
 *  * A DIO object, which links the UDEV object.
 *  * A TSK object, with the function to run set to the function demo
 *    defined in this file.
 *  * A LOG named trace for debug and status output.
 */
#include <std.h>
#include <log.h>
#include <sys.h>
#include <mem.h>
#include <sio.h>

#include <csl.h>
#include <csl_cache.h>
#include <csl_i2c.h>
#include <csl_mcasp.h>

#include <math.h>
#include <stdio.h>

#include <dec6713.h>
#include <dec6713_edma_aic23.h>

#define NUM_CODEC_CHANNELS	 2	/* stereo: left + right		*/
#define SAMPLEING_RATE		48	/* 48 samples/ms			*/
#define FRAME_SIZE			10	/* 10 ms					*/
#define	NFRAMES				100	/* 100 frames = 1 second	*/
#define	BUFLEN		(NUM_CODEC_CHANNELS*SAMPLEING_RATE*FRAME_SIZE)

#ifdef _6x_
extern far LOG_Obj trace;

/* 
 * Buffers placed in external memory are aligned on a 128 bytes boundary.
 * In addition, the buffer should be of a size multiple of 128 bytes for 
 * the cache work optimally on the C6x.
 */
#define BUFALIGN 128    /* alignment of buffer to allow use of L2 cache */
#else
extern LOG_Obj trace;
#define BUFALIGN 1
#endif

#define BUFSIZE (BUFLEN * sizeof(short)) 

#pragma DATA_SECTION(DataBuffer,".Audio_data");
Uint32 DataBuffer[9320] = {0};
/*chorus's frequence set*/

unsigned short uWork;//PCM编码结果
unsigned char cWork;
short sign, segment;
short temp, quant;
char seg;
//int absol;
unsigned int absol, tem;

short RxData;
short output;	

unsigned int i,j;
	

/*
 *  ======== DEC6713_DEVPARAMS ========
 *  This static initialization defines the default parameters used for
 *  DEC6713_EDMA_AIC23 IOM driver
 */
DEC6713_EDMA_AIC23_DevParams DEC6713_CODEC_DEVPARAMS =
        DEC6713_EDMA_AIC23_DEFAULT_DEVPARAMS;

/* inStream and outStream are SIO handles created in main */
SIO_Handle inStream, outStream;

/* 	Function prototype */
static Void prime();

/*
 * ======== main ========
 */
Void main()
{

    LOG_printf(&trace, "echo started");
}


/*
 *  ======== copyWithEcho ========
 * Copy an incoming buffer with stereo audio samples into an outgoing
 * buffer, mixing with samples from the echo buffer indexed by
 * the parameter timeDelay.  The parameter "a" indicates the mix
 * attenuation * 256 (i.e. 64 = 0.25).
 */
void PlayAudio(short *inBuf, short *outBuf)
{

   	for(j=0;j<BUFLEN;j++){

		RxData = * inBuf++;
	   
	 //PCM编码
     //   tem=absol=abs(RxData);
	     sign=(RxData >= 0)?1:0;//判断Left正负

	     absol=_abs(RxData);//计算Left绝对值

		 i = _norm (absol);		 

         seg = 26-i;

		 if(seg<=0) {//如果Left绝对值位数大于12
       		seg=0;
		//	quant = _smpy( absol, 1);
		//	quant &=0x0F;
	        quant=(absol>>1)&0x0F;//取Left绝对值的第1位到第4位的数据 

	     }
	     else{
	         quant=(absol>>seg)&0x0F;//取Left绝对值的第seg位到第(seg+4)位的数据 
		//	quant = _smpy( absol, seg);
		//	quant &=0x0F;
        }
		seg = _smpy( seg, 4);;//计算chord数值
       

       /* sign=(RxData >= 0)?1:0;//判断Left正负
	   	if(sign>0)
	        tem=absol=RxData;
		else
		    tem=absol=-RxData;
        //i=16-Left绝对值的最高位的位数   
		
        if(tem>=256){
			if(tem>=2048){		
				if (tem>=16384) {//2^14
					quant= tem & 0x3C00;//(0011 1100 0000 000)
					quant<<=10;
					seg=0xA0;
				}
	    		else if (tem>=8192) {//2^13
					quant= tem & 0x1E00;//(0001 1110 0000 000)
					quant<<=9;
					seg=0x90;
				}
				else if (tem>=4096) {//2^12
					quant= tem & 0x0F00;//(0000 1111 0000 000)
					quant<<=8;
					seg=0x80;
				}
				else  {//2^11
					quant= tem & 0x0780;//(0000 0111 1000 000)
					quant<<=7;
		    		seg=0x70;
	    		}
			}
			else{
				if (tem>=1024) {//2^10
					quant= tem & 0x03C0;//(0000 0011 1100 000)
					quant<<=6;
					seg=0x60;
				}
	   			else if (tem>=512) {//2^9
					quant= tem & 0x01E0;//(0000 0001 1110 000)
					quant<<=5;
					seg=0x50;
				}
				else  {//2^8
					quant= tem & 0x00F0;//(0000 0000 1111 0000)
					quant<<=4;
					seg=0x40;
				}
			}
		}
		else{
			if(tem>=32)
			{
				if (tem>=128) {//2^7
					quant= tem & 0x0078;//(0000 0000 0111 1000)
					quant<<=3;
					seg=0x30;
				}
	    		else if (tem>=64) {//2^6
					quant= tem & 0x003C;//(0000 0000 0011 1100)
					quant<<=2;
					seg=0x20;
				}
				else {//2^5
		 	  	    quant= tem & 0x001E;//(0000 0000 0001 1110)
					seg=0x10;
				}
			}
			else
			{
				if(tem>=16){//2^4
		   	 		quant= tem / 2 ;
					seg=0;
				}
				else if(tem>=8){//2^3
		    		quant= tem / 2 ;
					seg=0x90;
				}
				else if(tem>=4){//2^2
		    		quant= tem / 2 ;
					seg=0xA0;
				}
				else{
					quant= tem / 2 ;
					seg=0xB0;
				}
			}
		}*/
		        
	    output=seg+quant;	        	        
	    if(absol>4095) //Left绝对值与0xFFF相比较
            output=0x7F;	            	            
        if(sign)//Left正负
	        output^=0xD5;//Left负
        else
	        output^=0x55;//Left正		        
        uWork=(unsigned char)output;//左通道编码为编码结果 	        	        
        uWork<<=8;//左通道编码为编码结果的高8位	        
        
        //pCM 解码

       	cWork=uWork>>8;//取左通道PCM数值        	
       	temp=cWork^0xD5;
       	 // 	sign=(temp&0x80)>>7;
       	if(temp>=0x80)	{
       	    sign = 1;
       	    temp &= 0x70;
       	} 
       	else
       	    sign = 0;   	    
         
       //	segment=(temp&0x70)>>4;
        segment= temp ;
        
       	quant=temp&0x0F;
      //  quant = temp %16 ;
       	quant<<=1;
	 //   quant *= 2;
       	if(!segment)
            quant+=1;
        else  {
            quant+=33;
			segment >>= 4;
			segment -=1;;
            quant<<=segment;
        }
        if ( sign )
	        RxData=-quant;
        else
            RxData=quant;

		*outBuf++ = RxData;
	}
}

/*
 * ======== createStreams ========
 */
static Void createStreams()
{
    SIO_Attrs attrs;
    
    /* align the buffer to allow it to be used with L2 cache */
    attrs = SIO_ATTRS;
    attrs.align = BUFALIGN;
    attrs.model = SIO_ISSUERECLAIM;
	LOG_printf(&trace, "echo started");
    /* open the I/O streams */
    inStream = SIO_create("/dio_codec", SIO_INPUT, BUFSIZE, &attrs);
    LOG_printf(&trace, "echo started");
    if (inStream == NULL) {
        SYS_abort("Create input stream FAILED.");
    }

    outStream = SIO_create("/dio_codec", SIO_OUTPUT, BUFSIZE, &attrs);
    if (outStream == NULL) {
        SYS_abort("Create output stream FAILED.");
    }
}

/*
 * ======== prime ========
 */
static Void prime()
{
    Ptr buf0, buf1, buf2, buf3;

    LOG_printf(&trace, "Allocate buffers started");

    /* Allocate buffers for the SIO buffer exchanges */
    buf0 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
    buf1 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
    buf2 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
    buf3 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
    if (buf0 == NULL || buf1 == NULL || buf2 == NULL || buf3 == NULL) {
        SYS_abort("MEM_calloc failed.");
    } 
    
    /* Issue the first & second empty buffers to the input stream */
    if (SIO_issue(inStream, buf0, SIO_bufsize(inStream), NULL) != SYS_OK) {
        SYS_abort("Error issuing buffer to the input stream");
    }
    if (SIO_issue(inStream, buf1, SIO_bufsize(inStream), NULL) != SYS_OK) {
        SYS_abort("Error issuing buffer to the input stream");
    }

    /* Issue the first & second empty buffers to the output stream */
    if (SIO_issue(outStream, buf2, SIO_bufsize(outStream), NULL) != SYS_OK) {
        SYS_abort("Error issuing buffer to the output stream");
    }
    if (SIO_issue(outStream, buf3, SIO_bufsize(outStream), NULL) != SYS_OK) {
        SYS_abort("Error issuing buffer to the output stream");
    }
}

/*
 * ======== tskAudioDemo ========
 * This function copies from the input SIO to the output SIO. You could
 * easily replace the copy function with a signal processing algorithm. 
 */
Void tsk_Audio()
{
    Int nmadus;         /* number of minimal addressable units */
    short *inbuf, *outbuf;

    /* Call createStream function to create I/O streams */
    createStreams();
    
    /* Call prime function to do priming */
    prime();
    

    /* Loop forever looping back buffers */
    for (;;) {
        /* Reclaim full buffer from the input stream */
        if ((nmadus = SIO_reclaim(inStream, (Ptr *)&inbuf, NULL)) < 0) {
            SYS_abort("Error reclaiming full buffer from the input stream");
        }

        /* Reclaim empty buffer from the output stream to be reused */
        if (SIO_reclaim(outStream, (Ptr *)&outbuf, NULL) < 0) {
            SYS_abort("Error reclaiming empty buffer from the output stream");
        }

		/* process echo algorithm */
		PlayAudio(inbuf, outbuf);
		
        /* Issue full buffer to the output stream */
        if (SIO_issue(outStream, outbuf, nmadus, NULL) != SYS_OK) {
            SYS_abort("Error issuing full buffer to the output stream");
        }

        /* Issue an empty buffer to the input stream */
        if (SIO_issue(inStream, inbuf, SIO_bufsize(inStream), NULL) != SYS_OK) {
            SYS_abort("Error issuing empty buffer to the input stream");
        }
    }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -