⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskread.c

📁 4.8kcelp语音压缩编码程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  ----------------------  DATA FILE READ ROUTINES  -----------------------  *//*  ---------------------  designed and coded by rpc  ----------------------  *//*  ----------------------  Version 1.5   July 1988  -----------------------  *//*  ------------------------------------------------------------------------  *//*   RELEASE NOTES:     Version 1.0:  The original version for the SUNGRAPH signal data inputmodule.     Version 1.1:  Modified the argument list of some routines.  Other changes?     Version 1.2:  Added the auto error reporting feature.  This feature isenabled or disabled via disk_io_erh(flag) which is in its own source file.Also changed dfe[] & ffe[] to DFE & FFE.     Version 1.3:  Added relative positioning to goto_block & goto_sample.Deleted all checking for lseek errors since they can't occur.     Version 1.4:  Increased the amount of text in error reporting and changedit to print on stderr instead of stdout.     Version 1.5:  Made goto_sample, read_variable, goto_block and read_blockreturn the sample or block number to be read next, i.e. the current position.*/#include "diskio.h"#include <stdio.h>#include <strings.h>#include <sys/file.h>#include <sys/types.h>   /*  these two files are included for the call  */#include <sys/stat.h>    /*  to fstat in file length routine            *//*    variable type definitions: * *    TYPE  #  |  C TYPE  |  # of BYTES  |  FORTRAN TYPE *    -------------------------------------------------- *       1     |  short	  |      2       |  integer*2 *       2     |   int	  |      4       |  integer*4 *       3     |  float	  |      4       |    real*4 */static short bytes_in[] = { 2, 4, 4 }; /* number of bytes in the data types */#define NUM_DATA_TYPES sizeof(bytes_in)/sizeof(bytes_in[0]) /* elements in bytes_in */struct file_data {   char filename[MAX_FILENAME_LENG+1];/* file connected to this channel */   int fd;                            /* file descriptor assigned to above */   int format[2+2*MAX_VARS_PER_BLK];  /* the format of the data file */   short open;                        /* channel's status: 0-closed, 1-open */   short ch_type;                     /* channel type */   short v;                           /* variable # read on type 1 channels */   int next;                          /* next sample to read on type 1 chan */                                      /* next block to read on type 2 chan */   short samp_p_blk;                  /* total # of samples/block */   int byte_p_blk;                    /* total # of bytes/block */   int bytes[MAX_VARS_PER_BLK];       /* # of bytes/block for each variable */   short samp_avail;                  /* # of unread samples in current block */   int gap_head;                      /* # of bytes in block before selected variable */   int gap_total;                     /* # of block bytes not in selected variable */   };static struct file_data fd[MAX_CHANNELS];#define PARAM_OK -999struct errs {   char routine[20];               /* name of routine where error was */   char name[MAX_FILENAME_LENG+1]; /* filename or variable name */   int param;                      /* illegal argument of call in error */   };static struct errs ervar = { "", "", PARAM_OK };#define DFE   ".sg_data"#define FFE   ".sg_format"extern int errno;extern short auto_er;      /* flag to enable/disable auto error report & halt */extern long lseek();extern char *strcpy(), *strcat(), *strncat(), *rindex();/*  --------------------  OPEN VARIABLE CHANNEL ROUTINE  -------------------  *//*   DESCRIPTION:     chan_id = open_var_channel ( filename, var_name )     This routine is called to establish a new channel to access the values ofone of the variables in a data file.  "filename" is the name of the file and"var_name" is the name of the variable whose values are to be read.  Thevariable's values are accessed with the read_variable routine.  This functionreturns a channel id  ("chan_id") which is used to identify the opened channelwhen calling other disk read routines.  "filename" can have an extension, butit is not mandatory.If "filename" has an extension:     a) The extension is tested for validity.  (eg. Is it .sg_data or one of        the other types that can be read by these routines?)  Valid extensions        are these:  .sg_data; .spd     b) If the extension is valid, open_var_channel tries to open "filename".        If the extension is not valid, an error is returned.If "filename" does not have an extension:     a) Each valid extension is concatenated with a copy of filename and the        resulting filename is tested for existance.     b) If this file exists, open_var_channel tries to open it.        If none of these files exist, an error is returned.If the file to be opened has the .sg_data extension, the format informationmust reside in a corresponding .sg_format file.Returned value:     If there are no errors, the returned value is a channel id which is used toidentify the open channel when using other disk read routines.  A valid channelid is >= 0.  If an error occurs, the returned value is < 0.The following errors are detected:     - filename is too long     - all channels are open     - there is a format file problem     - the specified variable was not found     - invalid extension in filename     - no data file found     - the data file could not be opened*/open_var_channel ( filename, var_name )char filename[], var_name[];{   int chan_id;   chan_id = open_channel(filename, 1, var_name);   strcpy(ervar.routine, "open_var_channel");   strncpy(ervar.name, filename, MAX_FILENAME_LENG);   if (chan_id == -15)  strncpy(ervar.name, var_name, MAX_FILENAME_LENG);   strcat(ervar.name, "");   if (chan_id < 0 && auto_er) error_exit(chan_id);   return(chan_id);}/*  ---------------------  OPEN BLOCK CHANNEL ROUTINE  ---------------------  *//*   DESCRIPTION:     chan_id = open_block_channel ( filename )     This routine is called to establish a new channel to access the values ofall of the variables in a data file.  The values of the data file variables areaccessed with the read_block routine.  This function returns a channel id("chan_id") which is used to identify the opened channel when calling otherdisk read routines.  "filename" can have an extension, but it is not mandatory.If "filename" has an extension:     a) The extension is tested for validity.  (eg. Is it .sg_data or one of        the other types that can be read by these routines?)  Valid extensions        are these:  .sg_data; .spd     b) If the extension is valid, open_var_channel tries to open "filename".        If the extension is not valid, an error is returned.If "filename" does not have an extension:     a) Each valid extension is concatenated with a copy of filename and the        resulting filename is tested for existance.     b) If this file exists, open_var_channel tries to open it.        If none of these files exist, an error is returned.If the file to be opened has the .sg_data extension, the format informationmust reside in a corresponding .sg_format file.Returned value:     If there are no errors, the returned value is a channel id which is used toidentify the open channel when using other disk read routines.  A valid channelid is >= 0.  If an error occurs, the returned value is < 0.The following errors are detected:     - filename is too long     - all channels are open     - there is a format file problem     - invalid extension in filename     - no data file found     - the data file could not be opened*/open_block_channel ( filename )char filename[];{   int chan_id;   chan_id = open_channel(filename, 2, "");   strcpy(ervar.routine, "open_block_channel");   strncpy(ervar.name, filename, MAX_FILENAME_LENG);   strcat(ervar.name, "");   if (chan_id < 0 && auto_er) error_exit(chan_id);   return(chan_id);}/*  ------------------------  OPEN CHANNEL ROUTINE  ------------------------  *//*   DESCRIPTION:     chan_id = open_channel ( file, chan_type, vname )     This routine is for use only by the disk_read module; it cannot be calledfrom anywhere else.  It does the actual channel opening operations for eachchannel type.  "chan_type" indicates the type of channel being requested.  Twochannel types are currently defined according to the type of access desired:     1 - single variable access     2 - block access (all block variables)"vname" is the name of the variable accessed on type 1 channels.*/static open_channel ( file, chan_type, vname )char file[], vname[];int chan_type;{   int format[2 + 2*MAX_VARS_PER_BLK], var_num, i, temp_fd, chan, file_status;   char filename[MAX_FILENAME_LENG + sizeof(DFE)];   static char varnames[MAX_VARS_PER_BLK][MAX_VARNAME_LENG + 1];   static char *vnames[MAX_VARS_PER_BLK] = {		varnames[ 0], varnames[ 1], varnames[ 2], varnames[ 3],		varnames[ 4], varnames[ 5], varnames[ 6], varnames[ 7],		varnames[ 8], varnames[ 9], varnames[10], varnames[11],		varnames[12], varnames[13], varnames[14], varnames[15],		varnames[16], varnames[17], varnames[18], varnames[19],		varnames[20], varnames[21], varnames[22], varnames[23],		varnames[24], varnames[25], varnames[26], varnames[27],		varnames[28], varnames[29], varnames[30], varnames[31],		varnames[32], varnames[33], varnames[34], varnames[35] };/* *    do the easy error checking: */   if (strlen(file) > MAX_FILENAME_LENG) return(-2);/* *    look for first available channel: */   chan = -1;   for (i=0; i<MAX_CHANNELS; i++)   {      if (fd[i].open == 0)      {         chan = i;         break;      }   }   if (chan == -1) return(-14);/* *    read format file: */   if (read_format( file, format, vnames ) < 0)  return(-12);/* *    if type 1 channel, find the variable number from the variable name: */   var_num = 0;   if (chan_type==1)   {      for (i=0; i<format[1]; i++)      {         if (strcmp(vname, vnames[i]) == 0)         {            var_num = i+1;            break;         }      }      if (var_num == 0) return(-15);   }/* *    check for filename extension options and open the data file: */   file_status = test_filename(file, filename, 1);   if (file_status == -2) return(-10);  /* invalid extension */   if (file_status == -1) return(-16);  /* no data file found */   if( (temp_fd = open(filename, O_RDONLY)) == -1)  /* couldn't open */   {      perror("The system call error in disk read is");      return(-13);   }/* *    write the data file structure variables: */   fd[chan].open = 1;   strcpy( fd[chan].filename, file );   for (i=0; i < 2*format[1]+2; i++) fd[chan].format[i] = format[i];   fd[chan].fd = temp_fd;   fd[chan].ch_type = chan_type;   fd[chan].v = var_num;   fd[chan].next = 1;   fd[chan].samp_p_blk = 0;   fd[chan].byte_p_blk = 0;   for (i=1; i<=format[1]; i++)   {      fd[chan].samp_p_blk += format[2*i+1];      fd[chan].byte_p_blk += bytes_in[format[2*i] -1] * format[2*i+1];      fd[chan].bytes[i-1]  = bytes_in[format[2*i] -1] * format[2*i+1];   }   fd[chan].gap_head = 0;   fd[chan].gap_total = 0;   if (chan_type == 1 && format[1] > 1)  /*  the general case  */   {      fd[chan].samp_avail = format[2*var_num + 1];      fd[chan].gap_total = fd[chan].byte_p_blk              - bytes_in[format[2*var_num] -1] * format[2*var_num + 1];      for (i=1; i<var_num; i++)            fd[chan].gap_head += bytes_in[format[2*i] -1] * format[2*i+1];      lseek(fd[chan].fd, (long) fd[chan].gap_head, 1);/* *    for testing only, print gap_head & gap_total: *      printf("\n%d gap_head\n%d gap_total\n",             fd[chan].gap_head, fd[chan].gap_total ); */   }/* *    for testing only, print samples/block & bytes/block: *   printf("\n%d samples/block\n%d bytes/block\n\n",          fd[chan].samp_p_blk, fd[chan].byte_p_blk ); */   return(chan);}/*  ------------------------  READ FORMAT ROUTINE  -------------------------  *//*   DESCRIPTION:     status = read_format ( filename, format, vnames )     This routine determines the format associated with file "filename" andreturns this information.  As with the filename argument in the open channelroutines, read_format accepts filenames with or without extensions.  It uses thesame process that the open channel routines use to determine for what data filethe format information is sought.  Hence, for a given filename, read_formatalways gets the format which corresponds to the data file opened by an openchannel routine.  (However, read_format accepts filenames that end with.sg_format.  Such a filename would cause an error if given to an open channelroutine.)The format array contains the following information:     format[0]   -   file type indicator                     current meaning (will be expanded later):                     1 if .sg_data file allows sample & block positioning;                     0 if this is NOT allowed     format[1]   -   number of variables/block in .sg_data file     format[2*n]  -  data type of variable n in .sg_data file                     1 - short; 2 - int; 3 - float     format[2*n+1] - number of entries/block of variable n in .sg_data file"vnames" is an array of pointers to the names of variables saved in the datafile.  Thus, vnames[0] points to the name of the first variable, vnames[1]points to the name of the second variable, etc.     The format information comes from a .sg_format file when the data file isa .sg_data file.  Other data file types have fixed formats which return a setof parameters stored in this routine.  Below are listed the format parametersfor each of these other data file types.Format parameters for .spd data files:     format[0] = 1     format[1] = 1     format[2] = 1     format[3] = 512     vnames[0] = "speech_data"Returned value:     The returned value indicates the error status of the routine.  If no erroroccurs, the returned value is 0.  If an error occurs, the value is < 0.The following errors are detected:     - filename is too long     - invalid extension in filename     - no data file found, so can't determine format     - the format file could not be opened     - the format file is not complete     - invalid value read for file type     - invalid value read for variables/block     - invalid value read for data type     - invalid value read for values/block*/read_format ( file, format, vnames )char file[], *vnames[];int format[];{   short frmt[2 + 2*MAX_VARS_PER_BLK];   int temp_fd, i, file_status;   char filename[MAX_FILENAME_LENG + sizeof(FFE)];   strcpy(ervar.routine, "read_format");   strncpy(ervar.name, file, MAX_FILENAME_LENG);   strcat(ervar.name, "");   if (strlen(file) > MAX_FILENAME_LENG)  /* filename too long */   {      if (auto_er) error_exit(-2);      return(-2);   }/* *    check for filename extension options: */   file_status = test_filename(file, filename, 2);   if (file_status == -2)                /* invalid extension */   {      if (auto_er) error_exit(-10);      return(-10);   }   if (file_status == -1)                /* no data file found */   {      if (auto_er) error_exit(-25);      return(-25);   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -