/*-------------- Telecommunications & Signal Processing Lab --------------- McGill University Routine: AFILE *AFgetBLpar (FILE *fp, const char Fname[], long int *Nsamp, long int *Nchan, float *Sfreq, FILE *fpout) Purpose: Get file format information from an SPPACK file Description: This routine reads the header for an SPPACK file. The header information is used to set the file data format information in the audio file pointer structure and to set the returned argument values. A banner identifying the file and its parameters is printed. SPPACK sampled data file: Offset Length Type Contents 0 160 char Text strings (2 * 80) 160 80 char Command line 240 2 int Domain 242 2 int Frame size 244 4 float Sampling frequency 252 2 int File identifier 254 2 int Data type 256 2 int Resolution 258 2 int Companding 272 240 char Text strings (3 * 80) 512 ... -- Audio data 8-bit mu-law, 8-bit A-law, and 16-bit integer data formats are supported. Parameters: <- AFILE *AFgetBLpar Audio file pointer for the audio file -> FILE *fp File pointer for the file -> const char Fname[] File name <- long int *Nsamp Total number of samples in the file (all channels) <- long int *Nchan Number of channels <- float *Sfreq Sampling frequency from the file header -> FILE *fpout File pointer for printing the audio file identification information. If fpout is NULL, no information is printed. Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.21 $ $Date: 1996/08/14 17:55:36 $ -------------------------------------------------------------------------*/ static char rcsid [] = "$Id: AFgetBLpar.c 1.21 1996/08/14 AFsp-V2R1 $"; #include #include #include #include #include #include #define RHEAD_S(fp,offs,string) \ AFreadHead (fp, (long int) (offs), (void *) (string), \ 1, sizeof (string), DS_NATIVE) #define RHEAD_V(fp,offs,value,swap) \ AFreadHead (fp, (long int) (offs), (void *) &(value), \ sizeof (value), 1, swap) #define SAME_CSTR(str,ref) (memcmp (str, ref, sizeof (ref) - (size_t) 1) \ == 0) #define LHEAD 512 #define FM_SPPACK "\100\303" /* Magic value in file byte order */ #define S_SAMPLEDDATA ((uint2_t) 0xfc0e) /* sampled data file */ enum { C_UNIFORM = 1, /* uniform */ C_ALAW = 2, /* A-law companding */ C_MULAW = 3 /* mu-law companding */ }; enum { D_TIME = 1, /* time domain */ D_FREQ = 2, /* frequency domain */ D_QUEFR = 3 /* quefrency domain */ }; struct SPPACK_head { /* char text1[80]; */ /* char text2[80]; */ /* char cline[80]; */ uint2_t Domain; /* Domain */ /* uint2_t FrameSize; */ float4_t Sfreq; /* Sampling frequency */ /* uint2_t fill[2]; */ char Magic[2]; /* File magic */ uint2_t Dtype; /* Data type */ uint2_t Resolution; /* Resolution in bits */ uint2_t Compand; /* Companding flag */ /* char text3[80]; */ /* char text4[80]; */ /* char text5[80]; */ }; AFILE * AFgetBLpar (fp, Fname, Nsamp, Nchan, Sfreq, fpout) FILE *fp; const char Fname[]; long int *Nsamp; long int *Nchan; float *Sfreq; FILE *fpout; { struct SPPACK_head Fhead; AFILE *AFp; int Lw, Format; long int Nbytes, Nsampx, offs, Ldata; /* Get the size of the file */ Nbytes = FLfileSize (fp); if (Nbytes < LHEAD) UThalt ("AFgetBLpar: SPPACK file header too short"); /* Read the header parameters */ offs = 240L; /* skip header strings */ offs += RHEAD_V (fp, offs, Fhead.Domain, DS_EB); offs += 2; /* skip FrameSize */ offs += RHEAD_V (fp, offs, Fhead.Sfreq, DS_EB); offs += 4; /* skip two fill values */ offs += RHEAD_S (fp, offs, Fhead.Magic); offs += RHEAD_V (fp, offs, Fhead.Dtype, DS_EB); offs += RHEAD_V (fp, offs, Fhead.Resolution, DS_EB); offs += RHEAD_V (fp, offs, Fhead.Compand, DS_EB); if (! SAME_CSTR (Fhead.Magic, FM_SPPACK)) UThalt ("AFgetBLpar: Invalid SPPACK file identifier"); /* Set up the data format parameters */ if (Fhead.Dtype == S_SAMPLEDDATA) { switch (Fhead.Compand) { case C_MULAW: if (Fhead.Resolution != 8) UThalt ("AFgetBLpar: Invalid mu-law word length"); Lw = FDL_MULAW8; Format = FD_MULAW8; break; case C_ALAW: if (Fhead.Resolution != 8) UThalt ("AFgetBLpar: Invalid A-law word length"); Lw = FDL_ALAW8; Format = FD_ALAW8; break; case C_UNIFORM: if (Fhead.Resolution != 16) UThalt ("AFgetBLpar: Unsupported SPPACK data word length"); Lw = FDL_INT16; Format = FD_INT16; break; default: UThalt ("AFgetBLpar: Unsupported SPPACK companding option"); } } else UThalt ("AFgetBLpar: Unsupported SPPACK data format"); Ldata = Nbytes - LHEAD; /* Error check */ if (Fhead.Domain != D_TIME) UThalt ("AFgetBLpar - Unsupported SPPACK domain value"); /* Set the parameters for file access */ Nsampx = Ldata / Lw; AFp = AFsetAFp (fp, FO_RO, FT_SPPACK, Format, DS_EB, 1.0, 1L, (long int) LHEAD, Ldata, Nsampx); /* Check and print the header information */ AFprintAFh (AFp, Fname, "", Fhead.Sfreq, fpout); /* Set the return parameters */ *Nsamp = Nsampx; *Nchan = 1L; *Sfreq = Fhead.Sfreq; return AFp; }