📄 header.c
字号:
/* * This material contains unpublished, proprietary software of * Entropic Research Laboratory, Inc. Any reproduction, distribution, * or publication of this work must be authorized in writing by Entropic * Research Laboratory, Inc., and must bear the notice: * * "Copyright (c) 1987-1990 AT&T, Inc. * "Copyright (c) 1986-1990 Entropic Speech, Inc. * "Copyright (c) 1990-1997 Entropic Research Laboratory, Inc. * All rights reserved" * * The copyright notice above does not evidence any actual or intended * publication of this source code. * * Written by: David Talkin * Checked by: * Revised by: David Talkin, Rod Johnson, John Shore, Alan Parker * * Brief description: Create, accesss, read, and write file headers. */static char *sccs_id = "@(#)header.c 1.59 1/18/97 ATT/ESI/ERL";#include <stdio.h>#include <esps/esps.h>#include <esps/fea.h>#include <esps/feaspec.h>#include <sys/types.h>#include <unistd.h>#include <Objects.h>#ifdef OS5#include <sys/fcntl.h>#endif#if !defined(OS5) && !defined(hpux) && !defined(IBM_RS6000) && !defined(SG) && !defined(DEC_ALPHA) && !defined(LINUX)char *sprintf();#endifchar *savestring(), *read_all_types();short get_rec_len();int fea_sd_special = 0; /* global flag indicates whether * single-channel, non-complex, * FEA_SD files should be read in as * shorts and treated as traditional * waves SD (extra fields ignored); * if this flag is not set, a FEA_SD * file will be treated like any * other FEA file (set automatically * if board present) */extern int debug_level;#ifndef NULL#define NULL 0#endifSelector head_a23 = {"burst", "%hd", NULL, NULL}, head_a22 = {"ph_bound", "%hd", NULL, &head_a23}, head_a21 = {"end_time", "%lf", NULL, &head_a22}, head_a20 = {"lpc_order", "%d", NULL, &head_a21}, head_a19 = {"window_size", "%d", NULL, &head_a20}, head_a18 = {"window_step", "%d", NULL, &head_a19}, head_a17b = {"remark", "#astr", NULL, &head_a18}, head_a17 = {"comment", "#cstr", NULL, &head_a17b}, head_a16b = {"text", "#astr", NULL, &head_a17}, head_a16 = {"title", "#cstr", NULL, &head_a16b}, head_a15 = {"start_time", "%lf", NULL, &head_a16}, head_a14 = {"type_name", "%s", NULL, &head_a15}, head_a13 = {"type_code", "%x", NULL, &head_a14}, head_a12 = {"frequency", "%lf", NULL, &head_a13}, head_a11 = {"bandwidth", "%lf", NULL, &head_a12}, head_a10 = {"duration", "%lf", NULL, &head_a11}, head_a9 = {"samples", "%d", NULL, &head_a10}, head_a8 = {"segments", "%d", NULL, &head_a9}, head_a7 = {"dimensions", "%d", NULL, &head_a8}, head_a6 = {"maximum", "%lf", NULL, &head_a7}, head_a5 = {"minimum", "%lf", NULL, &head_a6}, head_a4 = {"version", "%d", NULL, &head_a5}, head_a3b = {"operation", "#astr", NULL, &head_a4}, head_a3 = {"operator", "#cstr", NULL, &head_a3b}, head_a2b = {"time", "#astr", NULL, &head_a3}, head_a2 = {"date", "#cstr", NULL, &head_a2b}, head_a1 = {"description", "#string", NULL, &head_a2}, head_a0 = {"identifiers", "#list", NULL, &head_a1};/* * This list determines which signal attributes from the Signal structure are * printed in the header on output. The attributes will be printed in the * order of this table. */static Selector *active_header_entries[] = { &head_a4, &head_a2b, &head_a13, &head_a12, &head_a9, &head_a15, &head_a21, &head_a11, &head_a7, &head_a6, &head_a5, &head_a0};#define N_HEADER_ENTRIES (sizeof(active_header_entries)/sizeof(Selector*))typedef struct meth_key { char *key; int (*proc) ();} Meth_key;int shortpr(), intpr(), longpr(), floatpr(), doublepr(), charpr(), astrpr(), cstrpr(), qstrpr(), strpr(), shexpr(), lhexpr(), loctpr(), listpr(), stringpr(), soctpr();Meth_key var_types[] = { "%d", longpr, "%d", intpr, "%f", floatpr, "%lf", doublepr, "%c", charpr, "%s", strpr, "%hx", shexpr, "%x", lhexpr, "%ho", soctpr, "%o", loctpr, "%hd", shortpr, "#list", listpr, "#str", strpr, "#string", stringpr, "#cstr", cstrpr, "#astr", astrpr, "#strq", qstrpr, "#qstr", qstrpr, "the_end", NULL};typedef struct sppack { char comment1[80]; char comment2[80]; char command[80]; short domain; short framelength; float frequency; short aux1; short aux2; short magic; short type; short module[128];} Sppack;char *get_date();static char scratch[200];/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */intsignal_magic(){ int i; strncpy((char *) (&i), "SIG\n", 4); return (i);}/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *//* * Allocate and initialize a new header large enough for n+1 bytes (data + * possible null terminator). The internal header structure is described in * Objects.h The external form of the header (in a file) consists of a simple * char array. The first four bytes are ascii for SIG<newline>; the next * eight are 7 ascii decimal numerals (or leading blanks) for the header size * and a <newline>. Thus, the header may be meaningfully read entirely as an * ascii string. */Header *w_new_header(n) int n;{ Header *h; char *c; if (debug_level >= 1) printf("w_new_header: function entered, n = %d.\n", n); if ((h = (Header *) malloc(sizeof(Header)))) { if (n) { if (!(c = malloc(n + 1))) { printf("Can't allocate a header structure in w_new_header()\n"); return (NULL); } h->nbytes = n; h->header = c; } else { h->nbytes = 0; h->header = NULL; } h->magic = SIGNAL_MAGIC; h->npad = 0; h->esps_hdr = NULL; h->esps_nbytes = 0; h->e_scrsd = 0; h->e_short = 0; h->strm = NULL; h->esps_clean = 0; return (h); } printf("Can't allocate a header structure in w_new_header()\n"); return (NULL);}/***********************************************************************//* * Put arbitrary keyword-format-value triples in a header. The format must * be exactly one of the types specified above in the "var_types" list. If * the keyword appears in the "head_a0" list, the format is implied and will * not be printed in the header. */#define STR_ALLOC 500head_printfx(head, key, format, value) Header *head; char *key, *format, *value;{ Selector sl; int n; if (!(n = head_printf(head, key, value))) { static char *str = NULL; static int strsize; if (!str) { if (!(str = malloc(STR_ALLOC + 1))) { printf("Can't allocate scratch space in head_printfx()\n"); return 0; } strsize = STR_ALLOC; } sl.name = key; sl.format = format; if (*format == '#') sl.dest = (char *) (&value); else sl.dest = value; if ((n = arg_to_stringx(&str, &strsize, &sl))) head_append(head, str, n); } return (n);}/***********************************************************************//* * Retrieve arbitrary data from the header by its keyword. If the keyword * appears in the "head_a0" list, the corresponding format is used to read * the data. Otherwise IT IS ASSUMED THAT A FORMAT SPECIFICATION IMMEDIATELY * FOLLOWS THE NON-STANDARD KEYWORD IN THE HEADER. THIS WILL BE TRUE IF * head_printfx() WAS USED TO INSTALL THE NON-STANDARD INFORMATION. Returns 1 * on success, 0 on failure. NOTE: When head_scanf() is called to retrieve a * standard C type, dest should be a pointer to the variable to be assigned. * When it is called to retrieve #string, #cstr, #astr, or #list types, dest * must be a pointer to a pointer to the free()-able variable structure (or * NULL) so that new structures can be allocated as needed to accommodate the * (variable size) input data. */head_scanf(head, key, dest) Header *head; char *key, *dest;{ Selector *sl, *slt, s; int its_in_list = FALSE; sl = &head_a0; while (sl) { if (!strcmp(sl->name, key)) { sl->dest = dest; its_in_list = TRUE; slt = sl; } else sl->dest = NULL; sl = sl->next; } if (its_in_list) return (get_header_args(head->header, &head_a0)); else { s.name = key; s.format = NULL; /* this will be retrieved from the header */ s.dest = dest; s.next = &head_a0; return (get_header_args(head->header, &s)); }}/***********************************************************************//* * Scans the null-terminated character array, alist, for keywords present in * the Selector list adscr (like head_a0). If keywords are encountered, the * associated value is decoded from alist and assigned to the variable * pointed to by the "dest" element of the Selector. Keywords may occur in * any order and may be repeated any number of times in alist. The value * corresponding to the last occurrence of the keyword is retained. * Get_header_args() returns the number of assignments performed. */get_header_args(alist, adscr) register char *alist; Selector *adscr;{ return (scan_header(alist, adscr, (char *) NULL, (char *) NULL));}/***********************************************************************//* * Given a Header, h, and a keyword, key, return a pointer to a string * specifying the data type of key's argument. */char *get_keyword_format(h, key) Header *h; char *key;{ static char type[10]; Selector *sl; sl = &head_a0; while (sl) { if (!strcmp(sl->name, key)) return (sl->format); sl->dest = NULL; /* to disable assignments for what may follow */ sl = sl->next; } *type = 0; scan_header(h->header, &head_a0, key, type); if (*type) return (type); return (NULL);}/***********************************************************************//* * Return a pointer to the value corresponding to the keyword, key, most * recently entered in the header, h. The format specification for the value * will be copied into type. Returns NULL on errors. */char *get_header_item(h, key, type) Header *h; char *key, *type;{ char *tp; static double dr; static int ir; static char cr, str[500], *stringr = NULL; static short sr; static float fr; static List *lpr = NULL; if ((tp = (char *) get_keyword_format(h, key))) { strcpy(type, tp); switch (*type) { case '%': /* it is a standard C type */ if (!(strcmp(type, "%d") && strcmp(type, "%o") && strcmp(type, "%x"))) { head_scanf(h, key, (char *) &ir); return ((char *) &ir); } if (!(strcmp(type, "%hd") && strcmp(type, "%ho") && strcmp(type, "%hx"))) { head_scanf(h, key, (char *) &sr); return ((char *) &sr); } if (!strcmp(type, "%lf")) { head_scanf(h, key, (char *) &dr); return ((char *) &dr); } if (!strcmp(type, "%f")) { head_scanf(h, key, (char *) &fr); return ((char *) &fr); } if (!strcmp(type, "%c")) { head_scanf(h, key, &cr); return (&cr); } if (!strcmp(type, "%s")) { head_scanf(h, key, str); return (str); } case '#': if (strcmp(type, "#list")) { head_scanf(h, key, (char *) &lpr); return ((char *) lpr); } if (strcmp(type, "#string")) { head_scanf(h, key, (char *) &stringr); return (stringr); } if (strcmp(type, "#cstr")) { head_scanf(h, key, (char *) &stringr); return (stringr); } if (strcmp(type, "#astr")) { head_scanf(h, key, &stringr); return (stringr); } default: break; } } return (NULL);}/***********************************************************************//* * If called with NULL pointers for key and type, see get_header_args(). If * key is a keyword and type points to a character array, scan_header() also * places the format specification for key in type (see get_keyword_type()). */scan_header(alist, adscr, key, type) register char *alist, *key, *type; Selector *adscr;{ int gotsome = 0, gotone; char name[32], junk[200], *get_next_item(); Selector *ad; if (alist && *alist && adscr) { while ((*alist == ' ') || (*alist == '\t') || (*alist == '\n')) alist++; /* skip initial blanks and blank lines */ while (*alist) { strnscan(alist, name, sizeof(name)); if (!*(alist = get_next_item(alist))) { printf("No argument for selector %s\n", name); return (gotsome); } ad = adscr; gotone = 0; while (ad) { if (!strcmp(name, ad->name)) { if (ad->format) { alist = read_all_types(alist, ad->format, ad->dest); if (key && !strcmp(name, key)) strcpy(type, ad->format); } else { /* format should be in header... */ sscanf(alist, "%s", junk); alist = get_next_item(alist); if ((*junk != '%') && (*junk != '#')) { printf("Free-format keyword %s without format spec.; %s ignored\n", name, junk); break; } alist = read_all_types(alist, junk, ad->dest); if (key && !strcmp(name, key)) strcpy(type, junk); } if (ad->dest) gotsome++; /* if an assignment was made */ gotone = 1; break; } else ad = ad->next; } if (!gotone) { strnscan(alist, junk, sizeof(junk)); if ((*junk == '%') || (*junk == '#')) { /* looks like a format * spec. */ if (key && !strcmp(name, key)) strcpy(type, junk); alist = get_next_item(alist); /* skip the non-standard item */ alist = read_all_types(alist, junk, NULL); } else { /* punt */ printf("Unknown selector %s; argument %s ignored\n", name, junk); alist = get_next_item(alist); } } } } return (gotsome);}/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */voidchcopy(out, in, n) register char *out, *in; register int n;{ for (; n-- > 0;) *out++ = *in++;}/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *//* Return a header structure which is an identical copy of header h. */Header *dup_header(h) Header *h;{ Header *h2; if (debug_level >= 1) printf("dup_header: nbytes = %d.\n", h->nbytes); if (h && (h2 = w_new_header(h->nbytes))) { if (h->nbytes) { chcopy(h2->header, h->header, h->nbytes); h2->header[h->nbytes] = 0; } h2->magic = h->magic; h2->esps_hdr = h->esps_hdr;/* since this contains a pointer to the same esps header do not let it be freed*/ h->esps_clean = 0; h2->esps_clean = 0; h2->esps_nbytes = h->esps_nbytes; h2->strm = h->strm; h2->npad = h->npad; return (h2); } else printf("Error in dup_header\n"); return (NULL);}/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */voidsetup_access(sig) Signal *sig;{ head_a21.dest = (char *) &(sig->end_time); head_a15.dest = (char *) &(sig->start_time); head_a13.dest = (char *) &(sig->type); head_a12.dest = (char *) &(sig->freq); head_a11.dest = (char *) &(sig->band); head_a9.dest = (char *) &(sig->file_size); head_a7.dest = (char *) &(sig->dim); head_a6.dest = (char *) &(sig->smax[0]); head_a5.dest = (char *) &(sig->smin[0]); head_a4.dest = (char *) &(sig->version); head_a0.dest = (char *) &(sig->idents);}/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *//* * Get information from ESPS header and initialize Waves Signal structure * values accordingly. */static int est_file_size();#define BAD_HDR_ITEM(itemname, type) \printf("%s: header item \"%s\" missing or not %s.\n", \"read_esps_hdr", (itemname), (type))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -