📄 spread.c
字号:
#include <stdio.h>#include <sp/sphere.h>#include <sp/ulaw.h>#include <string.h>#include <setjmp.h>extern jmp_buf exitenv;static int fob_short_checksum(FOB *f, SP_CHECKSUM *checksum, int do_byte_swap, SP_CHECKSUM (*add_checksum) (SP_CHECKSUM,SP_CHECKSUM));static int fob_char_checksum(FOB *, SP_CHECKSUM *, SP_CHECKSUM (*add_checksum) (SP_CHECKSUM , SP_CHECKSUM ));static int decompress_waveform(SP_FILE *);static int pre_verify_checksum(SP_FILE *);static int read_data_in(void *, size_t, SP_FILE *);/* * * 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");}int in_entropic = 0; /* set if in Entropic software */ /* if set, then check for early eof not done */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 (!in_entropic && 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -