📄 files.doc
字号:
There will be cases where there are not header items to save particu- lar analysis conditions or options. This is particularly likely dur- ing experimentation or testing of changes to programs. If it is determined that a new analysis condition or option is significant it will likely be added to the file header in a future release. In the meantime, experimental versions are free to use the spare locations in file headers (documented in [2, Section 5] for each file type), with the understanding that official ESPS releases may invalidate such use. To further support record keeping, all ESPS programs will record the command line that invoked them in the comment field of any generated output file headers, and in the case of conditions or options without corresponding header entries recording the command line will be the record of their use. This convention facilitates record keeping when files are produced by unofficial version of programs with special analysis options. The ESPS library routines get_cmd_line and add_comment (3-ESPS) support this convention. To allow a single file to contain its entire history, headers are recursive structures. This means that an entire file header may be included as an optional header item. The C structure representing the header in memory has fields that can contain pointers to other header structures. 5 . Programming with the ESPS Header Structures This section presents information needed to write programs using the ESPS header structures. 5 .1 . Header Structure Refer to the listing of header.h in reference [1] to help understand this section. Also, see ESPS(5-ESPS). In the following, we assume that the variable "head" is a pointer to an ESPS file header struc- ture. As mentioned above, the header structure contains two portions - the common portion and the type-specific portion. The common por- tion of the header itself contains two structures, common and variable The structure common contains items present in every ESPS data file, regardless of type. This section contains the type code of the header, a check value, identification of the program and its version that created the header, the name of the person who ran that program, the number of data records in the file, whether the data is tagged (meaning each record has a tag that refers to a point in a source file), and the type of the records in the data file. An example (file creation date) is head->common.date. The structure variable contains pointers to source file names, embed- ded source file headers, two text fields (one is the comment field mentioned earlier), the name of a reference file, and two variables that tell the number of source file names and embedded headers. An Version 3.5 ERL 1/22/93 ETM-S-86-13:rap/jtb page 7 example (reference file name) is head->variable.refer. The variable portion also contains so-called "generic" header items, which are used by programs to store arbitrary information not included in the standard header. This facility means that the basic design of an ESPS file type does not have to anticipate every application. For example, the SD file type does not make provision for storing in the file header the average rate of zero crossings, but a program that needs to can do so by means of a generic header item. If such an item was created and called "zero_crossing", a pointer to the stored value is given by get_genhd("zero_crossing", ih) The type-specific portion of the header is provided by a union hd that contains pointers to each possible type-specific structure. They are declared in a union so that additional pointers can be added in the future without affecting existing data files (since the size of the pointers themselves are the same). Programmers can tell which of these pointers to use by checking the item head->common.type. The pointer names are given in the following table: _____________________________________________ |Value_of_common.type___Pointer_in_hd_to_use_| |FT_SD hd.sd | |FT_SPEC hd.spec | |FT_FILT hd.filt | |FT_SCBK hd.scbk | |FT_FEA hd.fea | |____________________________________________| For example, the sampling frequency from the header of an (old-style) SD file is head->hd.sd->sf. 5 .1 .1 . NIST (Sphere) Headers ESPS programs can read sample data files containing the NIST Shpere header (such as found on the TIMIT CD-ROM database). This is imple- mented by having the ESPS file header access routines, detect an input file containing a NIST header and build an ESPS FEA_SD header from it. All header information in the NIST header is saved as generic header items in the ESPS header. Version 3.5 ERL 1/22/93 ETM-S-86-13:rap/jtb page 8 5 .1 .2 . Foreign Headers It is often desirable to maintain an existing file header even if a file is converted to ESPS. The non-ESPS header is called a foreign header and it can be stored in the file between the ESPS header and the first data record. Foreign headers are kept in the ESPS header in the following manner: The generic header item foreign_hd_length contains the size (in bytes) of the foreign header. If this item is present (and non-zero), read_header() will read this many additional bytes of data, put it into the header, and set an additional generic header item foreign_hd_ptr to point to it. From that point on, the foreign header is just part of the ESPS header. With this mechanism, it is possible to write programs that use the ESPS header and record I/O functions while still having access to the foreign header. The procedure is simple: use read_header() to read the ESPS header, and get_genhd() to get the pointer to the foreign header. The conversion programs btosps and addfeahd would usually be used to create such files. See reference [7]. 5 .2 . Header Access Routines There are several ESPS library routines that support access to the ESPS data file headers. These are described in detail in Section 3 of [1]. Declarations for all these functions are found in <esps/header.h>; the programmer need not declare them if this file is included. The read_header routine attempts to read a file header from a stream (the fd parameter is typically one from a "fopen" call). If an I/O error occurs read_header returns NULL. If the file does not begin with a valid ESPS header, then read_header will determine if the file begins with a NIST header. If a NIST header is present, then a FEA_SD header is generated and filled in with the appropriate values from the NIST header (sample rate, minimum and maximum sample values, data type, etc). Read_header then returns a pointer to this FEA_SD header in the usual way. Programs which called read_header on a NIST file will operate normally and not know that the file wasn't initially a normal ESPS file. If neither a valid ESPS header, or a NIST header in present, then read_header will check for the unix environment variable DEF_HEADER. If it is defined and points to a file containg a valid ESPS header, then that header is used instead. If all of the above attempts to find a header fail, then NULL is returned. Memory for the file header is allocated from dynamic memory. After read_header returns, the program should consult common.type to determine the type of the header that has been returned. The write_header routine attempts to write a file header onto a stream. It computes and fills in values for hsize, fixsiz, check, Version 3.5 ERL 1/22/93 ETM-S-86-13:rap/jtb page 9 date, and hdvers and ensures that must-be-zero fields contain zero, by clearing them. If an I/O error occurs, write_header writes an error message and the program bombs. The new_header routine allocates a new header from dynamic memory and returns a pointer to it. Which type-specific header is allocated depends on the value of the argument type. If type is zero, then no type-specific header is allocated, only the common part is. This case is intended for use by the header access programs. The copy_header routine accepts a pointer to a file header and returns a copy of the same type in which all items except common.comment, common.prog, common.vers, common.date, common.progdate, and common.hdvers are copied from the source header. This routine par- tially generates a header for an output file, given a header for an input file (any changed parameters must be filled in, along with the program name and version). It is important to realize that this func- tion can only be used when the output file is of the same type as the input file. The add_source_file routine inserts a source file name and header into the next available positions in a header. The nnames and nheads fields are incremented. Strictly speaking, only pointers are copied, so the source parameters must not be altered before write_header is called. The add_comment routine appends a character string onto the comment field of a header. For example, with the help of get_cmd_line (3-ESPS), the command line is added as a comment. All ESPS programs by convention add the command line as a comment in the output header. For creating zfunc structures, the function new_zfunc is supplied. It allocates dynamic memory, builds a new zfunc structure, and returns a pointer to it. The zeros and poles are also copied to dynamic memory. To assist in storing zfuncs as generic header items the functions add_genzfunc and get_genzfunc are provided. Generic header items are added to an existing header by the add_genhd_X (3-ESPS) routines ("X" stands for one of six possible data types). Other generic-related header access routines are genhd_list, which returns a list of the defined generic header items, genhd_type, which returns the type of a specific generic header item, and get_genhd, which returns a pointer to a specific generic header item. These routines make it possible for programs to process the generic header items in ESPS files without having to know what they are in advance. 5 .2 .1 . Using the Header Access Routines The header access routines are easy to use. The important thing to remember is that, before write_header is called, all values must be set in the header. The easiest error is to confuse pointers that might be in use pointing to several different headers, most often the input and the output file. The basic model of use is to open the Version 3.5 ERL 1/22/93
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -