📄 wtaudiorecord.c
字号:
337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767};typedef struct adpcm_state{ int index; int valprev;}_ADPCM,*pADPCM;voidadpcm_coder(short *indata, unsigned char *outdata, int len, struct adpcm_state *state){ short *inp; /* Input buffer pointer */ signed char *outp; /* output buffer pointer */ int val; /* Current input sample value */ int sign; /* Current adpcm sign bit */ int delta; /* Current adpcm output value */ int diff; /* Difference between val and valprev */ int step; /* Stepsize */ int valpred; /* Predicted output value */ int vpdiff; /* Current change to valpred */ int index; /* Current step change index */ int outputbuffer; /* place to keep previous 4-bit value */ int bufferstep; /* toggle between outputbuffer/output */ outp = (signed char *)outdata; inp = indata; valpred = state->valprev; index = state->index; step = stepsizeTable[index]; bufferstep = 1; for ( ; len > 0 ; len-- ) { val = *inp++; /* Step 1 - compute difference with previous value */ diff = val - valpred; sign = (diff < 0) ? 8 : 0; if ( sign ) diff = (-diff); /* Step 2 - Divide and clamp */ /* Note: ** This code *approximately* computes: ** delta = diff*4/step; ** vpdiff = (delta+0.5)*step/4; ** but in shift step bits are dropped. The net result of this is ** that even if you have fast mul/div hardware you cannot put it to ** good use since the fixup would be too expensive. */ delta = 0; vpdiff = (step >> 3); if ( diff >= step ) { delta = 4; diff -= step; vpdiff += step; } step >>= 1; if ( diff >= step ) { delta |= 2; diff -= step; vpdiff += step; } step >>= 1; if ( diff >= step ) { delta |= 1; vpdiff += step; } /* Step 3 - Update previous value */ if ( sign ) valpred -= vpdiff; else valpred += vpdiff; /* Step 4 - Clamp previous value to 16 bits */ if ( valpred > 32767 ) valpred = 32767; else if ( valpred < -32768 ) valpred = -32768; /* Step 5 - Assemble value, update index and step values */ delta |= sign; index += indexTable[delta]; if ( index < 0 ) index = 0; if ( index > 88 ) index = 88; step = stepsizeTable[index]; /* Step 6 - Output value */ if ( bufferstep ) { outputbuffer = (delta & 0x0f) ; } else { *outp++ = ((delta << 4) & 0xf0) | outputbuffer; } bufferstep = !bufferstep; } /* Output last step, if needed */ if ( !bufferstep ) *outp++ = outputbuffer; state->valprev = valpred; state->index = index;}voidadpcm_decoder(char *indata, short *outdata,int len, struct adpcm_state* state) { signed char *inp; /* Input buffer pointer */ short *outp; /* output buffer pointer */ 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 */ 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;}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);}/************************************************//* Example too the audio playback*/int main(){ BYTE *pDataIN; //input audio data DWORD *pDataOUT; _ADPCM state; int coding; int nSaveFile; int nr,nw; mySig(myExit); //safe exit state.index = 0; state.valprev = 0; AudioID = open("/dev/WTAUDIO",O_RDWR ); if(AudioID == -1) { printf("Can not open /dev/WTAUDIO .\n"); exit(0); } nSaveFile = open("../audio.raw",O_RDWR |O_CREAT); if(nSaveFile == -1) { printf("Can't creat ../audio.raw\n"); exit(0); } pDataOUT = (DWORD*)malloc(sizeof(int)*508); while(1) {#ifdef AUDIO_RECODE nr = read(AudioID, pDataOUT, sizeof(int)*508); if(nr != 508) printf("read error\n"); nw = write(nSaveFile, pDataOUT, sizeof(int)*508); if(nw != 508) printf("read error\n"); #endif } close(AudioID); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -