📄 hwave.c
字号:
*ia = (InputAction) (*ia | DoBSWAP); return w->nSamples*2;}/* ---------------------- TIMIT Format Interface Routines --------------------- */typedef struct { /* TIMIT File Header */ short hdrSize; short version; short numChannels; short sampRate; int32 nSamples;} TIMIThdr;/* GetTIMITHeaderInfo: get fixed size binary 12 byte TIMIT header */static long GetTIMITHeaderInfo(FILE *f, Wave w, InputAction *ia){ TIMIThdr hdr; int n = sizeof hdr; Boolean bSwap; if ((bSwap = MustSwap(VAXSO))) /* TIMIT is VAX ordered */ *ia = (InputAction) (*ia | DoBSWAP); if (fread(&hdr, 1, n, f) != n){ HRError(6250,"GetTIMITHeaderInfo: Cannot read TIMIT format header"); return -1; } if (bSwap) { SwapShort(&hdr.hdrSize); SwapShort(&hdr.version); SwapShort(&hdr.numChannels); SwapShort(&hdr.sampRate); SwapInt32(&hdr.nSamples); } if (hdr.nSamples < 0 || hdr.sampRate < 0 || hdr.numChannels < 0 || hdr.numChannels > 8 ){ HRError(6251,"GetTIMITHeaderInfo: Bad Numbers in TIMIT format header"); return -1; } w->nSamples = hdr.nSamples; w->sampPeriod = hdr.sampRate*2.5; w->hdrSize = n; return w->nSamples*2;}/* ---------------------- OGI Format Interface Routines --------------------- */typedef struct { /* OGI File Header */ short hdrSize; short version; short numChannels; short sampRate; int32 nSamples; int32 lendian;} OGIhdr; /* GetOGIHeaderInfo: get fixed size binary 16 byte OGI header */static long GetOGIHeaderInfo(FILE *f, Wave w, InputAction *ia){ OGIhdr hdr; int n = sizeof hdr; Boolean bSwap; if((bSwap = MustSwap(SUNSO))) /* OGI is SUN ordered */ *ia = (InputAction) (*ia | DoBSWAP); if (fread(&hdr, 1, n, f) != n){ HRError(6250,"GetOGIHeaderInfo: Cannot read OGI format header"); return -1; } if (bSwap) { SwapShort(&hdr.hdrSize); SwapShort(&hdr.version); SwapShort(&hdr.numChannels); SwapShort(&hdr.sampRate); SwapInt32(&hdr.nSamples); SwapInt32(&hdr.lendian); } if (hdr.nSamples < 0 || hdr.sampRate < 0 || hdr.numChannels < 0 || hdr.numChannels > 8 ){ HRError(6251,"GetOGIHeaderInfo: Bad Numbers in OGI format header"); return -1; } w->nSamples = hdr.nSamples; w->sampPeriod = hdr.sampRate*2.5; w->hdrSize = n; return w->nSamples*2;}/* ---------------------- NIST Format Interface Routines --------------------- */static int cNIST; /* current input char */static int cCount; /* num bytes read */enum _CompressType{ SHORTPACK, /* MIT shortpack-v0 */ SHORTEN, /* CUED Shorten */ IMULAW /* Interleaved 8 bit u-law */};typedef enum _CompressType CompressType;/* GetNISTToken: get next token delimited by white space from f */static char * GetNISTToken(FILE *f,char *buf){ int i=0; while (isspace(cNIST)) { cNIST=fgetc(f); ++cCount; } do { if (cNIST == EOF) HError(6250,"GetNISTToken: Unexpected end of file"); buf[i++] = cNIST; cNIST=fgetc(f); ++cCount; } while(!isspace(cNIST) && i<99); buf[i] = '\0'; return buf;}/* NISTSkipLine: skip to next input line of f */static void NISTSkipLine(FILE *f){ while (cNIST != '\012'){ /* new line is line feed on NIST ROM */ cNIST=fgetc(f); ++cCount; if (cNIST == EOF) HError(6250,"NISTSkipLine: Unexpected end of file"); } cNIST=fgetc(f); ++cCount;}/* GetNISTIVal: get int val from f (indicated by -i) */static int GetNISTIVal(FILE *f){ char buf[100]; if (strcmp(GetNISTToken(f,buf),"-i") != 0) HError(6251,"GetNISTIVal: NIST type indicator -i expected"); return atoi(GetNISTToken(f,buf));}/* GetNISTSVal: get string of lenth n into s (indicated by -sn) */static void GetNISTSVal(FILE *f, char *s){ char buf[100]; GetNISTToken(f,buf); if (buf[0] != '-' || buf[1] != 's') HError(6251,"GetNISTSVal: NIST type indicator -s expected"); GetNISTToken(f,s); if (atoi(buf+2) != strlen(s)) HError(6251,"GetNISTSVal: bad string length");}/* GetNISTHeaderInfo: get the NIST Header info */static long GetNISTHeaderInfo(FILE *f, Wave w, InputAction *ia){ char token[100],*lab,byteFormat[100],sampCoding[100],buf[100]; Boolean interleaved = FALSE; long nS,sR,sS, cC; long dataBytes; cNIST = ' '; cCount = 0; nS=sR=sS=-1; byteFormat[0]='\0'; sampCoding[0]='\0'; lab = GetNISTToken(f,token); /* Check NIST label */ if (strlen(lab)>4) *(lab+4) = '\0'; if (strcmp(lab,"NIST") !=0){ HRError(6251,"GetNISTHeaderInfo: NIST header label missing"); return -1; } NISTSkipLine(f); w->hdrSize = atoi(GetNISTToken(f,token)); /* header #bytes */ NISTSkipLine(f); while (strcmp(GetNISTToken(f,token),"end_head")!=0){ if (strcmp(token,"sample_count") == 0) /* objects */ nS = GetNISTIVal(f); else if (strcmp(token,"sample_rate") == 0) sR = GetNISTIVal(f); else if (strcmp(token,"sample_n_bytes") == 0) sS = GetNISTIVal(f); else if (strcmp(token,"sample_byte_format") == 0) GetNISTSVal(f,byteFormat); else if (strcmp(token,"sample_coding") == 0) GetNISTSVal(f,sampCoding); else if (strcmp(token,"channels_interleaved") == 0){ GetNISTSVal(f,buf); if (strcmp(buf,"TRUE") == 0) interleaved = TRUE; } else if (strcmp (token, "channel_count") == 0) { cC = GetNISTIVal(f); if (cC==2) interleaved = TRUE; else if (cC!=1) HError(6251,"GetNISTHeaderInfo: channel count = %d in NIST header",cC); } NISTSkipLine(f); } if (sS < 1 || sS > 2){ HRError(6251,"GetNISTHeaderInfo: Sample size = %d in NIST header",sS); return -1; } if (nS == -1){ HRError(6252,"GetNISTHeaderInfo: Num samples undefined in NIST header"); return -1; } if (sR == -1){ HRError(6252,"GetNISTHeaderInfo: Sample Rate undefined in NIST header"); return -1; } if (strcmp(byteFormat, "") == 0) { HRError(-6252,"GetNISTHeaderInfo: Byte Format undefined in NIST header"); } if (strcmp(sampCoding,"ulaw")==0) strcpy(sampCoding,"mu-law"); if (interleaved) strcat (sampCoding, "-interleaved"); w->nSamples = nS; w->sampPeriod = 1.0E7 / (float)sR; dataBytes = w->nSamples * 2; /* Fix for bug in original WSJ0 shortpack headers */ if (strcmp(byteFormat,"shortpack-v0") == 0) { strcpy(sampCoding,byteFormat); strcpy(byteFormat,"01"); } /* standard 16 bit linear formats */ if (strlen(sampCoding)==0 || strcmp(sampCoding,"pcm")==0){ if (strcmp(byteFormat,"01") == 0){ if(MustSwap(VAXSO)) *ia = (InputAction) (*ia | DoBSWAP); }else if (strcmp(byteFormat,"10") == 0) if(MustSwap(SUNSO)) *ia = (InputAction) (*ia | DoBSWAP); } /* ShortPack compression format */ else if (DoMatch(sampCoding,"*shortpack*")) { *ia = (InputAction) (*ia | DoSPACK); *ia = (InputAction) (*ia | DoCVT); dataBytes = FileBytes(f, w); } /* Shorten compression format */ else if (DoMatch(sampCoding,"*embedded-shorten*")) { *ia = (InputAction) (*ia | DoSHORT); *ia = (InputAction) (*ia | DoCVT); dataBytes = FileBytes(f, w); } /* Interleaved Mu-Law */ else if (DoMatch(sampCoding,"*mu-law-interleaved*")) { /* w->nSamples /= 2; */ *ia = (InputAction) (*ia | DoMULAW); *ia = (InputAction) (*ia | DoCVT); dataBytes = FileBytes(f, w); } else{ HRError(6251,"GetNISTHeaderInfo: unknown byte format in NIST header"); return -1; } ConsumeHeader(f,cCount,w->hdrSize); return dataBytes;}/* for use in bit-twiddling operations in GetShortPackBlock */static const unsigned char bitValue[8] = {1,2,4,8,16,32,64,128};/* GetShortPackBlock: decode the block of data starting at *inData and store at *outData return number of samples in block and update *inData and *outData. Data format defined by Mike Phillips at MIT */static int GetShortPackBlock(char **inData, short **outData){ char *in; /* dereferenced forms of the arguments */ short *out; unsigned char nSamp, nBits; unsigned char buf = '\0'; int i,k; Boolean negative; int charBits=0; int numChar=0; in = *inData; out = *outData; nSamp = *(in++); /* number of samples in block */ nBits = *(in++); /* number of bits / sample excluding sign bit */ if (nBits > 15) HError(6254,"GetShortPackBlock: Incorrect number of bits/sample"); for (i=0; i<nSamp; i++,out++) { *out = 0; if (charBits == 0) { buf = *(in++); numChar++; } negative = buf & bitValue[7-charBits]; charBits = (charBits+1)%8; k = nBits; while (k > 0) { if (charBits == 0) { buf = *(in++); numChar++; } if (charBits == 0 && k >= 8) { /* do the whole byte at once */ *out |= buf << (k-8); k -= 8; } else if (charBits == 0 && k >= 4) { /* most significant nibble */ *out |= ((buf & '\360') >> 4) << (k-4); k -= 4; charBits = 4; } else if (charBits == 4 && k >= 4) { /* least significant nibble */ *out |= (buf & '\017') << (k-4); k -= 4; charBits = 0; } else { /* do a single bit */ *out |= ((buf & bitValue[7-charBits]) >> (7-charBits)) << (k-1); k--; charBits = (charBits+1)%8; } } if (negative) /* shortpack data is signed binary */ *out=(*out==0)?-32768:-(*out); } if ((numChar%2) != 0) in++; /* MIT code uses shorts to read/write */ *outData = out; *inData = in; return (int)nSamp;}/* DecompressShortPack: decode short packed data into new data array */void DecompressShortPack(Wave w){ short* decomp; /* the decompressed data */ long outSampCount=0; char *inData; short *outData; decomp = (short *)New(w->mem,w->nSamples*2); inData = (char *)w->data; outData = decomp; while (outSampCount < w->nSamples) outSampCount += GetShortPackBlock(&inData, &outData); if (outSampCount != w->nSamples) HError(6254,"DecompressShortPack: Incorrect number of decompressed samples"); w->data = decomp;}/* DecodeIMuLaw: convert interleaved 8bit MU law to 16 bit linear */static void DecodeIMuLaw(Wave w){ unsigned char *src; short *tgt; int i,sample,lchan,rchan; char smode[MAXSTRLEN]; enum {imLeft,imRight,imSum} mode; /* Set Conversion Mode - left channel, right channel or sum */ mode = imSum; if (GetConfStr(cParm,numParm,"STEREOMODE",smode)){ if (strcmp(smode,"LEFT") == 0) mode = imLeft; else if (strcmp(smode,"RIGHT") == 0) mode = imRight; } /* Convert data */ src = (unsigned char *) w->data; tgt = w->data; sample = 0; for (i=1; i<=w->nSamples; i++,tgt++) { lchan = NISTmutab[*src++]; rchan = NISTmutab[*src++]; switch(mode){ case imLeft: sample = lchan; break; case imRight: sample = rchan; break; case imSum: sample = (lchan+rchan)/2; break; } *tgt = sample; }}/* ConvertNISTData: decompress the Wave */ ReturnStatus ConvertNISTData(Wave w, InputAction ia){ if (ia&DoSPACK) DecompressShortPack(w); else if (ia&DoSHORT){ HRError(6201,"ConvertNISTData: NIST Shorten Compression not implemented"); return(FAIL); } else if (ia&DoMULAW) DecodeIMuLaw(w); return(SUCCESS);}/* ---------------------- SDES1 Format Interface Routines --------------------- */typedef struct { /* skeleton SDES1 format header */ short hdrSize; /* should be 1336 */ char fill1[182]; int32 fileSize; /* num samples * 2 */ char fill[832]; int32 sampRate; /* sample rate in Hertz */ int32 sampPeriod; /* sample period in usecs */ short sampSize; /* sample size in bits (16) */} SDes1Header;/* GetSDES1HeaderInfo: get header for Sound Designer 1 format file */static long GetSDES1HeaderInfo(FILE *f, Wave w, InputAction *ia){ SDes1Header hdr; int n = sizeof hdr; Boolean bSwap; if ((bSwap = MustSwap(UNKNOWNSO))) /* User might know byte order */ *ia = (InputAction) (*ia | DoBSWAP); if (fread(&hdr, 1, n, f) != n){ HRError(6250,"GetSDES1HeaderInfo: Cannot read SDES1 format header"); return -1; } if (hdr.hdrSize != 1336){ HRError(6251,"GetSDES1HeaderInfo: Bad HeaderSize in SDES1 format header"); return -1; } if (bSwap) { SwapShort(&hdr.hdrSize); SwapInt32(&hdr.fileSize); SwapInt32(&hdr.sampRate); SwapInt32(&hdr.sampPeriod); SwapShort(&hdr.sampSize); } w->nSamples = hdr.fileSize / 2; w->sampPeriod = 1.0E7 / (float)hdr.sampRate; w->hdrSize = 1336; return w->nSamples*2;}/* ---------------------- SCRIBE Format Interface Routines --------------------- *//* GetSCRIBEHeaderInfo: create a header for a SCRIBE waveform file */static long GetSCRIBEHeaderInfo(FILE *f, Wave w, InputAction *ia){ int nsamp; if (MustSwap(UNKNOWNSO)) /* User might know byte order */ *ia = (InputAction) (*ia | DoBSWAP); w->hdrSize = 0; w->sampPeriod = 0.0; /* User must specify this */ if (!w->isPipe) w->nSamples = FileBytes(f,w) / 2; else{ if (!GetConfInt(cParm,numParm,"NSAMPLES",&nsamp)){ HRError(6230,"GetSCRIBEHeaderInfo: NSAMPLES not set in config"); return -1; } w->nSamples = nsamp; } return w->nSamples*2;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -