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

📄 wtaudioplay.c

📁 MCF5249的音频驱动程序,可以实现PCM的实时播放和采集
💻 C
📖 第 1 页 / 共 3 页
字号:
    int delta;			/* Current adpcm output value */    int step;			/* Stepsize */    int valpred;		/* Predicted value */    int vpdiff;			/* Current change to valpred */    int index;			/* Current step change index */    int inputbuffer;		/* place to keep next 4-bit value */    int bufferstep;		/* toggle between inputbuffer/input */    outp = outdata;    inp = (signed char *)indata;    valpred = state->valprev;    index = state->index;    step = stepsizeTable[index];    bufferstep = 0;        for ( ; len > 0 ; len-- ) {		/* Step 1 - get the delta value */	if ( bufferstep ) {	    delta = inputbuffer & 0xf;	} else {	    inputbuffer = *inp++;	    delta = (inputbuffer >> 4) & 0xf;	}	bufferstep = !bufferstep;	/* Step 2 - Find new index value (for later) */	index += indexTable[delta];	if ( index < 0 ) index = 0;	if ( index > 88 ) index = 88;	/* Step 3 - Separate sign and magnitude */	sign = delta & 8;	delta = delta & 7;	/* Step 4 - Compute difference and new predicted value */	/*	** Computes 'vpdiff = (delta+0.5)*step/4', but see comment	** in adpcm_coder.	*/	vpdiff = step >> 3;	if ( delta & 4 ) vpdiff += step;	if ( delta & 2 ) vpdiff += step>>1;	if ( delta & 1 ) vpdiff += step>>2;	if ( sign )	  valpred -= vpdiff;	else	  valpred += vpdiff;	/* Step 5 - clamp output value */	if ( valpred > 32767 )	  valpred = 32767;	else if ( valpred < -32768 )	  valpred = -32768;	/* Step 6 - Update step value */	step = stepsizeTable[index];	/* Step 7 - Output value */	*outp++ = valpred;    }    state->valprev = valpred;    state->index = index;}void upcm_encode(unsigned char *indata, unsigned char * outdata, int len){	unsigned int i=0;	unsigned short *src = (unsigned short *)indata;		for(;i<(len/2);i++)		outdata[i] = linear2ulaw(src[i]);}void a2u_encode(unsigned char *indata, unsigned char *outdata, int len){	int i=0;	for(;i<len;i++)		outdata[i] = alaw2ulaw(indata[i]);}static inline short adpcm_ima_expand_nibble(char nibble,pADPCM state){	int index;	int valprev;	int sign, delta, diff, step;	step = stepsizeTable[state->index];	index = state->index + indexTable[(unsigned)nibble];	if (index < 0) index = 0;	else if (index > 88) index = 88;	sign = nibble & 8;	delta = nibble & 7;	/* perform direct multiplication instead of series of jumps proposed by	* the reference ADPCM implementation since modern CPUs can do the mults	* quickly enough */	diff = ((2 * delta + 1) * step) >> 3;	/*		diff = step >> 3;	if ( delta & 4 ) diff += step;	if ( delta & 2 ) diff += step>>1;	if ( delta & 1 ) diff += step>>2;	*/	valprev = state->valprev;	if (sign) valprev -= diff;	else valprev += diff;	CLAMP_TO_SHORT(valprev);	state->valprev = valprev;	state->index = index;	return (short)valprev;}void ad2u_Send(void* indata, OUTDATA_T* outdata, int nSrcSize, BYTE* private ){	//short *samples;	long *samples;	unsigned char *src;	pADPCM state;	short tmp;	state = (pADPCM)private;	samples = (long *)outdata; //dest	src = (unsigned char *)indata;      //src    	state->valprev = (*src++) & 0x0FF;	state->valprev |= ((*src++) << 8) & 0x0FF00;	if(state->valprev & 0x8000)		state->valprev -= 0x10000;	CLAMP_TO_SHORT(state->valprev);	//*samples++ = state->valprev;		*samples++ = (linear2ulaw(state->valprev)<<24)&0xff000000;	state->index = *src++;	if (state->index < 0) state->index = 0;	if (state->index > 88) state->index = 88;	*src++;	//if (*src++) fprintf(stderr, "unused byte should be null !!\n"); 		for(; src < ((unsigned char *)indata + nSrcSize);) 	{		//*samples++ = adpcm_ima_expand_nibble(src[0] & 0x0F,state);						*samples++ = (linear2ulaw(adpcm_ima_expand_nibble(src[0] & 0x0F,state))<<24)&0xff000000;		//*samples++ = adpcm_ima_expand_nibble((src[0] >> 4) & 0x0F,state);		 				*samples++ = (linear2ulaw(adpcm_ima_expand_nibble((src[0] >> 4) & 0x0F,state))<<24)&0xff000000;				src++;	}	//*pDestSize = (unsigned char *)samples - (unsigned char *)outdata;	return;}void ulaw_Send(void* indata, OUTDATA_T* outdata, int nSrcSize, BYTE* private ){	unsigned char* src = (unsigned char *)indata;	while(nSrcSize--){		*outdata++ = (*src<<24);		src++;			}}unsigned long ad2ulaw(short indata, struct adpcm_state *state){	int sign;			/* Current adpcm sign bit */    	int delta;			/* Current adpcm output value */    	int step;			/* Stepsize */    	int valpred;		/* Predicted value */    	int vpdiff;			/* Current change to valpred */    	int index;			/* Current step change index */  //unsigned char Intmp[4],Outtmp[4];	int i;	unsigned long outdata=0; 	valpred = state->valprev; 	 index = state->index;  	for(i=3; i>=0; i--){				//delta = (indata>>4*i)&0x0f;		if(i == 3)			delta = indata>>8;		else if(i == 2)			delta = indata>>12;		else if(i == 0)			delta = indata>>4;		else			delta = indata;		delta &= 0x0f;		//printf("delta[%d] = 0x%02x\n",i,delta);		    step = stepsizeTable[index];		index += indexTable[delta];		if ( index < 0 ) index = 0;		if ( index > 88 ) index = 88;		sign = delta & 8;		delta = delta & 7;		vpdiff = step >> 3;		if ( delta & 4 ) vpdiff += step;		if ( delta & 2 ) vpdiff += step>>1;		if ( delta & 1 ) vpdiff += step>>2;		if ( sign )	  		valpred -= vpdiff;		else	  		valpred += vpdiff;		if ( valpred > 32767 )	  		valpred = 32767;		else if ( valpred < -32768 )	  		valpred = -32768;		//printf("valpred = 0x%04x\n",valpred);		outdata |= (linear2ulaw(valpred)<<(8*i));		//printf("outdata =0x%04x\n",outdata);	}	//printf("outdata =0x%04x\n",outdata);	state->valprev = valpred;    	state->index = index;	return outdata;	}int Audio_encode(unsigned char *indata, unsigned char * outdata, int len, int coding_type,struct adpcm_state *state){	unsigned char *pBuf;	int i;	unsigned short * pInData;	unsigned long *pOutData;	pInData = (unsigned short *)indata;	pOutData = (unsigned long *)outdata;	switch(coding_type) {	case AUDIO_ENCODING_ADPCM:		for(i=0; i<len; i++){						*pOutData ++ = ad2ulaw(*pInData++,state);					}		//adpcm_decoder(indata,(short *)pBuf,len,&state);		//upcm_encode(pBuf,outdata,len*4);		//free(pBuf);		break;	case AUDIO_ENCODING_LINEAR:		upcm_encode(indata,outdata,len);		break;	case AUDIO_ENCODING_ALAW:		a2u_encode(indata, outdata, len);	case AUDIO_ENCODING_ULAW:		while (len--){ 			*outdata++ = *indata++;			//printf("%x ",*outdata);		}	default:		return -1; 			}	return 0;}inline static void AudioDelay(int n){	WTDevBufStatus DevStatu;	DWORD *pDataOut;		//ioctl(AudioID,IOCAGDEVBUFSTATUS,&DevStatu);		//pDataOut = (unsigned long *)&ABuffer[DevStatu.tx_nBufT];	pDataOut = (unsigned long *)&AU_Stream.destBuffer[AU_Stream.nDestTag*ADSAMP_PER_PACK];	memset((void *)pDataOut,0,ADSAMP_PER_PACK*4*n);				AU_Stream.nDestTag = write(AudioID,NULL,ADSAMP_PER_PACK*4*n);	}void mySig(void (*fun)(int)){	struct sigaction act;   	act.sa_handler = fun;   	sigemptyset(&act.sa_mask);   	act.sa_flags=0;	sigaction(SIGTERM,&act,NULL);    	sigaction(SIGHUP,&act,NULL);    	sigaction(SIGINT,&act,NULL);    	sigaction(SIGQUIT,&act,NULL);    	sigaction(SIGUSR1,&act,NULL);    	sigaction(SIGUSR2,&act,NULL); 	}void myExit(int signo){	//I6400WriteMem(0x2000,0x2);//Stop	//munmap(VBuffer,VIDEOBUFSIZE);	//munmap(ABuffer,AUDIOBUFSIZE);		munmap(VU_Stream.srcBuffer,VIDEOBUFSIZE);	munmap(VU_Stream.srcBuffer,APACKCOUNT*AU_Stream.nOutPSize);			AudioDelay(1);		close(VideoIN);	close(AudioID);		printf("exit()_signo[%d]\n",signo);	//alarm(0);	//raise(signo);	exit(1);}void subtime(struct timeval t1,struct timeval t2,int *sec, int *usec)//返回t1-t2之间的毫秒差{	*sec = t1.tv_sec - t2.tv_sec;	if(t1.tv_usec < t2.tv_usec){		*sec=(*sec)--;		*usec = t1.tv_usec - t2.tv_usec + 1000000;	}	else		*usec = t1.tv_usec - t2.tv_usec;}int main(int argc, char **argv){   		//char *VBuffer;  //video buffer map from kernel (wtmpeg)	//char *ABuffer; //audio buffer map from kernel  (wtaudio)	//int    nVRD = 0; //indicate the read offset from video buffer base	int sock_fd; 	struct sockaddr_in server_addr; 	char recvbuf[1024]; 	int n;	BYTE *pDataIN;	WORD *wpDataIN;	DWORD *pDataOUT;	WORD ChnNo;       WORD MediaType;	WTDevBufStatus DevStatu;	int 	AbufT, AbufB;	DWORD dwTmp;	_ADPCM state;	int i,j;	int coding;		struct timeval oldtime,currenttime;	int val_sec, val_usec;	//int Sendflag = 1;	WTAudio_dev audiod;#ifdef AUDIO_RECODE	int AudioRecode;#endif	if((sock_fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1) 	{   		perror("Create Socket error!\n");   		exit(1);  	} 	server_addr.sin_family=AF_INET; 	server_addr.sin_port=htons(8888); 	server_addr.sin_addr.s_addr=INADDR_ANY; 	bzero(&(server_addr.sin_zero),8); 	if(bind(sock_fd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))==-1) 	{  		perror("Bind socket error!\n");  		exit(1); 	}  		coding = AUDIO_ENCODING_ADPCM;#ifdef _AUDIO_UPCM_	coding = AUDIO_ENCODING_ULAW;#endif		//mySig(SIGINT, myExit);	mySig(myExit);#ifdef AUDIO_RECODE	AudioRecode = open("../Audio.upcm",O_CREAT |O_RDWR);	if(AudioRecode == -1)	{		printf("Can not open ../Audio.upcm.\n");		exit(0);	}#endif	state.index = 0;	state.valprev = 0;	VideoIN = open("/dev/MPG4CAP",O_RDWR );	if(VideoIN == -1)	{		printf("Can not open /dev/MPG4CAP.\n");		exit(0);	}		AudioID = open("/dev/WTAUDIO",O_RDWR );	if(AudioID  == -1)	{		printf("Can not open /dev/WTAUDIO.\n");		exit(0);	}		//VBuffer = (unsigned char *)mmap(0,VIDEOBUFSIZE, PROT_READ|PROT_WRITE,0,VideoIN,0);		//ABuffer = (unsigned char *)mmap(0,AUDIOBUFSIZE, PROT_READ|PROT_WRITE,0,AudioID,0);	VU_Stream.srcBuffer = (BYTE *)mmap(0,VIDEOBUFSIZE, PROT_READ|PROT_WRITE,0,VideoIN,0);		switch(coding){	case AUDIO_ENCODING_ULAW:				AU_Stream.nOutPSize = USAMP_PER_PACK;		ioctl(AudioID,IOCASPACKSIZE,&AU_Stream.nOutPSize);  //setup the size of audio package						AU_Stream.coding = AUDIO_ENCODING_ULAW;		AU_Stream.AudioSend = ulaw_Send;		AU_Stream.private = NULL;					break;	case AUDIO_ENCODING_ADPCM:				AU_Stream.nOutPSize = ADSAMP_PER_PACK;		ioctl(AudioID,IOCASPACKSIZE,&AU_Stream.nOutPSize); //setup the size of audio package						AU_Stream.coding = AUDIO_ENCODING_ADPCM;		AU_Stream.AudioSend = ad2u_Send;				AU_Stream.private = (BYTE*)&state;			break;	default :		printf("unknow audio type!!!\n");	}#ifdef AUDIO_RECODE		AU_Stream.destBuffer = (BYTE *)mmap(0,APACKCOUNT*AU_Stream.nOutPSize+RECODERSIZE, PROT_READ|PROT_WRITE,0,AudioID,0);#ifdef DEBUG	//printf("\nT[%x]-Base[%x]\n",(APACKCOUNT*AU_Stream.nOutPSize+RECODERSIZE),AU_Stream.destBuffer);	//printf("Base%x\n",);#endif#else	AU_Stream.destBuffer = (BYTE *)mmap(0,APACKCOUNT*AU_Stream.nOutPSize, PROT_READ|PROT_WRITE,0,AudioID,0);#endif   	while(1)	{#ifdef AUDIO_PLAYBACK				 VU_Stream.nSrcTag = read(VideoIN, NULL, VIDEOPACKSIZE*VU_Stream.nInBSize);		 		recvfrom(sock_fd,recvbuf,sizeof(recvbuf),0, (struct sockaddr*)NULL,NULL);		pDataIN =  (BYTE *)recvbuf;							pDataOUT = (DWORD*)&AU_Stream.destBuffer[AU_Stream.nDestTag*AU_Stream.nOutPSize];			//gettimeofday(&oldtime, NULL);				AU_Stream.AudioSend((void *)pDataIN, (OUTDATA_T*)pDataOUT, AU_Stream.nOutPSize, AU_Stream.private);				//ad2u_Send((void *)pDataIN, (OUTDATA_T *) pDataOUT, APCMPACKSIZE, NULL);			//gettimeofday(&currenttime ,NULL);			//subtime(currenttime, oldtime, &val_sec, &val_usec);			//printf("val_sec[%d] val_usec[%d]\n",val_sec, val_usec);				//printf("%d\n", nOutsize);							AU_Stream.nDestTag = write(AudioID,NULL, AU_Stream.nOutPSize*4);				//printf("%d\n",AU_Stream.nDestTag);							}					}#endif#ifdef AUDIO_RECODE#ifndef RX_IRQ#ifdef    DMA_TEST{		unsigned char *Dbuf;		//ioctl(AudioID,IOCASRXSTART); 				Dbuf = (BYTE*)malloc(sizeof(char)*4*8*1024);		while(1){		read(AudioID,(void *)Dbuf, 0);		printf("-------");		write(AudioRecode,(void *)Dbuf,(4*8*1024));		}}#else		{			BYTE* pAINbuf;			int nPos;			int n;			//pAINbuf = (BYTE*)malloc(4*ADSAMP_PER_PACK*sizeof(BYTE));			pAINbuf = (AU_Stream.destBuffer + APACKCOUNT*AU_Stream.nOutPSize);			ioctl(AudioID,IOCASRXSTART); 					nPos = read(AudioID, NULL, 4*ADSAMP_PER_PACK);			for(n=0; n<ADSAMP_PER_PACK*4; n++){				write(AudioRecode, &pAINbuf[nPos*4*ADSAMP_PER_PACK], 1);						}						}#endif#else		{			//unsigned long Dbuf[120];			int n,i,m;			BYTE* pAINbuf;			pAINbuf = (AU_Stream.destBuffer + 128*4*ADSAMP_PER_PACK);							m=120;				while((n=read(AudioID,(void *)NULL,m))<m){					//printf("%x\n",*pAINbuf);					for(i=0; i<n; i+=4){						//printf("%x\n",*(unsig)pAINbuf);						write(AudioRecode,(void*)pAINbuf+i,1);					}					m-=n;					//printf("--%d--\n",n);				}				for(i=0; i<n; i+=4){						//printf("%x\n",*(unsig)pAINbuf);						write(AudioRecode,(void*)pAINbuf+i,1);				}						}					#endif		#endif		}		munmap(VU_Stream.srcBuffer,VIDEOBUFSIZE);	munmap(VU_Stream.srcBuffer,APACKCOUNT*AU_Stream.nOutPSize);			//munmap(VBuffer,VIDEOBUFSIZE);	//munmap(ABuffer,AUDIOBUFSIZE);		close(VideoIN);	close(AudioID);		return 0;}

⌨️ 快捷键说明

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