📄 diskread.c
字号:
if (file_status == 1) /* the file is a .spd file */ { /* set default values */ format[0] = 1; format[1] = 1; format[2] = 1; format[3] = 512; strcpy( vnames[0], "speech_data" ); return(0); }/* * the file is the usual .sg_format type. open it: */ if( (temp_fd = open(filename, O_RDONLY)) == -1) /* can't open format file */ { perror("The system call error in disk read is"); if (auto_er) error_exit(-19); return(-19); }/* * read format[0] & format[1]: */ if (read(temp_fd, (char *) frmt, 4) != 4) /* incomplete format file */ { close(temp_fd); if (auto_er) error_exit(-20); return(-20); }/* * check format[0] & format[1] for proper values: */ if (frmt[0] < 0 || frmt[0] > 1) /* invalid file type */ { close(temp_fd); ervar.param = frmt[0]; if (auto_er) error_exit(-21); return(-21); } if (frmt[1] < 1 || frmt[1] > MAX_VARS_PER_BLK) /* invalid # of vars/block */ { close(temp_fd); ervar.param = frmt[1]; if (auto_er) error_exit(-22); return(-22); }/* * read the data type and number per block from format file: */ if (4*frmt[1] != read(temp_fd, (char *) &frmt[2], (int) 4*frmt[1])) { close(temp_fd); if (auto_er) error_exit(-20); return(-20); }/* * check the data type and number per block; and read the variable names: */ for (i=1; i<=frmt[1]; ++i) { if (frmt[2*i] < 1 || frmt[2*i] > NUM_DATA_TYPES) /* invalid data type */ { close(temp_fd); ervar.param = frmt[2*i]; if (auto_er) error_exit(-23); return(-23); } if (frmt[2*i+1] < 1 || frmt[2*i+1] > MAX_VALUES_PER_VAR) /* invalid # of vals per block */ { close(temp_fd); ervar.param = frmt[2*i+1]; if (auto_er) error_exit(-24); return(-24); } *(vnames[i-1]+MAX_VARNAME_LENG) = '\0'; /* ensure null termination */ if (MAX_VARNAME_LENG != read(temp_fd, vnames[i-1], MAX_VARNAME_LENG) ) { close(temp_fd); if (auto_er) error_exit(-20); return(-20); } }/* * everything OK, so transfer format info to int array and close format file: */ for (i=0; i<2*MAX_VARS_PER_BLK + 2; i++) format[i] = frmt[i]; close(temp_fd); return(0);}/* ------------------------ FILE LENGTH ROUTINE ------------------------- *//* DESCRIPTION: status = file_length ( chan_id, bytes, samples, blocks ) This routine returns the length of the file connected to "chan_id" interms of bytes, samples and blocks. I don't know what it should do withreal-time data files yet.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: - channel number is outside valid range - specified channel is not open*/file_length ( channel, bytes, samples, blocks )int channel, *bytes, *samples, *blocks;{ int length; struct stat status; /* for use with fstat */ strcpy(ervar.routine, "file_length"); strcpy(ervar.name, "UNKNOWN"); /* can't determine associated file name */ if (channel < 0 || channel >= MAX_CHANNELS) /* bogus channel # */ { ervar.param = channel; if (auto_er) error_exit(-3); return(-3); } if (fd[channel].open != 1) /* channel not open */ { ervar.param = channel; if (auto_er) error_exit(-4); return(-4); } fstat(fd[channel].fd, &status); /* unix library routine that returns */ length = status.st_size; /* file length in structure "status" */ *bytes = length; *blocks = length / fd[channel].byte_p_blk; *samples = *blocks * fd[channel].samp_p_blk; return(0);}/* ------------------------ GOTO SAMPLE ROUTINE ------------------------- *//* DESCRIPTION: position = goto_sample ( chan_id, sample_num, how ) This routine changes the sample number that the next call to read_variableon "chan_id" reads from. When "how" is 0, "sample_num" is measured from thebeginning of the file (i.e. absolute positioning). When "how" is not 0,"sample_num" is measured from the current file position (i.e. relativepositioning). The first sample in the file is called sample 1. This routinecan be called only if the specified channel is a "variable channel", that isone opened via open_var_channel. This routine does not return an error if thesample to be read is beyond the end of file; this condition is reported whenreading. Returned value: If there are no errors, the returned value indicates the current fileposition (the sample number of the next sample to be read by read_variable).A valid sample number is 1 or greater. If an error occurs, the value is < 0.The following errors are detected: - channel number is outside valid range - specified channel is not open - this routine is for use only with variable channel types - the file connected to this channel prohibits positioning - effective sample_num is < 1*/goto_sample ( channel, sample_num, how )int channel, sample_num, how;{ int samp_per_rec, skipped_rec, skipped_samp, next; long p; strcpy(ervar.routine, "goto_sample"); strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name *//* * do the easy error checking: */ if (channel < 0 || channel >= MAX_CHANNELS) /* bogus channel # */ { ervar.param = channel; if (auto_er) error_exit(-3); return(-3); } if (fd[channel].open != 1) /* channel not open */ { ervar.param = channel; if (auto_er) error_exit(-4); return(-4); } strcpy(ervar.name, fd[channel].filename); if (fd[channel].ch_type != 1) /* not a "variable" chan type */ { if (auto_er) error_exit(-7); return(-7); } if (fd[channel].format[0] != 1) /* file prohibits positioning */ { if (auto_er) error_exit(-9); return(-9); } next = (how == 0) ? sample_num : sample_num + fd[channel].next; if (next < 1) /* invalid sample # */ { ervar.param = next; if (auto_er) error_exit(-27); return(-27); } fd[channel].next = next; samp_per_rec = fd[channel].format[2*fd[channel].v + 1]; skipped_rec = (fd[channel].next - 1) / samp_per_rec; skipped_samp = (fd[channel].next - 1) % samp_per_rec; p = skipped_rec * fd[channel].byte_p_blk + fd[channel].gap_head + skipped_samp * bytes_in[fd[channel].format[2*fd[channel].v] -1]; lseek(fd[channel].fd, p, 0); fd[channel].samp_avail = samp_per_rec - skipped_samp; return(next);}/* ----------------------- READ VARIABLE ROUTINE ------------------------ *//* DESCRIPTION: position = read_variable ( chan_id, values, num, num_read ) This routine returns the next "num" values of the variable connected tochannel number "chan_id". "values" is a pointer to an array where the returnedvalues are placed. In the calling routine, this array type should match that ofthe variable being returned. The size of "n" is limited only by the array sizein the calling routine. The actual number of values read is returned via thepointer "num_read". "num_read" will equal "num" unless an error (specifiedbelow) occurs; in this case, it may be zero to num-1. This routine can becalled only if the specified channel is a "variable channel", that is oneopened via open_var_channel.Returned value: If there are no errors, the returned value indicates the current fileposition (the sample number of the next sample to be read by read_variable).A valid sample number is 1 or greater. If an error occurs, the value is < 0.The following errors are detected: - error during the file read operation - EOF encountered on the data file - channel number is outside valid range - specified channel is not open - this routine is for use only with variable channel types*/read_variable ( channel, values, n, n_read )int channel, n, *n_read;char values[];{ int bytes, b_read, s_read; strcpy(ervar.routine, "read_variable"); strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name */ *n_read = 0; /* set number read in case of an early error *//* * do the easy error checking: */ if (channel < 0 || channel >= MAX_CHANNELS) /* bogus channel # */ { ervar.param = channel; if (auto_er) error_exit(-3); return(-3); } if (fd[channel].open != 1) /* channel not open */ { ervar.param = channel; if (auto_er) error_exit(-4); return(-4); } strcpy(ervar.name, fd[channel].filename); if (fd[channel].ch_type != 1) /* not a "variable" channel */ { if (auto_er) error_exit(-7); return(-7); }/* * split into two cases, 1 variable or >1 variable in file: */ if (fd[channel].format[1] == 1) /* .sg_data file has only 1 variable */ { bytes = bytes_in[fd[channel].format[2] -1] * n; b_read = read(fd[channel].fd, values, bytes); if (b_read == -1) /* error during read */ { perror("The system call error in disk read is"); if (auto_er) error_exit(-6); return(-6); } *n_read = b_read / bytes_in[fd[channel].format[2] -1]; } else /* .sg_data file has several variables, the general case */ { s_read = read_sg(channel, values, n); if (s_read == -1) /* error during read */ { perror("The system call error in disk read is"); if (auto_er) error_exit(-6); return(-6); } *n_read = s_read; } fd[channel].next += *n_read; if (*n_read != n) /* EOF encountered */ { if (auto_er) error_exit(-5); return(-5); } return(fd[channel].next);}/* ------------------------ GOTO BLOCK ROUTINE -------------------------- *//* DESCRIPTION: position = goto_block ( chan_id, block_num, how ) This routine changes the place from which data is read in the fileconnected to "chan_id". When 'how' is 0, 'block_num' is measured from thebeginning of the file (i.e. absolute positioning). When 'how' is not 0,'block_num' is measured from the current file position (i.e. relativepositioning). It can be used on block channels and on variable channels.The first block in a file is called block 1. This routine does not return anerror if positioned beyond the end of file; this condition is reported whenreading. On block channels the repositioning is as follows: If doing absolute positioning, the block number read by the next read_blockis "block_num". If doing relative positioning, the block number read by the next read_blockis changed by "block_num" blocks. On variable channels the repositioning is as follows: If doing absolute positioning, the first sample read by the nextread_variable is sample number:1 + (block_num - 1) * (# of values of variable per block) If doing relative positioning, the first sample read by the nextread_variable is changed by "block_num" blocks.Returned value: If there are no errors, the returned value indicates the current fileposition. On variable channels, the returned value is the sample number of thenext sample to be read by read_variable. On block channels, the returned valueis the block number of the next block to be read by read_block. A valid samplenumber or block number is 1 or greater. If an error occurs, the value is < 0.The following errors are detected: - channel number is outside valid range - specified channel is not open - the file connected to this channel prohibits positioning - effective block_num < 1*/goto_block ( channel, block_num, how )int channel, block_num, how;{ int next; long p; strcpy(ervar.routine, "goto_block"); strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name *//* * do the easy error checking: */ if (channel < 0 || channel >= MAX_CHANNELS) /* bogus channel # */ { ervar.param = channel; if (auto_er) error_exit(-3); return(-3); } if (fd[channel].open != 1) /* channel not open */ { ervar.param = channel; if (auto_er) error_exit(-4); return(-4); } strcpy(ervar.name, fd[channel].filename); if (fd[channel].format[0] != 1) /* file prohibits positioning */ { if (auto_er) error_exit(-9); return(-9); }/* * partition according to positioning type: */ if (how == 0) /* absolute positioning */ { next = (fd[channel].ch_type == 2) ? block_num : 1 + (block_num - 1) * fd[channel].format[2*fd[channel].v+1]; if (next < 1) /* invalid block # */ { ervar.param = block_num; if (auto_er) error_exit(-30); return(-30); } p = (block_num - 1) * fd[channel].byte_p_blk; lseek(fd[channel].fd, p, 0);/* * check for the general case and skip gap_head bytes, if so: */ if (fd[channel].ch_type == 1 && fd[channel].format[1] > 1) { lseek(fd[channel].fd, (long) fd[channel].gap_head, 1); fd[channel].samp_avail = fd[channel].format[2*fd[channel].v+1]; } } else /* relative positioning */ { next = (fd[channel].ch_type == 2) ? fd[channel].next + block_num : fd[channel].next + block_num * fd[channel].format[2*fd[channel].v+1]; if (next < 1) /* invalid block # */ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -