int verify_file_checksum(char *filename) { char *proc="verify_file_checksum " SPHERE_VERSION_STR; SP_FILE *sp; char buf[1024]; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (filename == CNULL) return_err(proc,100,100,"Null filename"); if ((sp = sp_open(filename,"rv")) == SPNULL) return_err(proc,101,101, rsprintf("Unable to open SPHERE file '%s'",filename)); if (sp->read_spifr->status->user_sample_count > 0){ if (sp_read_data(buf,1,sp) != 1){ sp_close(sp); return_err(proc,200,200,"Verification of checksum failed"); } } else { sp_close(sp); return_err(proc,300,300,"No data in file to check"); } sp_close(sp); if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"Checksum verification passed"); }
static int pre_verify_checksum(SP_FILE *sp){ char *proc="pre_verify_checksum " SPHERE_VERSION_STR; SPIFR *spifr=sp->read_spifr; SP_CHECKSUM checksum; /* if the samples are in memory, compute the checksum from there. */ /* if not, read in the file, a block at a time and compute the */ /* checksum. */ switch (spifr->status->file_encoding){ case SP_se_pcm2: if (fob_short_checksum(spifr->waveform->sp_fob, &checksum, spifr->status->file_sbf != spifr->status->natural_sbf, sp_add_checksum) < 0) return_err(proc,501,0,"Unable to Pre-Verify Checksum"); if (checksum != spifr->status->file_checksum){ spifr->waveform->failed_checksum = TRUE; return_err(proc,1001,0, "Pre-Read Short Checksum Test Failed"); } break; default: if (fob_char_checksum(spifr->waveform->sp_fob, &checksum,sp_add_checksum) < 0) return_err(proc,502,0,"Unable to Pre-Verify Checksum"); if (checksum != spifr->status->file_checksum){ spifr->waveform->failed_checksum = TRUE; return_err(proc,1001,0, "Pre-Read Char Checksum Test Failed"); } break; } return_success(proc,0,0,"ok"); }
int parse_sample_byte_format(char *str, enum SP_sample_byte_fmt *sbf) { char *proc="parse_sample_byte_format " SPHERE_VERSION_STR; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (str == CNULL) return_err(proc,100,100,"Null sample_byte_format_string"); if (sbf == (enum SP_sample_byte_fmt *)0) return_err(proc,101,101,"Null sbf pointer"); if (strsame(str,"01")) *sbf = SP_sbf_01; else if (strsame(str,"10")) *sbf = SP_sbf_10; else if (strsame(str,"1")) *sbf = SP_sbf_1; else if (strsame(str,"0123")) *sbf = SP_sbf_0123; else if (strsame(str,"1032")) *sbf = SP_sbf_1032; else if (strsame(str,"2301")) *sbf = SP_sbf_2301; else if (strsame(str,"3210")) *sbf = SP_sbf_3210; else if (strsame(str,"N")) *sbf = SP_sbf_N; if (strstr(str,"shortpack") != CNULL) { /* this return value must remain 1000, other functions depend on it*/ return_err(proc,1000,1000, rsprintf("Unknown sample_byte_format value '%s' in header",str)); } if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"ok"); }
int sp_compute_checksum(SP_FILE *sp, SP_CHECKSUM *comp_chksum){ char *proc = "sp_compute_checksum"; void *buff; SP_INTEGER cur_pos; if (sp == SPNULL) return_err(proc,101,101,"Null SPFILE structure"); if (sp->open_mode != SP_mode_read) return_err(proc,102,102,"File must be opened for read"); if (! sp->read_spifr->status->is_disk_file) return_err(proc,103,103,"File must be a disk file"); if (sp_error(sp) != 0) return_err(proc,104,104,"Sphere file already has an error"); /* save the current position so we can go back to it */ if ((cur_pos = sp_tell(sp)) < 0) return_err(proc,110,110, rsprintf("sp_tell() failed, returning: %s", get_return_status_message())); /* rewind the file */ if (sp_seek(sp,0,0) != 0) return_err(proc,111,111, rsprintf("sp_seek() to sample 0 failed, returning: %s", get_return_status_message())); /* allocate some memory */ if ((buff = (void *)sp_data_alloc(sp,4096)) == (void *)0) return_err(proc,112,112, rsprintf("can not alloc waveform buffer, returning: %s", get_return_status_message())); /* read in the data */ while (sp_read_data(buff,4096,sp) > 0) ; /* dealloc memory */ sp_data_free(sp,buff); if (sp_error(sp) != 0) return_err(proc,120,120, rsprintf("sp_error() indicates an error, returning: %s", get_return_status_message())); *comp_chksum = sp->read_spifr->waveform->checksum; if (sp_seek(sp,cur_pos,0) != 0) return_err(proc,130,130, rsprintf("sp_seek() to return the file to it's initial" "state failed, returning: %s", get_return_status_message())); return_success(proc,0,0,"ok"); }
bool s4pp_pull (s4pp_ctx_t *ctx, s4pp_next_fn next, s4pp_done_fn done) { if (ctx->next || ctx->done) { progress_work (ctx); return_err(S4PP_ALREADY_BUSY); } ctx->next = next; ctx->done = done; progress_work (ctx); return_res; }
int safechdir (str path) { vec<str> dirs; if (!path2vec (dirs, path)) { warn << "safechdir: invalid path " << path << "\n"; return EINVAL; } int curdir = open (".", O_RDONLY); if (curdir < 0) { warn ("open (\".\"): %m\n"); return errno; } str pp = ""; chdir ("/"); bhash<devino> dicache; { struct stat sb; if (stat (".", &sb) < 0) return return_err ("/", curdir); dicache.insert (devino (sb.st_dev, sb.st_ino)); } while (!dirs.empty ()) { str dir = dirs.pop_front (); pp = pp << "/" << dir; /* We open and fchdir because open never uses the attribute cache. * The problem is that on some systems, the name cache may contain * incorrect data (particularly if the directory we are mounting * on was just recently a symbolic link). Using open will at the * very least force a getattr, which we hope will, when it gets a * stale file handle error, cause a lookup. */ struct stat sb1, sb2; autofd fd (open (dir, O_RDONLY)); if (fd < 0 || lstat (dir, &sb1) < 0 || fstat (fd, &sb2) < 0) return return_err (pp, curdir); if (sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) { warn << pp << ": file system changed during safechdir\n"; return return_err (NULL, curdir, EXDEV); } if (!dicache.insert (devino (sb2.st_dev, sb2.st_ino))) return return_err (pp, curdir, ELOOP); if (!S_ISDIR (sb1.st_mode)) return return_err (pp, curdir, ENOTDIR); if (fchdir (fd) < 0) return return_err (pp, curdir); } close (curdir); return 0; }
static int decompress_waveform(SP_FILE *sp) { int decomp_into_memory=TRUE; int wav_bytes=0; SPIFR *spifr = sp->read_spifr; FOB *fob_in, *fob_out; char *buff; int blen; char *proc="decompress_waveform " SPHERE_VERSION_STR; wav_bytes = spifr->status->user_sample_count * spifr->status->user_channel_count * spifr->status->user_sample_n_bytes; /* the file must be decompressed, Question: Should it be done in memory? */ if (wav_bytes > MAX_INTERNAL_WAVFORM) decomp_into_memory = FALSE; /* The file needs to be de_compressed into memory !!!! */ /* 1. make an FOB struct for the uncompressed waveform to be read into d */ /* and the original file */ /* 2. allocate memory for the entire waveform */ /* 3. decompress the file */ /* 4. Clean up the FOB struct for the file, moving the fp from the FOB */ /* 5. reset the uncompressed FOB struct to the beginning of the memory */ if (decomp_into_memory) { if (sp_verbose > 15) fprintf(spfp,"Proc %s: Pre-buffering compressed data into memory\n", proc); if (fob_create2(spifr->waveform->sp_fp, FPNULL, &fob_in, &fob_out) < 0) return_err(proc,200,0,"Unable to setup for decompression"); blen = spifr->status->file_channel_count * spifr->status->file_sample_count * spifr->status->file_sample_n_bytes; if ((buff=mtrf_malloc(blen)) == CNULL){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,201,0,"Unable to malloc memory to decompress into"); } fob_bufinit(fob_out, buff, blen); } else { /* decompress into a disk file */ FILE *temp_fp; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Pre-buffering compressed data %s\n", proc,"into a temporary file"); spifr->status->temp_filename = sptemp_dirfile(); if (spifr->status->temp_filename == CNULL) return_err(proc,400,0,"Unable to create usable temporary file"); if (sp_verbose > 15) fprintf(spfp,"Proc %s: %s%d bytes long, using temp file %s\n", proc, "Attempting to read a big file ",wav_bytes, spifr->status->temp_filename); if ((temp_fp=fopen(spifr->status->temp_filename,TRUNCATE_UPDATEMODE)) == FPNULL) return_err(proc,401,0, rsprintf("Unable to open temporary file %s", spifr->status->temp_filename)); if (fob_create2(spifr->waveform->sp_fp, temp_fp, &fob_in, &fob_out) <0) return_err(proc,402,0,"Unable to setup for decompression"); /* the FILE pointer will be closed after completion of the */ /* decompression directly from the fob_in FOB pointer. this is the */ /* bug which Francis caught. */ /* Note: Do NOT set the waveform file to FPNULL here (see bugfix */ /* below.) ***PSI*** 24-Sep-1993 */ /* spifr->waveform->sp_fp = FPNULL; */ spifr->status->is_temp_file = TRUE; } if (sp_verbose > 15) fprintf(spfp, "Proc %s: before decompression, input file at position %d\n", proc,fob_ftell(fob_in)); switch (spifr->status->file_compress){ char message[80]; case SP_wc_shorten: if (sp_verbose > 15) fprintf(spfp,"Proc %s: Executing Shorten Decompression\n",proc); if (setjmp(exitenv) == 0){ if (shorten_uncompress(fob_in, fob_out, message) < 0){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,202,0, rsprintf("Shorten Decompression Failed",message)); } } else { fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,207,0,"Shorten Decompression aborted"); } break; case SP_wc_wavpack: if(setjmp(exitenv) == 0){ if (sp_verbose > 15) fprintf(spfp,"before set progname\n"); wavpack_set_progname( "wavpack" ); if (sp_verbose > 15) fprintf(spfp, "Proc %s: Executing Wavpack Decompression\n",proc); if (sp_verbose > 15) wavpack_dump_interface(spfp); if (wavpack_unpack(fob_in, fob_out) < 0){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,203,0,"Wavpack Decompression Failed"); } wavpack_free_progname(); } else { fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,206,0,"Wavpack Decompression aborted"); } break; case SP_wc_shortpack: if(setjmp(exitenv) == 0){ if (sp_verbose > 15) fprintf(spfp, "Proc %s: Executing Shortpack Decompression\n",proc); if (shortpack_uncompress(fob_in, fob_out, spifr->status->file_header) < 0){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,203,0,"Shortpack Decompression Failed"); } } else { fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,208,0,"Shortpack Decompression aborted"); } break; default: return_err(proc,209,0,"Unable to decompress the requested format\n"); } fob_rewind(fob_out); /**** Begin SRI bugfix. ****/ /* If a temporary file is being used, close the waveform file BEFORE */ /* setting it to FPNULL. ***PSI*** 24-Sep-1993 */ if (spifr->status->is_temp_file) { if (sp_verbose > 15) fprintf(spfp,"Proc %s: Closing waveform file \"%s\" (%d)\n", proc, spifr->status->external_filename, fileno(spifr->waveform->sp_fp)); if (fclose(spifr->waveform->sp_fp)) return_err(proc, 403, 0, rsprintf("Unable to close waveform file \"%s\" (%d)", spifr->status->external_filename, fileno(spifr->waveform->sp_fp))); spifr->waveform->sp_fp = FPNULL; } /**** End SRI bugfix. ****/ if (! decomp_into_memory) { /* Close the original file pointer to the SPHERE file */ fclose(fob_in->fp); } fob_destroy(fob_in); spifr->waveform->sp_fob = fob_out; return_success(proc,0,0,"ok"); }
/* * * sp_read_data() * */ int sp_mc_read_data(void *buffer, size_t num_sample, SP_FILE *sp) { char *proc="sp_read_data " SPHERE_VERSION_STR; SPIFR *spifr; int ret; int do_conversions, do_channel_selections; if (buffer == (void *)0) return_err(proc,100,0,"Null memory buffer"); if (sp == SPNULL) return_err(proc,101,0,"Null SPFILE structure"); if (sp->open_mode != SP_mode_read) return_err(proc,104,104,"Read on a file not opened for read"); #ifdef isnotansi if (num_sample < 0) return_err(proc,103,0, rsprintf("Negative sample count %d",num_sample)); #endif spifr = sp->read_spifr; if (sp_verbose > 10) fprintf(spfp, "Proc %s: file %s, %d bytes/sample, %d channels, %d samples\n", proc,spifr->status->external_filename, spifr->status->user_sample_n_bytes, spifr->status->user_channel_count, num_sample); if (spifr->waveform->failed_checksum) return_err(proc,1001,0,"Pre-Read Checksum Test Failed"); /***********************************************************************/ /* Perform all initializations to the sphere file to begin reading */ if (spifr->status->read_occured_flag == FALSE) { spifr->status->read_occured_flag = TRUE; if (sp_verbose > 15) fprintf(spfp, "Proc %s: Initializing read of data\n", proc); if ((spifr->status->user_compress == SP_wc_none) && (spifr->status->file_compress != SP_wc_none)){ decompress_waveform(sp) ; if ((ret = sp_get_return_status()) != 0) return_err(proc,ret,0, rsprintf("decompress_waveform failed, %s", get_return_status_message())); } else { /* The following code assumes that no pre-reading of the */ /* waveform is needed */ if ((spifr->waveform->sp_fob = fob_create(spifr->waveform->sp_fp)) == FOBPNULL) return_err(proc,300,0, "Unable to allocate a FOB 'File or Buffer' struct."); spifr->waveform->sp_fp = FPNULL; } /****************************************************/ /** INVARIANT ASSERTION: **/ /** The data is now in it's natural (decomp) form **/ /****************************************************/ /************ Set up the file conversions ***********/ /****************************************************/ /* Set up byte format the conversions */ if (spifr->status->user_sbf != spifr->status->file_sbf) if (((spifr->status->user_sbf == SP_sbf_01) && (spifr->status->file_sbf == SP_sbf_10)) || ((spifr->status->user_sbf == SP_sbf_10) && (spifr->status->file_sbf == SP_sbf_01))) fob_read_byte_swap(spifr->waveform->sp_fob); /********************************************************/ /* set up a translation buffer, for sample conversions */ /* and channel selections */ /* are sample encodings necessary ????? */ do_conversions = FALSE; if (spifr->status->user_encoding != spifr->status->file_encoding) { if (((spifr->status->file_encoding == SP_se_ulaw) && (spifr->status->user_encoding == SP_se_pcm2)) || ((spifr->status->file_encoding == SP_se_pcm2) && (spifr->status->user_encoding == SP_se_ulaw))) do_conversions = TRUE; else return_err(proc,400,0, "Unable to convert sample types ... for now\n"); } /* are channel selection requested ????? */ do_channel_selections = FALSE; if (spifr->status->channels != CHANNELSNULL) do_channel_selections = TRUE; if (do_conversions || do_channel_selections || (spifr->status->user_data_fmt == SP_df_array)){ /* allocate the memory for the file data buffer */ /* IF it's a legal transformation */ spifr->waveform->file_data_buffer_len = TRANSLATION_LEN * spifr->status->file_sample_n_bytes * spifr->status->file_channel_count; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes%s\n", proc, spifr->waveform->file_data_buffer_len,TRANSLATION_LEN, spifr->status->file_sample_n_bytes, spifr->status->file_channel_count, " for file data buffer"); if ((spifr->waveform->file_data_buffer = (void *) mtrf_malloc(spifr->waveform->file_data_buffer_len)) == (void *)0) return_err(proc,500,0, "Unable to alloc memory for the translation buffer"); } if (do_conversions && (do_channel_selections || (spifr->status->user_data_fmt == SP_df_array))){ spifr->waveform->converted_buffer_len = TRANSLATION_LEN * spifr->status->user_sample_n_bytes * spifr->status->file_channel_count; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes %s\n", proc, spifr->waveform->converted_buffer_len,TRANSLATION_LEN, spifr->status->user_sample_n_bytes, spifr->status->file_channel_count, "for converted data buffer"); if ((spifr->waveform->converted_buffer = (void *) mtrf_malloc(spifr->waveform->converted_buffer_len)) == (void *)0) return_err(proc,550,0, "Unable to alloc memory for the translation buffer"); } if (spifr->status->user_data_fmt == SP_df_array){ spifr->waveform->interleave_buffer_len = TRANSLATION_LEN * spifr->status->user_sample_n_bytes * spifr->status->user_channel_count; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes %s\n", proc, spifr->waveform->interleave_buffer_len,TRANSLATION_LEN, spifr->status->user_sample_n_bytes, spifr->status->user_channel_count, "for interleave data buffer"); if ((spifr->waveform->interleave_buffer = (void *) mtrf_malloc(spifr->waveform->interleave_buffer_len)) == (void *)0) return_err(proc,600,0, "Unable to alloc memory for the interleave buffer"); } /* pre-verify the waveform data */ if (spifr->status->extra_checksum_verify){ pre_verify_checksum(sp); if ((ret = sp_get_return_status()) != 0) return_err(proc,ret,0, rsprintf("pre_verify_checksum failed, %s", get_return_status_message())); } } if (sp_verbose > 15) fprintf(spfp, "Proc %s: current file position %d\n",proc, fob_ftell(spifr->waveform->sp_fob)); ret = read_data_in(buffer, num_sample, sp); if (sp_get_return_type() == RETURN_TYPE_ERROR) return_err(proc,sp_get_return_status(),0, rsprintf("read_data_in failed, %s", get_return_status_message())); return_success(proc,0,ret,"ok"); }
static int read_data_in(void *buffer, size_t num_sample, SP_FILE *sp){ SPIFR *spifr; char *proc=" read_data_in " SPHERE_VERSION_STR; int samples_read = 0; int in_samples=0, o, oc, s, c, ret; int block=0; char *in_block=(char *)0, *out_block=(char *)0; char *current_data_location = (char *)0; char *out_conversion_block=(char *)0,*in_conversion_block=(char *)0; char *next_out_block=(char *)0; short *sh_data=(short *)0; unsigned char *ulaw_data = (unsigned char *)0; SP_CHECKSUM checksum=0, block_checksum=0; int file_record_size; char **arr_buff = (char **)0, *arr; spifr = sp->read_spifr; file_record_size = spifr->status->file_sample_n_bytes * spifr->status->file_channel_count; while ((samples_read < num_sample) && (! fob_feof(spifr->waveform->sp_fob))){ if (sp_verbose > 16) fprintf(spfp,"Proc %s: Beginning block %d\n",proc,block); /* read in either a block or the whole chunk if data */ if (spifr->waveform->file_data_buffer != CNULL) { if (sp_verbose > 15) fprintf(spfp, "Proc %s: reading a block into temporary storage\n", proc); in_block = (void *)spifr->waveform->file_data_buffer; current_data_location = in_block; if ((in_samples = (num_sample - samples_read))> TRANSLATION_LEN) in_samples = TRANSLATION_LEN; ret = fob_fread(in_block, file_record_size, in_samples, spifr->waveform->sp_fob); if (ret < 0) return_err(proc,105,0,"Unable to read data"); } else { /* there was no change in the sample coding so just read */ /* in the data */ if (sp_verbose > 15) fprintf(spfp, "Proc %s: read a block WITHOUT coding conversions\n", proc); ret = fob_fread(buffer, file_record_size, num_sample, spifr->waveform->sp_fob); if (ret < 0) return_err(proc,107,0,"Unable to read data"); in_block = (void *)buffer; current_data_location = in_block; } if (sp_verbose > 16) fprintf(spfp, "Proc %s: block read of %d Samples, expected %d\n", proc,ret,num_sample); in_samples = ret; /**** ret is the number of samples per time period read in from */ /**** the file */ /**** Do the checksum computation before format changes occur ***/ switch (spifr->status->file_encoding){ case SP_se_pcm2: /* DON'T SWAP if the coding type hasn't changed, and the */ /* output SBF == natural_sbf */ /* OR if the coding changed and the file SBF */ /* is == natural SBF */ if (((spifr->status->user_encoding == SP_se_pcm2) && (spifr->status->natural_sbf == spifr->status->user_sbf)) || ((spifr->status->user_encoding != SP_se_pcm2) && (spifr->status->natural_sbf == spifr->status->file_sbf))){ if (sp_verbose > 16) fprintf(spfp, "Proc %s: Not Swapping for checksum\n",proc); checksum = sp_compute_short_checksum((void *)in_block,in_samples* spifr->status->file_channel_count, FALSE); } else { if (sp_verbose > 16) fprintf(spfp,"Proc %s: Swapping for checksum\n",proc); checksum = sp_compute_short_checksum((void *)in_block, in_samples*spifr->status->file_channel_count, TRUE); } break; default: { int n; n = in_samples * spifr->status->file_channel_count * spifr->status->file_sample_n_bytes; if (sp_verbose > 16) fprintf(spfp,"Proc %s: Computing char checksum %d bytes\n", proc,n); checksum = sp_compute_char_checksum(in_block, n); break; } } spifr->waveform->checksum = sp_add_checksum(spifr->waveform->checksum,checksum); block_checksum = checksum; /*** FINISHED WITH THE CHECKSUMS ***/ samples_read += in_samples; spifr->waveform->samples_read += in_samples; if (sp_eof(sp)) /* only check this if the user_sample count is real */ /* Added June 22, 1994 by JGF */ if (spifr->status->user_sample_count != 999999999){ if (spifr->waveform->samples_read != spifr->status->user_sample_count){ spifr->waveform->read_premature_eof = TRUE; return_err(proc,500,0, rsprintf("Premature End-of-File %d read != %d", spifr->waveform->samples_read, spifr->status->user_sample_count)); } } if (spifr->waveform->samples_read == spifr->status->user_sample_count){ if ((! spifr->status->ignore_checksum) && (spifr->waveform->checksum != spifr->status->file_checksum)){ spifr->waveform->failed_checksum = TRUE; return_err(proc,1000,0, rsprintf("%sComputed %d != Expected %d", "Checksum Test Failed ", spifr->waveform->checksum, spifr->status->file_checksum)); } } /**** Do the sample coding conversions ****/ if (((spifr->status->file_encoding == SP_se_ulaw) && (spifr->status->user_encoding == SP_se_pcm2)) || ((spifr->status->file_encoding == SP_se_pcm2) && (spifr->status->user_encoding == SP_se_ulaw))) { int samples_to_change = in_samples*spifr->status->file_channel_count; if ((spifr->status->channels != CHANNELSNULL) || (spifr->status->user_data_fmt == SP_df_array)){ out_conversion_block = next_out_block = (char *)spifr->waveform->converted_buffer; if (sp_verbose > 16) fprintf(spfp,"Proc %s: using converted buffer output\n", proc); } else { out_conversion_block = (char *)buffer; if (sp_verbose > 16) fprintf(spfp,"Proc %s: using buffer output argument\n", proc); if (next_out_block == (char *)0) next_out_block = out_conversion_block; } if (sp_verbose > 16) fprintf(spfp, "Proc %s: converting %d (%d*%d) samples\n",proc, samples_to_change,in_samples, spifr->status->file_channel_count); if ((spifr->status->file_encoding == SP_se_ulaw) && (spifr->status->user_encoding == SP_se_pcm2)) { /* now convert the block into the buffer */ if (sp_verbose > 16) fprintf(spfp,"Proc %s: Converting ULAW to PCM", proc); /* set up some pointers */ ulaw_data = (unsigned char *)spifr->waveform->file_data_buffer; sh_data = (short *)next_out_block ; /*** This was a bug, it used to compare to sp_sbf_10 ***/ if (spifr->status->user_sbf != get_natural_sbf(2)){ if (sp_verbose > 16) fprintf(spfp," outputting 01 format bytes\n"); for (o=0; o < samples_to_change; o++) { *sh_data = ulaw2linear_01_sbf_lut[*ulaw_data]; sh_data ++; ulaw_data ++; } } else { if (sp_verbose > 16) fprintf(spfp," outputting 10 format bytes\n"); for (o=0; o < samples_to_change; o++) { *sh_data = ulaw2linear_10_sbf_lut[*ulaw_data]; sh_data ++; ulaw_data ++; } } next_out_block = (char *)sh_data; } else if ((spifr->status->file_encoding == SP_se_pcm2) && (spifr->status->user_encoding == SP_se_ulaw)) { if (sp_verbose > 16) fprintf(spfp,"Proc %s: Performing read translation%s\n", proc," from PCM2 to ULAW"); /* set up some pointers */ sh_data = (short *)spifr->waveform->file_data_buffer; ulaw_data = (unsigned char *)next_out_block; if (spifr->status->file_sbf != spifr->status->natural_sbf){ char *p , temp; short odata; if (sp_verbose > 16) fprintf(spfp, "Proc %s: Swapping input shorts\n", proc); for (o=0; o < samples_to_change; o++) { /* Pre swap the bytes */ odata = *sh_data; p = (char *) &odata; temp = *p; *p = *(p + 1); *(p + 1) = temp; /* fprintf(spfp, " %d -> %x -> %x\n",o,*sh_data,odata); */ *ulaw_data = linear2ulaw(odata); sh_data ++; ulaw_data ++; } }else for (o=0; o < samples_to_change; o++) { *ulaw_data =linear2ulaw(*sh_data); sh_data ++; ulaw_data ++; } next_out_block = (char *)ulaw_data; } else return_err(proc,109,0,"Internal Error"); current_data_location = out_conversion_block; } /* Do the channel conversions */ if (spifr->status->channels != CHANNELSNULL){ int in_recsize, out_recsize, in_chancnt, out_chancnt; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Converting channels\n",proc); if (spifr->status->user_data_fmt == SP_df_array) out_block = spifr->waveform->interleave_buffer; else if (out_block == (void *)0) out_block = (void *)buffer; current_data_location = out_block; if (spifr->status->file_encoding != spifr->status->user_encoding) in_conversion_block = (void *)spifr->waveform->converted_buffer; else if (in_conversion_block == (void *)0) in_conversion_block = (void *)spifr->waveform->file_data_buffer; in_chancnt = spifr->status->file_channel_count; in_recsize = spifr->status->user_sample_n_bytes * in_chancnt; out_chancnt = spifr->status->user_channel_count; out_recsize = spifr->status->user_sample_n_bytes * out_chancnt; for (oc=0; oc<spifr->status->channels->num_chan; oc++) if (spifr->status->channels->ochan[oc].num_origin == 1){ char *in_ptr, *out_ptr; in_ptr = in_conversion_block + ((spifr->status->channels->ochan[oc].orig_channel[0]-1) * spifr->status->user_sample_n_bytes); out_ptr = out_block + (oc * spifr->status->user_sample_n_bytes); for (s=0; s<in_samples; s++){ memcpy(out_ptr,in_ptr, spifr->status->user_sample_n_bytes); in_ptr += in_recsize; out_ptr += out_recsize; } } else { if (spifr->status->user_encoding == SP_se_pcm2) { /* do a straight add */ ORIGINATION_CHAN *ochn; short *in_ptr, *out_ptr; int sum, ch; if (sp_verbose > 15) fprintf(spfp, "Proc %s: Adding PCM data %s %d\n", proc, "channel",oc); in_ptr = (short *)in_conversion_block; out_ptr = (short *)out_block; ochn = &(spifr->status->channels->ochan[oc]); if (spifr->status->user_sbf== get_natural_sbf(2)){ for (s=0; s<in_samples; s++){ for (ch=0, sum=0; ch < ochn->num_origin; ch++){ sum +=*(in_ptr+ochn->orig_channel[ch]-1); } if (sum > 32767) sum = 32767; else if (sum < -32768) sum = -32768; *(out_ptr + oc) = (short)sum; in_ptr += in_chancnt; out_ptr += out_chancnt; } } else { short x; if (sp_verbose > 15) fprintf(spfp,"Proc %s: %s %d\n", proc, "Adding Swapped PCM data channel",oc); for (s=0; s<in_samples; s++){ /* fprintf(spfp,"sample %d\n",s); */ for (ch=0, sum=0; ch < ochn->num_origin; ch++){ x = *(in_ptr+ochn->orig_channel[ch]-1); swap_bytes(x); sum += x; /* fprintf(spfp," %d = %d\n",x,sum); */ } if (sum > 32767) x = 32767; else if (sum < -32768) x = -32768; else x = sum; swap_bytes(x); *(out_ptr + oc) = (short)x; in_ptr += in_chancnt; out_ptr += out_chancnt; } } } else if (spifr->status->user_encoding == SP_se_ulaw){ /* do an add on ulaw data */ ORIGINATION_CHAN *ochn; unsigned char *in_ptr, *out_ptr; int sum, ch; if (sp_verbose > 15) fprintf(spfp, "Proc %s: Adding ULAW data %s %d\n", proc, "channel",oc); in_ptr = (unsigned char *)in_conversion_block; out_ptr = (unsigned char *)out_block; ochn = &(spifr->status->channels->ochan[oc]); for (s=0; s<in_samples; s++){ for (ch=0, sum=0; ch < ochn->num_origin; ch++){ sum += ulaw2linear_10_sbf_lut[ *(in_ptr+ochn->orig_channel[ch]-1)]; } if (sum > 32767) sum = 32767; else if (sum < -32768) sum = -32768; *(out_ptr + oc) = linear2ulaw(sum); in_ptr += in_chancnt; out_ptr += out_chancnt; } } } out_block += out_recsize * in_samples; } if (spifr->status->user_data_fmt == SP_df_array){ /* convert the data from it's interleaved form */ /* to an array format */ int snb = spifr->status->user_sample_n_bytes; int chcnt = spifr->status->user_channel_count; int recsize = snb * chcnt; char *in_dat; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Converting data to an array\n", proc); if (arr_buff == (char **)0) arr_buff = (char **)buffer; for (c=0; c<chcnt; c++){ in_dat = current_data_location + (snb * c) ; arr = arr_buff[c] + ((samples_read-in_samples) * snb); for (s=0; s<in_samples; s++,arr+=snb,in_dat+=recsize) memcpy(arr,in_dat,snb); } } if (sp_verbose > 11){ fprintf(spfp,"Proc %s: Block %d: Requested %d samples", proc,block++,num_sample); fprintf(spfp," read %d total %d, Checksum %d (BC %d)\n", ret,spifr->waveform->samples_read, block_checksum, spifr->waveform->checksum); } } return_success(proc,0,samples_read,"ok"); }
int sp_copy_header(SP_FILE *spin, SP_FILE *spout) { char *proc_name="sp_copy_header " SPHERE_VERSION_STR; struct header_t *h; int i; SP_INTEGER l_int; SP_REAL real; if (spin->open_mode == SP_mode_read) h = spin->read_spifr->header; else if (spin->open_mode == SP_mode_write) h = spin->write_spifr->header; else return_err(proc_name,100,100,"Unable to dup header opened for update"); /* just loop through all the names, adding each field */ for (i=0; i < h->fc ; i++){ switch (h->fv[i]->type){ case T_STRING: if (sp_h_set_field(spout,h->fv[i]->name, h->fv[i]->type,h->fv[i]->data) != 0){ sp_print_return_status(spfp); return_err(proc_name,200,200, rsprintf("Unable to copy STRING field '%s'", h->fv[i]->name)); } break; case T_INTEGER: l_int=atol(h->fv[i]->data); if (sp_h_set_field(spout,h->fv[i]->name, h->fv[i]->type,&l_int) != 0){ sp_print_return_status(spfp); return_err(proc_name,200,200, rsprintf("Unable to copy INTEGER field '%s'", h->fv[i]->name)); } break; case T_REAL: real=atof(h->fv[i]->data); if (sp_h_set_field(spout,h->fv[i]->name,h->fv[i]->type,&real) != 0){ sp_print_return_status(spfp); return_err(proc_name,200,200, rsprintf("Unable to copy REAL field '%s'", h->fv[i]->name)); } break; } } /* Special Check, if the input file is a pipe and the sample_count */ /* field is missing, (this is legal), AND the output is a disk file */ /* add a dummy sample_count field to the output header */ /* Added June 22, 1994 */ { int type, size, is_disk_file, out_is_disk_file; is_disk_file = (spin->open_mode == SP_mode_read) ? spin->read_spifr->status->is_disk_file : spin->write_spifr->status->is_disk_file; out_is_disk_file = (spout->open_mode == SP_mode_read) ? spout->read_spifr->status->is_disk_file : spout->write_spifr->status->is_disk_file; if (! is_disk_file) if (sp_get_field(h,SAMPLE_COUNT_FIELD,&type,&size) < 0){ /* add the field to the header */ l_int = 999999999; if (sp_h_set_field(spout,SAMPLE_COUNT_FIELD, T_INTEGER,&l_int) != 0){ sp_print_return_status(spfp); return_err(proc_name,400,400, rsprintf("Unable to copy INTEGER field '%s'", h->fv[i]->name)); } } } if (sp_set_default_operations(spout) != 0) return_err(proc_name,300,300, "Unable to set default operations duplicated file"); return_success(proc_name,0,0,"ok"); }
int parse_sample_coding(char *str, int sample_n_bytes, enum SP_sample_encoding *sample_encoding, enum SP_waveform_comp *wav_compress) { int enc_set=FALSE, comp_set=FALSE; char *pstr, *str_mem; char *proc="parse_sample_coding " SPHERE_VERSION_STR; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (str == CNULL) return_err(proc,101,101,"Null coding string"); if (sample_n_bytes < 1 || sample_n_bytes > 2) { /*then we are assuming the field wasn't set yet, so use the default*/ sample_n_bytes = 0; } if (sample_encoding == (enum SP_sample_encoding *)0) return_err(proc,103,103,"Null sample encoding pointer"); if (wav_compress == (enum SP_waveform_comp *)0) return_err(proc,104,104,"Null waveform compress pointer"); *wav_compress = SP_wc_null; *sample_encoding = SP_se_null; if (sp_verbose > 16) fprintf(spfp,"%s: string IS %s\n",proc,str); /* the algorithm to parse the sample encoding field is : */ /* 1: get a token before a ',' or NULL */ /* 2: set a flag to what it matches */ /* 3: move past the token */ /* 4: loop to (1) */ /* make a duplicate copy because strtok is destructive */ str_mem = mtrf_strdup(str); pstr = strtok(str_mem,","); while (pstr != CNULL){ if (sp_verbose > 16) fprintf(spfp,"%s: token found = %s\n",proc,pstr); if (strsame(pstr,"pcm")){ if (enc_set){ mtrf_free(str_mem); return_err(proc,105,105, "Multiple sample encodings in header field"); } if (sample_n_bytes == 1) *sample_encoding = SP_se_pcm1; else *sample_encoding = SP_se_pcm2; enc_set = TRUE; } else if (strsame(pstr,"ulaw") || strsame(pstr,"mu-law")) { if (enc_set){ mtrf_free(str_mem); return_err(proc,105,105, "Multiple sample encodings in header field"); } *sample_encoding = SP_se_ulaw; enc_set = TRUE; } else if (strsame(pstr,"raw")){ if (enc_set){ mtrf_free(str_mem); return_err(proc,105,105, "Multiple sample encodings in header field"); } *sample_encoding = SP_se_raw; enc_set = TRUE; } else if (strstr(pstr,"embedded-shorten-v") != CNULL) { if (comp_set) { mtrf_free(str_mem); return_err(proc,106,106, "Multiple waveform compressions in header field"); } *wav_compress = SP_wc_shorten; comp_set = TRUE; } else if (strstr(pstr,"embedded-wavpack") != CNULL) { if (comp_set){ mtrf_free(str_mem); return_err(proc,106,106, "Multiple waveform compressions in header field"); } *wav_compress = SP_wc_wavpack; comp_set = TRUE; } else if (strstr(pstr,"embedded-shortpack-v") != CNULL) { if (comp_set){ mtrf_free(str_mem); return_err(proc,106,106, "Multiple waveform compressions in header field"); } *wav_compress = SP_wc_shortpack; comp_set = TRUE; } else { mtrf_free(str_mem); return_err(proc,107,107,"Unknown token in sample coding field"); } pstr = strtok(CNULL,","); } if (*wav_compress == SP_wc_null) *wav_compress = SP_wc_none; if (*sample_encoding == SP_se_null) *sample_encoding = SP_se_pcm2; mtrf_free(str_mem); if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"ok"); }
int sp_set_default_operations(SP_FILE *sp) { SP_INTEGER l_int; char *str, *proc="sp_set_default_operations " SPHERE_VERSION_STR; SPIFR *spifr; int ret; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (sp == SPNULL) return_err(proc,100,100,"Null SPFILE pointer"); if ((sp->open_mode == SP_mode_read) || (sp->open_mode == SP_mode_update)) spifr = sp->read_spifr; else if (sp->open_mode == SP_mode_write) spifr = sp->write_spifr; else return_err(proc,100,100,"Unknown File Mode"); /**********************************************************************/ /* The following fields are REQUIRED for Read operations, */ /* NO Exceptions */ if (sp_h_get_field(sp,SAMPLE_COUNT_FIELD,T_INTEGER,(void *)&l_int) != 0){ /* ---------- OLD CODE --------------------- return_err(proc,101,101,rsprintf("Missing '%s' header field", SAMPLE_COUNT_FIELD)); spifr->status->user_sample_count = spifr->status->file_sample_count = (int)l_int;*/ /* added a condition to permit a pipe to NOT have a sample_count */ /* field. ADDED June 22, 1993 */ if (spifr->status->is_disk_file){ return_err(proc,101,101,rsprintf("Missing '%s' header field", SAMPLE_COUNT_FIELD)); } else { /* Sample counts may be missing from piped files */ spifr->status->user_sample_count = spifr->status->file_sample_count = 999999999; } } else spifr->status->user_sample_count = spifr->status->file_sample_count = (int)l_int; if (l_int <= 0) return_err(proc,108,108, rsprintf("Field '%s' value out of range, %d <= 0", SAMPLE_COUNT_FIELD,l_int)); if (sp_h_get_field(sp,SAMPLE_N_BYTES_FIELD, T_INTEGER,(void *)&l_int) != 0) return_err(proc,104,104, rsprintf("Missing '%s' header field", SAMPLE_N_BYTES_FIELD)); spifr->status->user_sample_n_bytes = spifr->status->file_sample_n_bytes = (int)l_int; if (l_int <= 0) return_err(proc,108,108, rsprintf("Field '%s' value out of range, %d <= 0", SAMPLE_N_BYTES_FIELD,l_int)); if (sp_h_get_field(sp,CHANNEL_COUNT_FIELD,T_INTEGER,(void *)&l_int) != 0) return_err(proc,105,105, rsprintf("Missing '%s' header field", CHANNEL_COUNT_FIELD)); spifr->status->user_channel_count = spifr->status->file_channel_count = (int)l_int; if (l_int <= 0) return_err(proc,108,108, rsprintf("Field '%s' value out of range, > 0", CHANNEL_COUNT_FIELD,l_int)); /**********************************************************************/ /* The following fields may exist, if they do not, there is a default */ /***** NOTE: only set the file_sbf, Sp_set_data_mode is called to */ /***** set the user_sbf */ if ((ret=sp_h_get_field(sp,SAMPLE_BF_FIELD,T_STRING,(void *)&str)) != 0){ if ((spifr->status->file_sbf = get_natural_sbf(spifr->status->user_sample_n_bytes)) == SP_sbf_null) return_err(proc,107,107, rsprintf("Unable to read sample sizes of %d bytes", spifr->status->user_sample_n_bytes)); } else { /* str holds the sample_byte_format_value */ ret = parse_sample_byte_format(str,&(spifr->status->file_sbf)); if (ret == 1000) { /* then the file was compressed using change_wav_format */ spifr->status->file_sbf = get_natural_sbf(spifr->status->user_sample_n_bytes); spifr->status->file_compress = SP_wc_shortpack; if ((h_set_field(spifr->header,SAMPLE_BF_FIELD, T_STRING,get_natural_byte_order(2)) != 0) || (h_set_field(spifr->status->file_header,SAMPLE_BF_FIELD, T_STRING,get_natural_byte_order(2)) != 0)){ sp_print_return_status(spfp); mtrf_free(str); return_err(proc,110,110, rsprintf("Unable to re-set sample byte format%s", "field for a shortpacked file")); } if ((h_set_field(spifr->header,SAMPLE_CODING_FIELD,T_STRING, rsprintf("pcm,embedded-%s",str)) != 0) || (h_set_field(spifr->status->file_header,SAMPLE_CODING_FIELD, T_STRING,rsprintf("pcm,embedded-%s",str)) !=0)){ sp_print_return_status(spfp); mtrf_free(str); return_err(proc,111,111, rsprintf("Unable to re-set sample coding field%s", "for a shortpacked file")); } } else if (ret != 0) { /* there really was an error */ mtrf_free(str); return_err(proc,106,106, "Unable to parse the 'sample_byte_format' field"); } mtrf_free(str); } /***** field break *****/ if (sp_h_get_field(sp,SAMPLE_CODING_FIELD,T_STRING,(void *)&str) != 0) if (spifr->status->user_sample_n_bytes == 1) str = mtrf_strdup("ulaw"); else /* the default, since old Corpora are missing this field */ str = mtrf_strdup("pcm"); if (parse_sample_coding(str,spifr->status->file_sample_n_bytes, &(spifr->status->file_encoding), &(spifr->status->file_compress)) != 0){ mtrf_free(str); print_return_status(spfp); return_err(proc,107,107, rsprintf("Unable to parse sample_coding value '%s' header field", str)); } mtrf_free(str); /*********************************************************************/ /* The following fields are conditionally required. */ ret = sp_h_get_field(sp,SAMPLE_RATE_FIELD,T_INTEGER,(void *)&l_int); switch (spifr->status->file_encoding) { case SP_se_pcm1: case SP_se_pcm2: case SP_se_ulaw: if (ret != 0) return_err(proc,102,102, rsprintf("Header field '%s' missing, but required%s", SAMPLE_RATE_FIELD," for waveform data")); spifr->status->user_sample_rate = spifr->status->file_sample_rate = (int)l_int; break; case SP_se_raw: default: spifr->status->user_sample_rate = spifr->status->file_sample_rate =0; } /***********************************************************************/ /* The following fields are OPTIONAL, but if they exist, there is a */ /* special purpose for them */ if (sp_h_get_field(sp,SAMPLE_CHECKSUM_FIELD,T_INTEGER,(void *)&l_int)==0) spifr->status->file_checksum = l_int; else { spifr->status->ignore_checksum = TRUE; } /*********************/ /* Consitency checks */ /*********************/ if (spifr->status->file_encoding == SP_se_ulaw && spifr->status->file_sample_n_bytes != 1) return_err(proc,120,120, rsprintf("Ulaw encoding requires a 1 byte sample,%s %d", " however the header value is", spifr->status->file_sample_n_bytes)); if (spifr->status->file_encoding == SP_se_pcm1 && spifr->status->file_sample_n_bytes != 1) return_err(proc,120,120, rsprintf("PCM1 encoding requires a 1 byte sample, %s %d", "however the header value is", spifr->status->file_sample_n_bytes)); if (spifr->status->file_encoding == SP_se_pcm1 && spifr->status->file_sample_n_bytes != 2) return_err(proc,120,120, rsprintf("PCM2 encoding requires a 2 byte sample, %s %d", "however the header value is", spifr->status->file_sample_n_bytes)); /********************************/ /* set up the default decodings */ if (sp->open_mode == SP_mode_read) if (sp_set_data_mode(sp,"") != 0){ print_return_status(spfp); return_err(proc,110,110, rsprintf("Unable to set up default encodings %s", "on file opened for read")); } else if (sp->open_mode == SP_mode_update) if (sp_set_data_mode(sp,"SE_ORIG:SBF_ORIG") != 0){ print_return_status(spfp); return_err(proc,111,111, "Unable to set up default encodings on file opened for update"); } if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"ok"); }
/* * sp_open * */ SP_FILE *sp_open(char *filename, char *mode) { SP_FILE *tsp; char *errmsg, *proc="sp_open " SPHERE_VERSION_STR, *fopen_mode; enum SP_file_open_mode current_mode; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (filename == CNULL) return_err(proc,101,SPNULL,"Null filename string"); if (mode == CNULL) return_err(proc,101,SPNULL,"Null file mode string"); if (sp_verbose > 10) fprintf(spfp,"Proc %s: file '%s' mode '%s'\n", proc,filename,mode); if ((tsp=sp_alloc_and_init_sphere_t()) == SPNULL) return_err(proc,102,SPNULL,"Unable to malloc SPFILE memory"); /* set the file open mode in the status structure */ if (strsame(mode,"r")) current_mode = tsp->open_mode = SP_mode_read; else if (strsame(mode,"w")) current_mode = tsp->open_mode = SP_mode_write; else if (strsame(mode,"rv")){ current_mode = tsp->open_mode = SP_mode_read; tsp->read_spifr->status->extra_checksum_verify = TRUE; } else if (strsame(mode,"wv")) { current_mode = tsp->open_mode = SP_mode_write; tsp->write_spifr->status->extra_checksum_verify = TRUE; } else if (strsame(mode,"u")) { tsp->open_mode = SP_mode_read; current_mode = SP_mode_update; } else { free_sphere_t(tsp); return_err(proc,103,SPNULL, rsprintf("Illegal SPFILE open mode '%s'",mode)); } /* just open the file, either for reading or writing. If the */ /* mode was SP_mode_writing, and the file exists, change the mode */ /* to SP_mode_update. */ switch (tsp->open_mode) { case (SP_mode_read): { if (! strsame(filename,"-")) { fopen_mode = (current_mode == SP_mode_read) ? READMODE : UPDATEMODE; if ((tsp->read_spifr->waveform->sp_fp = fopen(filename,fopen_mode)) == (FILE *)0){ free_sphere_t(tsp); return_err(proc,111,SPNULL, rsprintf("%s'%s' for reading fopen mode %s", "Unable to open SPHERE file ", filename,fopen_mode)); } tsp->read_spifr->status->is_disk_file = TRUE; } else { tsp->read_spifr->waveform->sp_fp = stdin; tsp->read_spifr->status->is_disk_file = FALSE; } tsp->read_spifr->status->external_filename = mtrf_strdup(filename); break; } case (SP_mode_write):{ if (! strsame(filename,"-")) { /* open the file, truncating if the file exists */ fopen_mode = (current_mode == SP_mode_write) ? WRITEMODE : UPDATEMODE; if ((tsp->write_spifr->waveform->sp_fp = fopen(filename,fopen_mode)) == (FILE *)0){ free_sphere_t(tsp); return_err(proc,105,SPNULL, rsprintf("Unable to open SPHERE file '%s' for %s %s", filename,"writing, fopen mode",fopen_mode)); } tsp->write_spifr->status->is_disk_file = TRUE; } else { tsp->write_spifr->waveform->sp_fp = stdout; tsp->write_spifr->status->is_disk_file = FALSE; } tsp->write_spifr->status->external_filename = mtrf_strdup(filename); break; } default: { return_err(proc,200,SPNULL,"Internal error"); } } /* now that the file is opened, load the header if it exist, */ /* otherwise alloc an empty header for the user */ switch (tsp->open_mode) { case (SP_mode_read): { /* read the header */ tsp->read_spifr->header = sp_open_header(tsp->read_spifr->waveform->sp_fp,TRUE,&errmsg); if ( tsp->read_spifr->header == HDRNULL ) { free_sphere_t(tsp); return_err(proc,104,SPNULL, rsprintf("Unable to open SPHERE header of file '%s', %s", filename,errmsg)); } /* get the size of the header */ if (! strsame(filename,"-")) { if ((tsp->read_spifr->waveform->header_data_size = sp_file_header_size(filename)) < 0){ free_sphere_t(tsp); return_err(proc,110,SPNULL, rsprintf("Unable to get SPHERE header size of file '%s'", filename)); } } else { if ((tsp->read_spifr->waveform->header_data_size = sp_header_size(tsp->read_spifr->header)) < 0){ free_sphere_t(tsp); return_err(proc,111,SPNULL, rsprintf("Unable to get SPHERE header size of file '%s'", filename)); } } /****** Remove the sample_count field if it's ******/ /****** value is 999999999 and the file is a stream ******/ /****** Added by JGF June 22, 1994 ******/ if (! tsp->read_spifr->status->is_disk_file){ int type, size; SP_INTEGER l_int; if (sp_get_field(tsp->read_spifr->header, SAMPLE_COUNT_FIELD,&type,&size) == 0){ if (sp_get_data(tsp->read_spifr->header,SAMPLE_COUNT_FIELD, (char *)&l_int,&size) == 0){ if (l_int == 999999999){ if (sp_verbose > 10) fprintf(spfp, "Proc %s: file '%s' deleting %s field\n", proc,filename,SAMPLE_COUNT_FIELD); if (sp_delete_field(tsp->read_spifr->header, SAMPLE_COUNT_FIELD) < 0) return_err(proc,112,SPNULL, rsprintf("Unable to delete fake '%s' field", SAMPLE_COUNT_FIELD)); } } } } /****** Correct any out-of-date headers right NOW ******/ if (correct_out_of_date_headers(tsp) != 0){ fprintf(spfp,"Warning: correction of "); fprintf(spfp,"out-of-date headers failed\n"); sp_print_return_status(spfp); } /* duplicate the header for the file interface */ if ((tsp->read_spifr->status->file_header = sp_dup_header(tsp->read_spifr->header)) == HDRNULL){ fprintf(spfp,"Error: sp_open_header unable "); fprintf(spfp,"to dup header for file '%s'\n",filename); free_sphere_t(tsp); return_err(proc,106,SPNULL, rsprintf("Unable to duplicate the SPHERE header of file", filename)); } /* set the default operation settings */ if (sp_set_default_operations(tsp) != 0){ print_return_status(spfp); return_err(proc,107,SPNULL, rsprintf("Unable to interpret the SPHERE header of file '%s'", filename)); } break; } case (SP_mode_write):{ tsp->write_spifr->header = sp_create_header(); if ( tsp->write_spifr->header == HDRNULL ) { free_sphere_t(tsp); return_err(proc,108,SPNULL, rsprintf("Unable to allocate SPHERE header for file '%s'", filename)); } tsp->write_spifr->status->file_header = sp_create_header(); if ( tsp->write_spifr->status->file_header == HDRNULL ) { free_sphere_t(tsp); return_err(proc,109,SPNULL, rsprintf("Unable to allocate hidden SPHE. header for file '%s'", filename)); } } default: ; } /* the file was actually opened for update, so make a temp file, and */ /* duplicate the read in file. */ if (current_mode == SP_mode_update){ SP_FILE *tsp2; SPIFR *tspifr; char *temp_file; char data_mode[100]; temp_file = sptemp(tsp->read_spifr->status->external_filename); if (temp_file == CNULL) return_err(proc,300,SPNULL,"Unable to create temporary filename"); if ((tsp2 = sp_open(temp_file,WRITEMODE)) == SPNULL) { free_sphere_t(tsp); mtrf_free(temp_file); return_err(proc,301,SPNULL, rsprintf("Unable to open temporary file",temp_file)); } sp_set_data_mode(tsp,"SE-ORIG:SBF-ORIG"); /* now copy the header into the update file */ if (sp_copy_header(tsp,tsp2) != 0){ free_sphere_t(tsp); free_sphere_t(tsp2); unlink(temp_file); mtrf_free(temp_file); return_err(proc,302,SPNULL,"Unable to duplicate output header"); } *data_mode = '\0'; /*now set the data mode to match the output format of the read file*/ switch (tsp->read_spifr->status->file_compress){ case SP_wc_shorten: strcat(data_mode,"SE-SHORTEN:"); break; case SP_wc_wavpack: strcat(data_mode,"SE-WAVPACK:"); break; case SP_wc_shortpack: strcat(data_mode,"SE-SHORTPACK:"); break; default: ; } switch (tsp->read_spifr->status->file_sbf){ case SP_sbf_01: strcat(data_mode,"SBF-01"); break; case SP_sbf_10: strcat(data_mode,"SBF-10"); break; case SP_sbf_1: strcat(data_mode,"SBF-1"); break; case SP_sbf_N: strcat(data_mode,"SBF-N"); break; default: ; } if (sp_set_data_mode(tsp2,data_mode) >= 100){ free_sphere_t(tsp); free_sphere_t(tsp2); unlink(temp_file); mtrf_free(temp_file); return_err(proc,303,SPNULL, rsprintf("Unable to set_data_mode '%s' for update file", data_mode)); } /* now merge the two SPFILE pointers into a single structure */ /* and free the residual */ tspifr = tsp->write_spifr; tsp->write_spifr = tsp2->write_spifr; tsp2->write_spifr = tspifr; free_sphere_t(tsp2); mtrf_free(temp_file); tsp->open_mode = current_mode; } /* sp_file_dump(tsp,spfp);*/ if (sp_verbose > 17) sp_file_dump(tsp,spfp); if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning Sphere-file pointer\n",proc); return_success(proc,0,tsp,"ok"); }
int sp_close(SP_FILE *sp) { char *proc="sp_close " SPHERE_VERSION_STR; char *write_name; char *read_name; SP_INTEGER lint=0, header_size=0, data_size=0; int header_changed=FALSE; SPIFR *spifr; SPSTATUS *w_spstat, *r_spstat; int ret, verify_checksum=FALSE; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (sp == SPNULL) return_err(proc,100,100,"Null SPFILE pointer"); w_spstat = sp->write_spifr->status; r_spstat = sp->read_spifr->status; write_name = (w_spstat->external_filename == CNULL) ? CNULL : mtrf_strdup(sp->write_spifr->status->external_filename); read_name = (r_spstat->external_filename == CNULL) ? CNULL : mtrf_strdup(r_spstat->external_filename); if (sp->open_mode == SP_mode_update) { if (sp_verbose > 10) fprintf(spfp,"Proc %s: Mode SP_update\n",proc); if (w_spstat->write_occured_flag) { /* if there has been a spwrite, then the waveform is written */ /* as if it were a file opened for write */ /* Step 1: recursively call sp_close, changing the mode to write */ /* Step 2: delete the previous file */ /* Step 3: rename the temporary file */ if (sp_verbose > 15) fprintf(spfp,"Proc %s: Overwriting the original waveform\n", proc); sp->open_mode = SP_mode_write; if ((ret=sp_close(sp)) != 0){ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_child(proc,int,ret); } unlink(read_name); rename(write_name,read_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } else { /* the header has been changed and the data mode of the waveform */ /* COULD BE CHANGED the waveform has not been modified in any */ /* way, only the header has changed */ /* Step 1: write the header into the temporary file */ /* Step 2: If the header changed in size OR the waveform */ /* format has changed */ /* A: copy the waveform into the temp file */ /* B: close the files */ /* C: delete the old file in favor of the new file */ /* Else the header has not changed in size. */ /* A: write the header into the original file */ /* B: Close both files */ /* C: delete the temporary file */ FILE *fp; int samples_read, samples_written; /* Step 1: */ spifr = sp->write_spifr; fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (sp_verbose > 15) fprintf(spfp, "Proc %s: Writing header to temp file. position %d\n", proc,ftell(fp)); if (fp == FPNULL){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3000,3000,"Internal Error"); } /* Write the header into the temporary file to compute the size */ /* of the header and then rewind back over the just written header*/ rewind(fp); if (sp_write_header(fp,spifr->status->file_header, &header_size,&data_size) < 0){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3001,3001, "Unable to update header in file"); } rewind(fp); /* Step 2 - - if the header size or waveform has changed */ if ((sp->read_spifr->waveform->header_data_size != header_size) || (w_spstat->file_encoding != r_spstat->file_encoding) || (w_spstat->file_compress != r_spstat->file_compress) || (w_spstat->file_sbf != r_spstat->file_sbf) || (w_spstat->channels != CHANNELSNULL)){ char *buff; int ns, nc, in_nspb, out_nspb; if (sp_verbose > 15) { fprintf(spfp,"Proc %s: output header and/or",proc); fprintf(spfp,"data has changed, copying file.\n"); fprintf(spfp,"Proc %s: from %d to %d\n",proc, sp->read_spifr->waveform->header_data_size, header_size); } ns = r_spstat->user_sample_count; nc = r_spstat->user_channel_count; in_nspb = r_spstat->user_sample_n_bytes * r_spstat->user_channel_count; out_nspb = w_spstat->user_sample_n_bytes * w_spstat->user_channel_count; if ((buff=mtrf_malloc(nc * in_nspb * 4096)) == CNULL) { free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3010,3010, "Unable to malloc transfer buffer space"); } /* A: */ do { sp->open_mode = SP_mode_read; samples_read = sp_read_data(buff,4096,sp); if (samples_read > 0) { sp->open_mode = SP_mode_write; samples_written = sp_write_data(buff,samples_read,sp); if (samples_written != samples_read){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3012,3012, "Copy of waveform data failed"); } } else { if (sp_eof(sp) == 0) { free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3013,3013, "Error: Zero samples read while not at EOF"); } if (sp_error(sp) >= 100) { /* a checksum error occured, close the sp and */ /* delete the temp file */ sp->open_mode = SP_mode_update; sp_print_return_status(spfp); free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); mtrf_free(buff); return_err(proc,3011,3011, "Error copying waveform data"); } } sp->open_mode = SP_mode_update; } while (samples_read > 0); mtrf_free(buff); /* make sure the file is at eof (as if it were opened for */ /* read) */ sp->open_mode = SP_mode_read; if (! sp_eof(sp)){ sp->open_mode = SP_mode_update; free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3012,3012,"Error copying waveform data"); } sp->open_mode = SP_mode_write; if ((ret=sp_close(sp)) != 0){ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_child(proc,int,ret); } /* C: */ unlink(read_name); rename(write_name,read_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } else { /* A: */ spifr = sp->read_spifr; fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (fp == FPNULL) return_err(proc,3002,3002,"Internal Error"); rewind(fp); if (sp_verbose > 15) fprintf(spfp, "Proc %s: header size not changed. position %d\n", proc,ftell(fp)); if (sp_write_header(fp,w_spstat->file_header, &header_size,&data_size) < 0){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3003,3003, "Unable to update header in file"); } /* B: */ free_sphere_t(sp); /* C: */ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } } } /* END of update mode file */ if (sp->open_mode == SP_mode_write) { if (sp_verbose > 10) fprintf(spfp, "Proc %s: Mode SP_mode_write\n",proc); spifr = sp->write_spifr; /* flush the data to the file */ if (spifr->status->is_disk_file) fob_fflush(spifr->waveform->sp_fob); /* if the mode is write, update the sample_count and checksum */ /* field if needed. If the checksum field exists, verify it, */ /* and warn if it's not the same */ /************ ONLY UPDATE FIELDS IF THE FILE IS NOT A STREAM *********/ if (spifr->status->is_disk_file){ h_get_field(w_spstat->file_header, SAMPLE_COUNT_FIELD, T_INTEGER, (void *)&lint); if (spifr->waveform->samples_written != lint) { /* then update the field */ lint = (SP_INTEGER) spifr->waveform->samples_written; spifr->status->file_sample_count = lint; /* temporarily reset the write occured flag to allow header */ /* modifications */ w_spstat->write_occured_flag = FALSE; if (sp_h_set_field(sp,SAMPLE_COUNT_FIELD,T_INTEGER,&lint) !=0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,200,200,"Unable to update sample_count"); } /* Reset the write occured flag */ w_spstat->write_occured_flag = TRUE; header_changed = TRUE; } if (h_get_field(spifr->status->file_header,SAMPLE_CHECKSUM_FIELD, T_INTEGER,(void *)&lint) != 0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,201,201, "Unable to get sample_checksum for file on disk"); } if (lint != spifr->status->file_checksum) { /* then the checksum was just computed, so install it */ lint = (SP_INTEGER)spifr->waveform->checksum; /* temporarily reset the write occured flag to allow header */ /* modifications */ w_spstat->write_occured_flag = FALSE; if (sp_h_set_field(sp,SAMPLE_CHECKSUM_FIELD, T_INTEGER,&lint) >= 100){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,202,202,"Unable to update checksum"); } /* Reset the write occured flag */ w_spstat->write_occured_flag = TRUE; header_changed = TRUE; } else if (lint != spifr->waveform->checksum) { spifr->waveform->failed_checksum = TRUE; if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,203,203, rsprintf("Write verification of checksum failed on file %s", spifr->status->external_filename)); } } /* flush the updated header to the file */ if (header_changed) { FILE *fp; if (! spifr->status->is_disk_file) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,301,301, "Internal Error, header changed size on write to stdout"); } fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (fp == FPNULL) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,300,300,"Internal Error"); } rewind(fp); if (sp_write_header(fp,spifr->status->file_header, &header_size,&data_size) < 0) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,204,204,"Unable to update header in file"); } } if ((spifr->status->is_temp_file == FALSE) && fob_is_fp(spifr->waveform->sp_fob)) { /* check to make sure the blocking has not changed */ if (header_changed) if (((data_size + PAD_MULT) / PAD_MULT) != ((spifr->waveform->header_data_size + PAD_MULT) /PAD_MULT)){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,205,205, "Header size has changed on update"); } } else { if (spifr->status->user_compress == spifr->status->file_compress){ if (fob_flush_to_fp(spifr->waveform->sp_fob, spifr->waveform->sp_fp) != 0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,206,206,"Unable to flush data to disk"); } } else { /* do some compression */ FOB *comp_fob; /* 1. rewind the data */ /* 2. alloc FOB to compress into */ /* 3. compress the file */ /* 4. free the allocated FOB */ fob_rewind(spifr->waveform->sp_fob); if ((comp_fob = fob_create(spifr->waveform->sp_fp)) == FOBPNULL) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,207,207,"Unable to setup for compression"); } spifr->waveform->sp_fp = FPNULL; switch (spifr->status->file_compress){ char message[70]; case SP_wc_shorten: /* optimize the compression */ shorten_set_channel_count(spifr->status->file_channel_count); if (spifr->status->file_encoding == SP_se_ulaw) shorten_set_ftype("au"); else if (spifr->status->file_encoding == SP_se_pcm1) shorten_set_ftype("s8"); else if (spifr->status->file_encoding == SP_se_pcm2) if (spifr->status->file_sbf == SP_sbf_01) shorten_set_ftype("s16lh"); else shorten_set_ftype("s16hl"); if (sp_verbose > 15) shorten_dump_flags(spfp); if(setjmp(exitenv) == 0){ if (shorten_compress(spifr->waveform->sp_fob, comp_fob, message) < 0){ fob_destroy(comp_fob); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,208,208, rsprintf("Shorten Compression Failed - %s", message)); } } else return_err(proc,213,0,"Shorten Compression Aborted"); fob_fflush(comp_fob); break; case SP_wc_wavpack: if(setjmp(exitenv) == 0){ /* optimize the compression */ wavpack_set_progname( "wavpack" ); if (spifr->status->file_channel_count == 1) wavpack_set_monoflg(TRUE); else wavpack_set_monoflg(FALSE); wavpack_set_byteflg(spifr->status->file_sbf ==SP_sbf_1); if (sp_verbose > 15) wavpack_dump_interface(spfp); if (wavpack_pack(spifr->waveform->sp_fob, comp_fob)<0){ fob_destroy(comp_fob); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,209,209, "Wavpack Compression Failed"); } wavpack_free_progname(); fob_fflush(comp_fob); } else { return_err(proc,212,0,"Wavpack Compression Aborted"); } break; case SP_wc_shortpack: return_err(proc,211,211, "Unable to Compress using shortpack\n"); default: if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,210,210, "Unable to Compress the requested format\n"); } spifr->waveform->sp_fp = comp_fob->fp; fob_destroy(comp_fob); } } if ((sp->open_mode == SP_mode_write) || (sp->open_mode == SP_mode_update)) if (w_spstat->extra_checksum_verify) verify_checksum = TRUE; } free_sphere_t(sp); /*************************************************/ /* The file is now completely written and closed */ /*************************************************/ /**************************************************/ /* If the write verification is requested, do it */ if (verify_checksum) { if (strsame(write_name,"-")) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_warn(proc,1,1, "Unable to verify checksum, file went to STDOUT"); } if (verify_file_checksum(write_name) != 0){ sp_print_return_status(spfp); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,1000,1000, "Read Verification of written file failed"); } } if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); }
bool s4pp_on_recv (s4pp_ctx_t *ctx, char *data, uint16_t len) { ctx->err = S4PP_OK; // clear earlier errors if (!len) // remote side disconnected { if (ctx->conn) ctx->io->disconnect (ctx->conn); // free the conn ctx->conn = NULL; if (ctx->state == S4PP_BUFFERING || ctx->state == S4PP_COMMITTING) { ctx->err = S4PP_SEQUENCE_NOT_COMMITTED; invoke_done (ctx, false); return_res; } else return_ok; } char *nl = memchr (data, '\n', len); // deal with joining with previous chunk if (ctx->inbuf.len) { char *end = nl ? nl : data + len - 1; unsigned dlen = (end - data); unsigned newlen = ctx->inbuf.len + dlen; ctx->inbuf.bytes = realloc (ctx->inbuf.bytes, newlen); if (!ctx->inbuf.bytes) { ctx->inbuf.len = 0; ctx->state = S4PP_ERRORED; // we just lost bytes, can't recover return_err (S4PP_NO_MEMORY); } memmove (ctx->inbuf.bytes + ctx->inbuf.len, data, dlen); ctx->inbuf.len += dlen; data += dlen; len -= dlen; if (!handle_line (ctx, ctx->inbuf.bytes, ctx->inbuf.len)) return_res; else { free (ctx->inbuf.bytes); ctx->inbuf.bytes = NULL; ctx->inbuf.len = 0; nl = memchr (data, '\n', len); } } // handle full lines inside 'data' while (nl) { unsigned dlen = (nl - data) + 1; if (!handle_line (ctx, data, dlen)) return_res; data += dlen; len -= dlen; nl = memchr (data, '\n', len); } // deal with left-over pieces if (len) { ctx->inbuf.bytes = malloc (len); if (!ctx->inbuf.bytes) // we just lost bytes, can't recover { ctx->state = S4PP_ERRORED; return_err (S4PP_NO_MEMORY); } else ctx->inbuf.len = len; } return_res; }