spread.c

来自「speech signal process tools」· C语言 代码 · 共 1,151 行 · 第 1/3 页

C
1,151
字号
#include <stdio.h>#include <sp/sphere.h>#include <sp/ulaw.h>#include <sp/alaw.h>#include <sp/shorten/shorten.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;    /* dissallow reads if the file is still compressed. J.Thompson */    if (spifr->status->user_compress != SP_wc_none)  	return_err(proc,110,110,"Unable to Read file in compressed mode");     if (sp_verbose > 10)        fprintf(spfp,	       "Proc %s: file %s, %d bytes/sample, %d channels, %ld 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->waveform->waveform_setup){	    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;	    }	    spifr->waveform->waveform_setup = TRUE;	}	    	/****************************************************/	/**            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);	    else		fob_read_byte_natural(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;	    if (((spifr->status->file_encoding == SP_se_pculaw) &&		 (spifr->status->user_encoding == SP_se_pcm2)) || 		((spifr->status->file_encoding == SP_se_pcm2) &&		 (spifr->status->user_encoding == SP_se_pculaw))) 		do_conversions = TRUE;	    if (((spifr->status->file_encoding == SP_se_alaw) &&		 (spifr->status->user_encoding == SP_se_pcm2)) || 		((spifr->status->file_encoding == SP_se_pcm2) &&		 (spifr->status->user_encoding == SP_se_alaw))) 		do_conversions = TRUE;	    if (do_conversions == FALSE)		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()));	} else {	    /* ONLY Pre-verify the waveform once, subsequent rewind operations */	    /* should not have to do this */	    spifr->status->extra_checksum_verify = FALSE;	}    }    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 called_by_waves = 0;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;    unsigned char *pculaw_data = (unsigned char *)0;    unsigned char *alaw_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 %ld\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 (!called_by_waves && 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);

⌨️ 快捷键说明

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