📄 fea.tme
字号:
to allocate the correct amount of memory of each data type..ipana\->fea_rec = fea_rec = allo_fea_rec(hd);.lpThe address of the feature-file record (the.i fea_datastructure) is saved in the FEA_ANA subtype record (the.i anafeastructure).This is so that subtype-specific routinescan simply be passed a pointer to the subtype recordand still have access to the underlying feature-file record.(We have also saved the address in a variable.i fea_recfor convenience of reference.).ppAfter the feature record is allocated,.i get_fea_ptris calledfor a pointer to the memory associated with each particular named field.The return data type of thisfunction is (\fBchar\fP *), and it must be cast to the correct data type.(This is like \fImalloc\fR(3)).For example,.ipana\->raw_power = (\fBfloat *\fR) get_fea_ptr(fea_rec, "raw_power", hd);.lpmakes.i ana\->raw_powerpoint to the storage for the first element of the.i floatarray field named "raw_power", and.ipana\->frame_len = (\fBlong *\fR) get_fea_ptr(fea_rec, "frame_len", hd);.lpmakes.i ana\->frame_lenpoint to the storage for the.i longscalar field named "frame_len".Then you can use statements like.ip.nfana\->lpc_power[i] = new_value;xx = *ana\->frame_len;.fi.lpto set and get values of field elements..ppOne invocation of.i get_fea_ptris needed for each field defined for the subtype.If you fail to use the correct cast,you will get a compile-time error complaining about illegal pointercombinations..ppIf you forget that.i frame_lenis a pointer and say.i ana\->frame_leninstead of.i *ana\->frame_lenin an expression, you will get a funny number which is the address of thedata. In some such cases you will get a message about illegalcombination of pointer and integer or some such, but don't count on it..ppSince \fIget_fea_ptr\fR returns a pointer,you could use its return value directly to access the datainstead of saving the pointer in a structure as we have shown.This probably is not the best way touse the function in general. In particular, you probably don't want toput the function call in a processing loop that gets executed 10,000times. But this does work:.ipsomething = *(\fBlong\fR *) get_fea_ptr(fea_rec, "frame_len", hd) + something_else;.lpSo does this:.ip*(\fBlong\fR *) get_fea_ptr(fea_rec, "frame_len", hd) = 779;.ppThe tag is handled specially, since it's the one fieldthat is directly built in and preallocated in feature file records..ipana\->tag = &fea_rec\->tag;.lp.i ana\->tagis a pointer containing the address of.i fea_rec\->tag,so to say.i *ana\->tagis to refer to the same memory as.i fea_rec\->tag.You can access the tag as.i *ana\->tag,but if you do not want to access itthrough a pointer, you can just use it directly from thefeature file record. .ppThe function.i allo_anafea_recallocates a feature-file record for the FEA file subtype FEA_ANA.It allocates a structure and assigns to the pointers in it theaddresses of the data in the feature-file record.The function uses a macro.i GETPTRto simplify writing several invocations of.i get_fea_ptrThe feature-file header must be set up before this function is called..ip.nf#\fBdefine\fP GETPTR(member,type,field) \\ {fana\->member = (type *) get_fea_ptr(fea_rec, field, hd);}\fBstruct\fR anafea *allo_anafea_rec(hd) \fBstruct\fR header hd;{ \fBstruct\fR anafea *fana = (\fBstruct\fR anafea *) calloc(1, \fBsizeof\fR *ana); \fBstruct\fR fea_data *fea_rec = allo_fea_rec(hd); /* check to be sure this is the right kind of file */ \fBif\fR(hd\->common.type != \fB\s-1FT_FEA\fR\s+1) error("Not a feature file"); \fBif\fR(hd\->hd.fea\->fea_type != \fB\s-1FEA_ANA\fR\s+1) error("Not a FEA_ANA file"); /* hook the pointers in the ana record up to the data area in the * feature file record */ fana\->tag = &fea_rec\->tag; GETPTR(raw_power, \fBfloat\fP, "raw_power") GETPTR(lpc_power, \fBfloat\fP, "lpc_power") GETPTR(p_pulse_len, \fBfloat\fP, "p_pulse_len") GETPTR(ref_coeff, \fBfloat\fP, "ref_coeff") GETPTR(frame_len, \fBlong\fP, "frame_len") /* save the pointer to the feature file record in the ana record */ fana\->fea_rec = fea_rec; \fBreturn\fR fana;}.fi.sh 1 "Reading and Writing Records".ppIn addition to a header-initialization routineand a record-allocation function,a support module for a new file type typically includesget/put record functions that do the record input/output..ppIn most cases the get/put functions simply read or write a feature filerecord. Since the subtype record consists of pointers to the datarecord memory there is no moving of data required. In some cases,however, it might be desirable to move the data into a different type ofdata structure. For example, you might want to represent the data inthe program as a matrix (this could also be done just by setting up anarray of pointers, but in some cases it might be just as well to movethe data). In such cases, the get/put routines would be where thismovement of the data is done..ppWe continue to use our example from above where we implement the FEA_ANA filetype as a feature file and show the required support modules..sh 2 "put_anafea_rec".ppThis routine writes a record of the FEA file subtype FEA_ANA. In thisexample, it does nothing more than write the feature-file record. Insome other cases, it might have to do some transformation of the data(for example to support a matrix data structure)..ip.nf\fBvoid\fRput_anafea_rec(rec, hd, strm) \fBstruct\fR anafea *rec; \fBstruct\fR header *hd; \fB\s-1FILE\s+1\fR *strm;{ \fBif\fR (hd\->common.type != \fB\s-1FT_FEA\fR\s+1) error("Not a feature file"); \fBif\fR (hd\->hd.fea\->fea_type != \fB\s-1FEA_ANA\fR\s+1) error("Not a FEA_ANA file"); put_fea_rec(rec\->fea_rec, hd, strm);}.fi.sh 2 "get_anafea_rec".ppThis routine reads a record of the FEA file subtype FEA_ANA. Like the putfunction above, it does nothing more than get the feature file record.It returns 1 on successbecause all other ESPS \fIget_record\fR functions return EOFon end of file or a positive non-zero integer if the record is readcorrectly..ip.nf\fBint\fRget_anafea_rec(rec, hd, strm) \fBstruct\fR anafea *rec; \fBstruct\fR header *hd; \s-1\fBFILE\s+1\fR *strm;{ \fBif\fR (hd\->common.type != \fB\s-1FT_FEA\fR\s+1) error("Not a feature file"); \fBif\fR (hd\->hd.fea\->fea_type != \fB\s-1FEA_ANA\fR\s+1) error("Not a FEA_ANA file"); \fBif\fR (get_fea_rec(rec\->fea_rec, hd, strm) == \fB\s-1EOF\fR\s+1) return \fB\s-1EOF\fR\s+1; \fBreturn\fR (1);}.fi.sh 1 "Other Parts of the Support Module".ppIn addition to these routines the support module should containdefinitions for any global variables needed by the feature file subtype.The most common examples of required global variables are string arraysused to define possible values for coded or enumerated data fields inthe record. See \fIlin_search\fR(3\-ESPS)..ppFor a more complete (and more complex) example of a feature file subtypesupport routine see.i vqsupport.cin the ESPS library source directory.The most significant difference between.i vqsupport.cand the example here that oneof the items in the data structure is a two-dimensional array, so thedata is moved between the feature file record and the.i vqrecord.This could have been doneby setting up an array of pointers with the correct values.The function.i marg_index (3-ESPSu)is intended for that purpose;see its manual page for an example of its use.But since.i vqfiles do not have many records it did not seemnecessary at the time. Of course, it could be changed withoutaffecting existing programs. The other difference between.i vqsupport.cand this example is that it is complete and does compile and execute..sh 1 "Extension of Predefined Feature-File Subtypes".ppSometimes an application arisesfor which a predefined feature-file subtype is suitableexcept that a little extra information needs to be recorded in each record.Rather than define an entire new subtypethat differs only slightly from the existing subtype,you can use the support functions for the existing subtype unchangedand just use auxiliary functions to take care of the additional fields.If just a single additional field is needed,the basic feature-file facilities may be enough..ppSuppose for example that a FEA_ANA file with an additional scalar field.i comb_cm_lagof type.i floatis called for.(The name is taken from an actual application.)To create a header, you can just call.i add_fea_fldafter using.i init_anafea_hd:.ip.nfhd = new_header(\fB\s-1FT_FEA\fR\s+1);\fBif\fP (init_anafea_hd(hd, maxraw, maxlpc, maxpulses, order_vcd, order_unvcd) != 0) error("error filling FEA_ANA header");\fBif\fP (add_fea_fld("comb_cm_lag", 1L, 0, (\fBlong\fR *) \fB\s-1NULL, FLOAT\fR\s+1, (\fBchar\fR **) \fB\s-1NULL\fR\s+1, hd) == \-1) error("error adding auxiliary field");.fi.lpAfter creating or reading such a header,you can allocate a data record as usual:.ip.nfana = allo_anafea_rec(hd);.fi.lpthis creates space for the new field as well as the predefined fields.The latter are accessed as usual through the pointers in the.i anafeastructure:.ip.nf*ana\->frame_len = some_length;.fi.lpThe new field is accessed through a pointer obtained from.i get_fea_ptr:.ip.nfcomb_cm_lag_p = (\fBfloat\fR *) get_fea_ptr(ana\->fea_rec, "comb_cm_lag", hd); /* . . . */old_val = *comb_cm_lag_p;*comb_cm_lag_p = new_val;.fi.lpFinally, nothing new is needed for reading or writing the record:.ip.nfget_anafea_rec(ana, hd, istrm);.fi.lpwill read a record, including the new field, from an input file.i istrm,and.ip.nfput_anafea_rec(ana, hd, ostrm);.fi.lpwill write the record, including the new field, to an output file.i ostrm..ppIf several new fields are needed, it may be worthwhileto define an auxiliary data structure and support functions.For example, suppose these fields are required:.TScenter, box, tab(;);c | c | c | c l | l | l | l.Name;Size;Rank;Type=cm_lag;\fIn_rows\fR;1;NULL;float;NULLcomb_cm_lag;1;0;NULL;float;NULLposteriors;\fIn_vclas\fR;1;NULL;float;NULL.TE.ppA support function parallel to.i init_anafea_hdwill take care of defining the new fields..ip.nf#\fBdefine\fP ADDFLD(name, size, rank, dimen, type, enums) \\ {\fBif\fP (add_fea_fld((name), (\fBlong\fP)(size), (rank), (\fBlong\fP*)(dimen), \\ type, (\fBchar\fP**)(enums), hd) == \-1) \fBreturn\fP 1;}\fBint\fPinit_auxana_hd(hd, n_rows, n_vclas) \fBstruct\fP header *hd; /* FEA file header */ \fBint\fP n_rows; /* number of elements of cm_lag */ \fBint\fP n_vclas /* number of elements of posteriors */{ \fBint\fP i; *add_genhd_l("n_rows", (\fBlong\fP *) \fB\s-1NULL\fR\s+1, 1, hd) = n_rows; *add_genhd_l("n_vclas", (\fBlong\fP *) \fB\s-1NULL\fR\s+1, 1, hd) = n_vclas; ADDFLD("cm_lag", n_rows, 1, \fB\s-1NULL, FLOAT, NULL\fR\s+1) ADDFLD("comb_cm_lag", 1, 0, \fB\s-1NULL, FLOAT, NULL\fR\s+1) ADDFLD("posteriors", n_vclas, 1, \fB\s-1NULL, FLOAT, NULL\fR\s+1) \fBreturn\fP 0;}.fi.lpThis is called along with.i init_anafea_hdwhen a new header is created:.ip.nfhd = new_header(\fB\s-1FT_FEA\fR\s+1);\fBif\fP (init_anafea_hd(hd, maxr, maxl, maxp, o_vcd, o_unv) != 0) error("error filling FEA_ANA header");\fBif\fP (init_auxana_hd(hd, n_rows, n_vclas) != 0) error("error adding auxiliary fields");.fi.lpFor record access, define a pointer structure.ip.nf\fBstruct\fP auxana{ \fBfloat\fP *cm_lag; /* vector */ \fBfloat\fP *comb_cm_lag; /* scalar */ \fBfloat\fP *posteriors; /* vector */};.fi.lpThis can be put in a private include file.For each.i anafeastructure, the program should have a corresponding.i auxanastructure:.ip.nf\fBstruct\fR anafea *ana;\fBstruct\fR auxana *aux;.fi.lpThe structure is allocated and the pointer values filled inby a support function parallel to.i allo_anafea_rec:.ip.nf#\fBdefine\fP GETPTR(member, type, field) \\ {aux_rec\->member = (type *) get_fea_ptr(fea_rec, field, hd);}\fBstruct\fP auxana *allo_auxana_rec(hd, rec) \fBstruct\fP header *hd; \fBstruct\fP anafea *rec;{ \fBint\fP i; \fBstruct\fP auxana *aux_rec; \fBstruct\fP fea_data *fea_rec; aux_rec = (\fBstruct\fP auxana *) calloc(1, sizeof(\fBstruct\fP auxana)); fea_rec = rec\->fea_rec; GETPTR(cm_lag, \fBfloat\fP, "cm_lag") GETPTR(comb_cm_lag, \fBfloat\fP, "comb_cm_lag") GETPTR(posteriors, \fBfloat\fP, "posteriors") \fBreturn\fP aux_rec;}.fi.lpThis is called after each invocation of.i allo_anafea_rec:.ip.nfana = allo_anafea_rec(hd);aux = allo_auxana_rec(hd, ana);.fi.lpThen the predefined fields are accessed as usual through the.i anafeastructure, as before,and the new fields are accessed through the.i auxanastructure:.ip.nfold_val = *aux\->comb_cm_lag;*aux\->comb_cm_lag = new_val;.fi.pp.sh 1 "Documentation for Official Feature File Subtypes".ppThis section describesthe standard documentation format for an official feature file subtype.The feature file header has a field for a type code to allow for thedefinition of new file types implemented with feature files. When thisis done, the new file type must be documented so that other programmerscan properly design programs that must use these files..ppThe format of the documentation for these files is nearly the same asthe existing section 5 manual pages for files types such as SD. Theinformation that a programmer must have to use a feature fileincludes:.(lfile type code,generic header items and their meaning,listing of the fields in the feature file and their size information,the data structure of the record if one is appropriate, andmanual pages for supporting functions as appropriate..)l.ppIn most cases when a new file type is implemented using feature files,the designer should provide a data structure like our FEA_ANA example abovefor other programmers to use.This will go into an include filethat will be installed in the ESPS include-file directory.This header file should also includedeclarations for any support functions for the new file type. See\fI<esps/vq.h>\fR for an example of this..ppWhen a feature file subtype is to be made official, the designer willsubmit the following to the ESPS maintainer:.(lsection 5 manual page,section 3 manual pages for support functions,support functions as described above in a C module \fIxx\fPsupport.c, andinclude file <esps/\fIxx\fP.h> with structure declarations,.)lwhere \fIxx\fP is a name for the subtype..ppThe ESPS maintainer will assign the file type a type code (FEA_\fIxx\fR)and add this to the others in \fI<esps/fea.h>\fR.The file.i ftypes.cin the ESPS library source directory contains the definition of an array.i fea_file_typeof strings that associates each type code with its name;for example.ip.nffea_file_type[\fB\s-1FEA_ANA\fR\s+1] == "FEA_ANA".fi.lpThe ESPS maintainer will update the definition of.i fea_file_typewhen the new type code is assigned.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -