📄 hwave.c
字号:
/* Note this is a special case of the NeXt SNDSoundStruct header */typedef struct { /* SUNAU8 format header */ int32 magic; /* magic number 0x2e736e64 */ int32 dataLocation; /* offset to start of data */ int32 dataSize; /* number of bytes of data */ int32 dataFormat; /* format code */ int32 sampRate; /* sample rate code */ int32 numChan; /* number of channels */ char info[4]; } SunAU8Header;/* GetSUNAU8HeaderInfo: get header for SUN 8bit mulaw sound file */static long GetSUNAU8HeaderInfo(FILE *f, Wave w, InputAction *ia){ int n; Boolean bSwap; SunAU8Header hdr; n = sizeof(SunAU8Header); if (fread(&hdr,1,n,f) != n){ HRError(6250,"GetSunAU8HeaderInfo: Cannot read SunAU8 format header"); return -1; } if ((bSwap = MustSwap(UNKNOWNSO))) { /* User might know byte order */ SwapInt32(&hdr.magic); SwapInt32(&hdr.dataLocation); SwapInt32(&hdr.dataSize); SwapInt32(&hdr.dataFormat); SwapInt32(&hdr.sampRate); SwapInt32(&hdr.numChan); } if (hdr.magic != 0x2e736e64 || hdr.dataFormat != 1 /* 8 bit mulaw */ || hdr.numChan != 1 /* mono */ ){ HRError(6251,"GetSUNAU8HeaderInfo: Bad Numbers in SUNAU8 format header"); return -1; } w->nSamples = hdr.dataSize; w->sampPeriod = 1248; /* 8012.821 Hz codec input rate */ w->hdrSize = hdr.dataLocation; ConsumeHeader(f,n,w->hdrSize); *ia = (InputAction) (*ia | DoCVT); /* convert 8bit mulaw to 16bit linear */ return w->nSamples; /* data size = 2 * file size */}/* ConvertSUNAU8Data: convert 8bit MU law to 16 bit linear */static ReturnStatus ConvertSUNAU8Data(Wave w){ unsigned char *src, ulawbyte; short *tgt; static int exp_lut[8]={0,132,396,924,1980,4092,8316,16764}; int i, sign, exponent, mantissa, sample; /* Convert data */ src = ((unsigned char *) w->data) + w->nSamples-1; tgt = ((short *) w->data) + w->nSamples-1; for (i=1; i<=w->nSamples; i++,src--,tgt--) { ulawbyte = ~(*src); sign = (ulawbyte & 0x80); exponent = (ulawbyte >> 4) & 0x07; mantissa = ulawbyte & 0x0F; sample = exp_lut[exponent] + (mantissa << (exponent+3)); *tgt = (sign != 0) ? -sample : sample; } return(SUCCESS);}/* ---------------------- AIFF Format Interface Routines --------------------- */typedef struct { /* skeleton chunk record */ int32 id; /* must be 'FORM' */ int32 size; /* size of rest of chunk */ int32 formType; /* must be 'AIFF' */} FormChunk;typedef struct { int32 id; int32 size; short numChannels;} CommonChunk1;typedef struct { unsigned int nSamples; short sampSize; /* extended sampRate; Apples non-standard fp format!! */ } CommonChunk2; /* GetAIFFHeaderInfo: get AIFF format header */static long GetAIFFHeaderInfo(FILE *f, Wave w, InputAction *ia){ FormChunk fchunk; int fn = sizeof fchunk; long sndStart = 0; /* start of sound chunk */ long fPtr; CommonChunk1 ch1, commchunk1; CommonChunk2 ch2, commchunk2; int cn1 = 10; /* sizeof(long) + sizeof(long) + sizeof(short); */ int cn2 = 6; /* sizeof(long) + sizeof(short); */ Boolean hasCC=FALSE, hasSC=FALSE; const long fcid = 0x464f524d; /* 'FORM' */ const long ccid = 0x434f4d4d; /* 'COMM' */ const long scid = 0x53534e44; /* 'SSND' */ if (w->isPipe){ HRError(6201,"GetAIFFHeaderInfo: cannot pipe an AIFF file"); return -1; } *ia = (InputAction) 0; if (MustSwap(SUNSO)){ HRError(6201,"GetAIFFHeaderInfo: Cannot byte swap AIFF format"); return -1; } rewind(f); if (fread(&fchunk, 1, fn, f) != fn){ HRError(6250,"GetAIFFHeaderInfo: Cannot read AIFF form chunk"); return -1; } if (fchunk.id != fcid){ HRError(6251,"GetAIFFHeaderInfo: Not an AIFF file!"); return -1; } fPtr = 12; while (!(hasCC && hasSC)) { if (fseek(f,fPtr,SEEK_SET) != 0){ HRError(6220,"GetAIFFHeaderInfo: Seek error searching for AIFF chunks"); return -1; } if ((fread(&ch1, 1, cn1, f) != cn1) || (fread(&ch2, 1, cn2, f)!= cn2)){ HRError(6251,"GetAIFFHeaderInfo: Cannot read AIFF common chunk"); return -1; } if (ch1.id == ccid){ /* common chunk found */ hasCC=TRUE; commchunk1=ch1;commchunk2=ch2; } if (ch1.id == scid){ /* sound chunk found */ hasSC=TRUE; sndStart=fPtr; } fPtr += ch1.size + 8; } w->nSamples = commchunk2.nSamples; w->sampPeriod = 625; /* fudge to avoid decoding Apples 10 byte floating point format - assume 16 kHz */ w->hdrSize = sndStart+16; return w->nSamples * 2;}/* --------------------- WAV Format Interface Routines --------------------- *//* GetWAVHeaderInfo: get header for Microsoft WAVE format sound file */static long GetWAVHeaderInfo(FILE *f, Wave w, InputAction *ia){ char magic[4]; int32 len,lng,numBytes; char c; short sht,sampSize,type,chans; if (MustSwap(VAXSO)) *ia = (InputAction) (*ia | DoBSWAP); fread(magic, 4, 1, f); if (strncmp("RIFF", magic, 4)){ HRError(6251,"Input file is not in RIFF format"); return -1; } fread(&lng, 4, 1, f); fread(magic, 4, 1, f); if (strncmp("WAVE", magic, 4)){ HRError(6251,"Input file is not in WAVE format"); return -1; } /* Look for "fmt " before end of file */ while(1) { if (feof(f)){ HRError(6251,"No data portion in WAVE file"); return -1; } fread(magic, 4, 1, f); fread(&len, 4, 1, f); if (*ia & DoBSWAP) SwapInt32(&len); /* Check for data chunk */ if (strncmp("data", magic, 4)==0) break; if (strncmp("fmt ", magic, 4)==0) { fread(&type, 2, 1, f); if (*ia & DoBSWAP) SwapShort(&type); if (type != WAVE_FORMAT_PCM && type!=WAVE_FORMAT_MULAW && type!=WAVE_FORMAT_ALAW){ HRError(6251,"Only standard PCM, mu-law & a-law supported"); return -1; } if(type==WAVE_FORMAT_MULAW) *ia = (InputAction) (*ia | (DoMULAW|DoCVT)); else if(type==WAVE_FORMAT_ALAW) *ia = (InputAction) (*ia | (DoALAW|DoCVT)); fread(&chans, 2, 1, f); /* Number of Channels */ if (*ia & DoBSWAP) SwapShort(&chans); if (chans!=1 && chans!=2){ HRError(6251,"Neither mono nor stereo!"); return -1; } if(chans==2) *ia = (InputAction) (*ia | (DoSTEREO|DoCVT)); fread(&lng, 4, 1, f); /* Sample Rate */ if (*ia & DoBSWAP) SwapInt32(&lng); w->sampPeriod = 1.0E7 / (float)lng; fread(&lng, 4, 1, f); /* Average bytes/second */ fread(&sht, 2, 1, f); /* Block align */ fread(&sampSize, 2, 1, f); /* Data size */ if (*ia & DoBSWAP) SwapShort(&sampSize); if (sampSize != 16 && sampSize!=8){ HRError(6251,"Only 8/16 bit audio supported"); return -1; } if((type==WAVE_FORMAT_MULAW||type==WAVE_FORMAT_ALAW) && sampSize!=8){ HRError(6251,"Only 8-bit mu-law/a-law supported"); return -1; } if(type==WAVE_FORMAT_PCM && sampSize==8) *ia = (InputAction) (*ia | (Do8_16|DoCVT)); len -= 16; } /* Skip chunk */ for (; len>0; len--) fread(&c,1,1,f); } numBytes=len; w->nSamples = numBytes / (sampSize/8); /*If stereo: w->nSamples is the stereo value; changed in convertWAV*/ return numBytes;}/* ConvertWAVData*/ ReturnStatus ConvertWAVData(Wave w, InputAction *ia){ unsigned char *srcc; short *tgt,*srcs; int i,sample,lchan,rchan; char smode[MAXSTRLEN]; enum {imLeft,imRight,imSum} mode; if(*ia&DoMULAW){ srcc = ((unsigned char *) w->data) + w->nSamples-1; tgt = ((short *) w->data) + w->nSamples-1; for (i=1; i<=w->nSamples; i++,srcc--,tgt--) { *tgt = NISTmutab[*srcc]; } *ia = (InputAction) (*ia & (~DoBSWAP)); /* Must not byte-swap now */ } if(*ia&DoALAW){ srcc = ((unsigned char *) w->data) + w->nSamples-1; tgt = ((short *) w->data) + w->nSamples-1; for (i=1; i<=w->nSamples; i++,srcc--,tgt--) { *tgt = a2l[*srcc]; } *ia = (InputAction) (*ia & (~DoBSWAP)); /* Must not byte-swap now */ } if(*ia&Do8_16){ srcc = ((unsigned char *) w->data) + w->nSamples-1; tgt = ((short *) w->data) + w->nSamples-1; for (i=1; i<=w->nSamples; i++,srcc--,tgt--) { *tgt = (*srcc * 256)-32768; } *ia = (InputAction) (*ia & (~DoBSWAP)); } if(*ia&DoSTEREO){ w->nSamples/=2;/*Final mono number*/ mode = imSum; if (GetConfStr(cParm,numParm,"STEREOMODE",smode)){ if (strcmp(smode,"LEFT") == 0) mode = imLeft; else if (strcmp(smode,"RIGHT") == 0) mode = imRight; } srcs = (short *) w->data; tgt = w->data; for (i=1; i<=w->nSamples; i++,tgt++) { lchan = *srcs++; rchan = *srcs++; switch(mode){ case imLeft: sample = lchan; break; case imRight: sample = rchan; break; case imSum: sample = (lchan+rchan)/2; break; } *tgt = sample; } } return(SUCCESS);}/*variable to hold fieldlist of an ESIG input file */static FieldList ESIGFieldList; /* EXPORT->StoreESIGFieldList: store the field list of an ESIG input file */void StoreESIGFieldList(HFieldList fList){ ESIGFieldList = fList;}/* EXPORT->RetrieveESIGFieldList: store the field list of an ESIG input file */void RetrieveESIGFieldList(HFieldList *fList){ *fList = ESIGFieldList ;}/* EXPORT->ReadEsignalHeader: Get header from Esignal file; return FALSE in case of failure. */Boolean ReadEsignalHeader(FILE *f, long *nSamp, long *sampP, short *sampS, short *kind, Boolean *bSwap, long *hdrS, Boolean isPipe){ FieldList list, list1; FieldSpec *field; char *version; int inarch = UNKNOWN; /* format variant in input */ long pre_size = -9999; /* arbitrary invalid value for * uninitialized variable */ long hdr_size = -9999; long rec_size = -9999; if (!(list = ReadHeader(&version, &inarch, &pre_size, &hdr_size, &rec_size, f))) { HError(6250,"ReadEsignalHeader: cannot read Esignal Header"); return FALSE; } StoreESIGFieldList(list); if ((field=FindField(list, "parmKind"))) *kind = Str2ParmKind ((char *) field->data); else { list1 = FieldOrder(list); /* obtain list with record fields only */ if (list1 == NULL || list1[0] == NULL) { HError(6252, "ReadEsignalHeader: " "no record fields defined in Esignal file"); return FALSE; } if (list1[1] != NULL) { HError(6252, "ReadEsignalHeader: " "extraneous field or missing item parmKind in Esignal file"); return FALSE; } field = list1[0]; if (field->occurrence != REQUIRED) { HError(6251, "ReadEsignalHeader: " "field %s in Esignal file is OPTIONAL; should be REQUIRED", field->name); return FALSE; } if (FieldLength(field) != 1) { HError(6251, "ReadEsignalHeader: " "field %s in Esignal file has length %ld; 1 expected", field->name, FieldLength(field)); return FALSE; } *kind = WAVEFORM; } if ((field=FindField(list, "recordFreq"))) *sampP = (long) (1.0E7/((double*)field->data)[0]); else { HError(6252, "ReadEsignalHeader: item recordFreq missing from Esignal file"); return FALSE; } *sampS=rec_size; if(isPipe) *nSamp=INT_MAX; else *nSamp=NumberBytes(f, hdr_size, isPipe)/rec_size; *hdrS = hdr_size; switch (inarch) { case EDR1: /* fall through */ case EDR2: *bSwap = vaxOrder; break; case NATIVE: *bSwap = FALSE; break; case ASCII: HError(6251, "ReadEsignalHeader: " "Esignal ASCII format not supported"); return FALSE; default: HError(6251, "ReadEsignalHeader: " "unrecognized architecture type in Esignal file"); return FALSE; } return TRUE;}/* GetESIGHeaderInfo: get header info and check format is 1 2-byte item per record */static long GetESIGHeaderInfo(FILE *f, Wave w, InputAction *ia){ int nsamp; long nSamp, sampP; short sampSize, kind; long hdrS; Boolean bSwap; if (!ReadEsignalHeader(f, &nSamp, &sampP, &sampSize, &kind, &bSwap, &hdrS, w->isPipe)) HError(6250,"GetESIGHeaderInfo: cannot read Esignal Header"); if (kind != WAVEFORM) HError(6251,"GetESIGHeaderInfo: sample kind is not WAVEFORM"); if (sampSize != 2) HError(6251,"GetESIGHeaderInfo: samples are not shorts"); w->sampPeriod = sampP; w->hdrSize = hdrS; w->nSamples = nSamp; /*Will be INT_MAX if pipe*/ if (bSwap) *ia = (InputAction) (*ia | DoBSWAP); if(w->isPipe){ if (!GetConfInt(cParm,numParm,"NSAMPLES",&nsamp)){ HRError(6230,"GetESIGHeaderInfo: NSAMPLES not set in config"); return -1; } w->nSamples = nsamp; } return w->nSamples*2;}/* EXPORT->PutESIGHeader: Write header info to ESIG file f */void PutESIGHeaderInfo(FILE *f, Wave w){ FieldSpec *field, *field1; FieldList inList, outList=NULL; int len, i; /* Create header items first */ field = NewFieldSpec( CHAR, 1 ); field->occurrence=GLOBAL; field->name="commandLine"; field->dim[0]=strlen(RetrieveCommandLine())+1; field->data=malloc(field->dim[0]); strcpy((char *) field->data, RetrieveCommandLine()); AddField( &outList, field );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -