📄 foo1
字号:
struct ana_data *p; struct header *ih; . . . ifile = fopen(in_file,"r"); /* open the file */ ih = read_header(ifile); /* read the header */ if (ih->common.type != FT_SPEC) bomb();/* must be an ANA file */ p = allo_ana_rec(ih); /* allocate the record */ if (!get_ana_rec(p,ih,ifile) eof(); /* read record */ nfreq = p->n_frqs; /* get number of frequencies*/ Version 3.4 ERL 9/11/91 ETM-S-86-13:rap/jtb page 12 The pointer p could be used in subsequent calls to _g_e_t__a_n_a__r_e_c pro- vided that the program deals with only one record at a time. If more than one record is needed at the same time within the program, addi- tional pointers must be declared and additional space must be allo- cated by calls to _a_l_l_o__a_n_a__r_e_c. In the case of the built in file types, the type of the data (_e._g. float, integer, etc.) is fixed and defined by the file format itself. The header access routine _w_r_i_t_e__h_e_a_d_e_r automatically sets the type fields in the common part of the header to their correct values (which depend on various other fields in the header). The type codes might be set by code like this (this is done within _w_r_i_t_e__h_e_a_d_e_r - most ESPS programmers will never have to do anything like this): struct header *h; { . . . /* the tag doesn't count here */ h->common.ndouble = 0; h->common.nfloat = 3 * val1 + 2; h->common.nlong = 0; h->common.short = 1; h->common.nchar = 0; } The actual code in the library has additional logic to insure that it is being used properly. There is one case where the type code fields are not set properly by _w_r_i_t_e__h_e_a_d_e_r - old style SD files. Since SD files can have data records of different types (unlike other current file types, in which the types in records are pre-defined), the user has specify what type of SD record is wanted. This is done by means of the function _s_e_t__s_d__t_y_p_e, which must be called before writing any data to the file and before calling _w_r_i_t_e__h_e_a_d_e_r. SD files are exceptional in one other respect, namely that the "get" and "put" routines come in several flavors. Recognizing that programmers will sometimes want to read or write SD records to or from short, float, and double arrays, different routines are provided to support these cases. For example, the routine _p_u_t__s_d__r_e_c_f will write SD records from a program array of type float. Note that the type of SD record (i.e., the type that will be stored in the SD file) does not matter here. Provided that there has been a previous call to _s_e_t__s_d__t_y_p_e, the right conversion will be performed on output. The new FEA_SD file type, which is intended to replace SD files, also allows separate specification of the data type stored in the file and the data type in memory (see _i_n_i_t__f_e_a_s_d__h_d and _a_l_l_o__f_e_a_s_d__r_e_c_s). As mentioned above, FEA files provide a mechanism to define their own record structure. That is, users can determine the number, types, sizes, and names of the items stored in FEA records. FEA files include special support for labelling the records with pointers to Version 3.4 ERL 9/11/91 ETM-S-86-13:rap/jtb page 13 other source files. The (3-ESPS) functions that deal with FEA files are: _a_l_l_o__f_e_a__r_e_c, _a_d_d__f_e_a__f_l_d, _f_e_a__d_e_c_o_d_e, _f_e_a__e_n_c_o_d_e, _g_e_t__f_e_a__p_t_r, _g_e_t__f_e_a__r_e_c, _p_r_i_n_t__f_e_a__r_e_c, and _p_u_t__f_e_a__r_e_c. For a detailed introduc- tion to FEA files, see [5]. 6 .2 . Using _e_o_p_e_n Many ESPS programs go through a sequence of getting a command-line file name, checking to see if it is a "-" (for standard input or out- put), opening the file, and checking to see that is an ESPS file type of the proper type (and proper subtype for FEA files). Here's an example with a FEA_ANA file: /* * open the input file */ if (optind < argc) { in_fea = argv[optind++]; if (strcmp (in_fea, "-") == 0) in_fea = "<stdin>"; else TRYOPEN (argv[0], in_fea, "r", infea_strm); } else { Fprintf(stderr, "no input file specified.0); SYNTAX; } /* * check for FEA_ANA ESPS file */ if ((fea_ih = read_header(infea_strm)) == NULL) ERROR_EXIT("couldn't read input FEA file header"); if(fea_ih->common.type != FT_FEA) ERROR_EXIT("Input file is not a FEA file"); if(fea_ih->hd.fea->fea_type != FEA_ANA) ERROR_EXIT("Input file is not FEA_ANA type"); /* * allocate a record; input a record, and process */ anafea_rec = allo_anafea_rec(fea_ih); (void) get_anafea_rec(anafea_rec, fea_ih, infea_strm); if (*(short *)get_genhd("spec_rep", fea_ih) != RC) ERROR_EXIT("FEA_ANA file does not have reflection coefficients"); rc0 = anafea_rec->spec_param[0]; /*get first reflection coefficient*/ Often, code like the above can be simplified by using _e_o_p_e_n, as fol- lows: if (optind < argc) in_fea = eopen(ProgName, argv[optind++], "r", FT_FEA, FEA_ANA, &fea_ih, &infea_strm); else { Fprintf(stderr, "no input file specified.0); Version 3.4 ERL 9/11/91 ETM-S-86-13:rap/jtb page 14 SYNTAX; } /* note that standard input is allowed, so we don't need to check in_fea * * allocate a record; input a record, and process */ anafea_rec = allo_anafea_rec(fea_ih); (void) get_anafea_rec(anafea_rec, fea_ih, infea_strm); if (*(short *)get_genhd("spec_rep", fea_ih) != RC) ERROR_EXIT("FEA_ANA file does not have reflection coefficients"); rc0 = anafea_rec->spec_param[0]; /*get first reflection coefficient*/ 6 .3 . Reading Data Files with Generic Programs Before FEA files were introduced, a different mechanism was available to allow so-called "generic" (also called "dumb") programs to operate on ESPS data files without knowing the details of the file format. We shall describe that mechanism here, but users should avoid using it as it will be phased out in later releases. An example of such a "dumb" generic program is _s_t_a_t_s (1-ESPS). This program computes certain statistics on records in a data file, without knowledge of the particular data structure. Clearly, in order to sup- port this class of programs sufficient information must be available in the file header. To provide that information, the common part of the header contains the number of doubles, floats, longs, shorts, and characters that comprise a record within the file. Moreover, the data in each record is stored in the order listed - i.e., the given number of doubles followed by the given number of floats, etc. These items are set automatically by _w_r_i_t_e__h_e_a_d_e_r when the ESPS file is created (except in the case of SD files, where a call to _s_e_t__s_d__t_y_p_e is also needed), and they can be used by generic programs to properly read a record. To simplify this further, the library function _g_e_t__g_e_n__r_e_c_d is provided to read an arbitrary ESPS record into an vector of dou- bles. A short example of reading records from a data file in a non- type specific manner is: FILE *ifile; struct header *ih; double tag; double dbuf[100]; . . . ifile = fopen(in_file,"r"); ih = read_header(ifile); if (get_gen_recd(dubf, &tag, ih, ifile) == EOF) done(); a = dbuf[2]; /* access an element */ Programmers and users sometimes need to know the correspondence between this generic view of an ESPS record and the type-specific view provided by the C structures such as this one for PIT files (see _P_I_T (5-ESPS)): Version 3.4 ERL 9/11/91 ETM-S-86-13:rap/jtb page 15 struct pitch { long tag; /*position in the reference file*/ float pulse_dist; /*pulse to pulse distance*/ float raw_pulse_dist; /*raw pulse distance*/ } For example, a user of a generic statistics program might want to get statistics on the pulse_dist component of pitch records, and to do so must be able to state which element of the record this is from the viewpoint of generic programs. This information is provided in the section "RECORD ELEMENT FILE STRUCTURE" within each Section 5 ESPS manual page. Thus, for example, by reading _S_C_B_K (5-ESPS) you can determine that the final_dist component of SCBK records is the element number 1 from the generic viewpoint. In the case of FEA files, the correspondence between the FEA-specific view and the generic view is more complicated since a single such table will not suffice, and for this reason an ESPS program is provided to translate between the two views; see _e_l_e_m_f_e_a (1-ESPS). 7 . The Preamble - Reading ESPS Files with non-ESPS Programs Each ESPS header contains a fixed size structure which we call the preamble. The preamble contains information necessary for the opera- tion of the _r_e_a_d__h_e_a_d_e_r function and will not be described in detail here. However, the preamble does contain information that allows a non-ESPS program to skip over an ESPS header to access the data directly. Note that this can also be achieved by the user level pro- gram _b_h_d. The assumption here, is that the user needs to incorporate into an existing non-ESPS program to ability to read an ESPS file. From the view point of a non-ESPS program, the preamble is the first 8 long words (32 bytes) of the file. The preamble is always written in the Entropic EDR format (see reference [8]), so on a machine with a different default byte order the user program will have to byte swap the data. EDR format has the same byte order as Sun workstations, so if your machine's order if different, you will have to convert it. This is the preamble: struct preamble { long machine_code; /* machine which wrote file, see header.h */ long check_code; /* version check code */ long data_offset; /* data offset (in bytes, from 0) in file */ long record_size; /* record size in bytes */ long check; /* ESPS magic number, same as main header */ long edr; /* YES if EDR_ESPS, NO if native */ long align_pad_size; /* alignment pad need for some SD files */ long foreign_hd; /* pointer to foreign header, -1 if */ /* there is none */ }; The third long word contains the offset from the beginning of the file to the first data record (in bytes). So to skip over the ESPS Version 3.4 ERL 9/11/91 ETM-S-86-13:rap/jtb page 16 header, simply seek to this location in the file. The next long word, contains the record size in bytes. For a better detailing of the record format use the program _f_e_a__e_l_e_m_e_n_t(1-ESPS) or _g_e_n__e_l_e_m_e_n_t(1-ESPS). All a non-ESPS need do to read an ESPS file, is to declare this struc- ture, read in the first part of the file into it and then seek into the file to the point indicated by _d_a_t_a__o_f_f_s_e_t. If the machine on which you are reading this file has a different byte order from EDR, the you will have to byte swap these fields after reading them. The field _e_d_r in the preamble tells you whether you have to worry about the data format of the data records, with respect to byte order and floating point format. If _e_d_r is 1, then the data is in EDR format. This is the most common data format in the workstation market. If your machine's data formats are different than that of a Sun, then you will have to convert the data. If the _e_d_r flag is 0, then the file is in the native format of the machine which wrote it. You will have to determine that machine type (look at _m_a_c_h_i_n_e__c_o_d_e) and convert from that format to that of the destination machine. In most cases there is nothing to do, but some cases can be difficult. It is possible that you can ensure that the ESPS file is written in the easiest for- mat for you to deal with by your non-ESPS program. See reference [8] for details on this. If _f_o_r_e_i_g_n__h_d in the preamble is not -1, then the file contains a foreign header and this is a pointer to it. Please note that this is not the normal way for ESPS programs to access the foreign header. That would be via the generic item _f_o_r_e_i_g_n__h_d__p_t_r and _f_o_r_e_i_g_n__h_d__l_e_n_g_t_h. The foreign header pointer in the preamble is provided just for the case of non-ESPS program access. (end) Version 3.4 ERL 9/11/91
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -