📄 wtaudioplay.c
字号:
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(¤ttime ,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 + -