This is cnv.c in view mode; [Download] [Up]
/* cnv.c author : jolly - alias Patrick version : 1.00 additional remark : lines between the defines FROM_Thomas_Funke are added from Thomas Funke - thf@z*.de ADPCM3 support added by kiwi@belly, April '94 */ #import <libc.h> #import <sound/sound.h> #import "precomp.h" void cnv_snd(char *newdir,char *outdir,char *fname) { struct zyxel header; char str[MAXPATHLEN]; char str2[MAXPATHLEN]; FILE *feil,*infd,*outfd; feil=tmpfile(); sprintf(str,"%s/%s%s",newdir,fname,Z_EXT); infd=fopen(str,"r"); if(infd==NULL) log("cnv_snd: no infile %s", str); else { sprintf(str2,"%s/conv.snd",outdir); outfd=fopen(str2,"w+"); if(outfd==NULL) log("cnv_snd: error opening outfile %s",str2); else { fread(&header,sizeof(struct zyxel),1,infd); switch(isZyXEL(&header)) { case ZYX_AD2: ad2(feil,infd);lin96_to_mulaw(feil,outfd);break; case ZYX_AD3: ad3(feil,infd);lin96_to_mulaw(feil,outfd);break; default :return; } fclose(outfd); } fclose(infd); /* The nohup prevents the sndconvert being killed by am's Hangup. Absolute paths are needed because the chdir(PATH) in am.c doesn't affect the CWD of the shell. kiwi@belly NEEDS WORK */ sprintf(str,"nohup sndconvert -o %s/%s/%s.snd -f 1 -s 8012 %s/%s >/dev/console 2>&1 &", PATH,outdir,fname,PATH,str2); #if DEBUG log(str); #endif system(str); } return; } void ad2(FILE *feil,FILE *infd) { u_char buf; short sample[4]; #ifndef __BIG_ENDIAN__ char *little_endian=(char *)sample; #endif do { fread(&buf,1,1,infd); if(buf==DLE) { fread(&buf,1,1,infd); if(buf!=DLE) fread(&buf,1,1,infd); } sample[0]=ad2_to_lin16( (buf&0xc0)>>6); sample[1]=ad2_to_lin16( (buf&0x30)>>4); sample[2]=ad2_to_lin16( (buf&0x0c)>>2); sample[3]=ad2_to_lin16( (buf&0x03) ); #ifdef __BIG_ENDIAN__ fwrite(sample,sizeof(short),4,feil); #else fwrite(little_endian+1,sizeof(char),1,feil); fwrite(little_endian+0,sizeof(char),1,feil); fwrite(little_endian+3,sizeof(char),1,feil); fwrite(little_endian+2,sizeof(char),1,feil); fwrite(little_endian+5,sizeof(char),1,feil); fwrite(little_endian+4,sizeof(char),1,feil); fwrite(little_endian+7,sizeof(char),1,feil); fwrite(little_endian+6,sizeof(char),1,feil); #endif } while(!feof(infd)); } /* pos needs to be reset when starting new conversion, so I moved it out of con_ad3 (pos is the byte position relative to start of sample) */ static int pos = 0; void con_ad3(u_char buf, FILE *feil) { static int Pack; static short sample[8]; #ifndef __BIG_ENDIAN__ char *little_endian=(char *)sample; #endif switch(pos) { case 0: sample[0]=ad3_to_lin16((buf&0xe0)>>5) ; /* XXX- ---- */ sample[1]=ad3_to_lin16((buf&0x1c)>>2) ; /* ---X XX-- */ Pack = (buf&0x03)<<1 ; break; case 1: sample[2]=ad3_to_lin16(Pack|((buf&0x80)>>7)) ; sample[3]=ad3_to_lin16((buf&0x70)>>4) ; /* -XXX ---- */ sample[4]=ad3_to_lin16((buf&0x0e)>>1) ; /* ---- XXX- */ Pack = (buf&0x01)<<2 ; break; case 2: sample[5]=ad3_to_lin16(Pack|((buf&0xc0)>>6)) ; sample[6]=ad3_to_lin16((buf&0x38)>>3) ; /* --XX X--- */ sample[7]=ad3_to_lin16(buf&0x07) ; /* ---- -XXX */ #ifdef __BIG_ENDIAN__ fwrite(sample,sizeof(short),8,feil); #else fwrite(little_endian+1,sizeof(char),1,feil); fwrite(little_endian+0,sizeof(char),1,feil); fwrite(little_endian+3,sizeof(char),1,feil); fwrite(little_endian+2,sizeof(char),1,feil); fwrite(little_endian+5,sizeof(char),1,feil); fwrite(little_endian+4,sizeof(char),1,feil); fwrite(little_endian+7,sizeof(char),1,feil); fwrite(little_endian+6,sizeof(char),1,feil); fwrite(little_endian+9,sizeof(char),1,feil); fwrite(little_endian+8,sizeof(char),1,feil); fwrite(little_endian+11,sizeof(char),1,feil); fwrite(little_endian+10,sizeof(char),1,feil); fwrite(little_endian+13,sizeof(char),1,feil); fwrite(little_endian+12,sizeof(char),1,feil); fwrite(little_endian+15,sizeof(char),1,feil); fwrite(little_endian+14,sizeof(char),1,feil); #endif break; }; pos++; if(pos == 3) pos = 0; } void ad3(FILE *feil,FILE *infd) { u_char buf; pos = 0; /* starting at position zero (see con_ad3 for details) */ do { fread(&buf,1,1,infd); if(buf==DLE) { fread(&buf,1,1,infd); if(buf!=DLE) { /* This is a workaround for a bug in rec_message, but since rec_message was fixed, it shouldn't be triggered in future recordings (see DOUBLE_DLE in am.c) kiwi@belly */ fprintf(stderr, "Bug triggered with %x\n",buf); con_ad3(0x10, feil); } } con_ad3(buf, feil); } while(!feof(infd)); } short ad2_to_lin16(u_char c) { static int M[]={0x3800,0x5600}; static int A=0; static int delta=5; static char sign; static char data; sign=c>>1; data=c&1; #define FROM_Thomas_Funke if (!sign) A += delta * data + 0.5 *delta; else A -= delta * data + 0.5 *delta; if (A <= -0x7ffe) A = -0x7ffe; else { if (A >= 0x7ffe) A = 0x7ffe; } delta = M[(int)data] * delta; delta += 0x2000; delta >>= 14; // div 16384 if (delta < 5) delta = 5; #undef FROM_Thomas_Funke return A; } /********************* ADPCM3 conversion was included by kiwi@belly on 31.3.94. The code is based heavily on a program source by ZyXEL Corporation. I just adapted it to fit in here. kiwi@belly **********************/ short ad3_to_lin16(u_char c) { static int M[]={0x399A, 0x3A9F, 0x4D14, 0x6607 }; static int A=0; static int delta=5; static char sign; static char data; int TmpMax ; long t0 ; /******* This part is modified for the Firmware > 6.10 **************/ t0 = (long)A ; t0 *= 3973 ; t0 += 2048 ; t0 /= 4096 ; A = (int)t0 ; /********************************************************************/ sign=c & 4; data=c & 3; if ( (delta&1) && !sign ) ++A ; /* calculate A */ TmpMax = (delta>>1) ; while ( data-- ) TmpMax += delta ; if ( sign ) A -= TmpMax ; else A += TmpMax ; if (A <= -0x7ffe) A = 0; else { if (A >= 0x7ffe) A = 0; } /* calc new delta */ delta = delta * M[(int)c & 3]; delta += 0x2000; delta >>= 14; // div 16384 if(delta <1) delta=1; return A; } /* */ void lin96_to_mulaw(FILE *feil,FILE *outfd) { int len; SNDSoundStruct snd; short sample[6]; len=ftell(feil); rewind(feil); snd.magic =htonl(SND_MAGIC); snd.dataLocation =htonl(sizeof(SNDSoundStruct)); snd.dataSize =htonl((long)len/sizeof(short)); snd.dataFormat =htonl(SND_FORMAT_LINEAR_16); snd.samplingRate =htonl(9600); snd.channelCount =htonl(1); strcpy(snd.info,"jr"); // yep Jolly Roger ! fwrite(&snd,sizeof(SNDSoundStruct),1,outfd); do { fread(sample,sizeof(short),1,feil); fwrite(sample,sizeof(short),1,outfd ); } while(!feof(feil)); return; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.