spwrite.c

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

C
827
字号
	    break;	  default: {	      int n;	      n =  out_samples * spstat->file_channel_count *		  spstat->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(out_block,n);	      spwav->checksum = 		  sp_add_checksum(spwav->checksum,checksum);	      spwav->samples_written += ret;	  }	}		if (sp_verbose > 11) 	    fprintf(spfp,"Proc %s: Block %d: Requested %ld samples, written %d total %d, Checksum %d (BC %d)\n",		    proc,block++,num_sample,ret,		    spwav->samples_written,		    checksum,spwav->checksum);    }    return_success(proc,0,samples_written,"ok");}static int spw_file_init(SP_FILE *sp, char *call_proc){    char proc[40], *str;    SP_INTEGER l_int, h_size;    int ret;    SPIFR *spifr;     SPSTATUS *spstat;     SPWAVEFORM *spwav;    sprintf(proc,"%s:%s",call_proc,"spw_file_init");    spifr = sp->write_spifr;    spstat = spifr->status;    spwav = spifr->waveform;    /******************************************************/    /*             Check for required fields              */        if (sp_verbose > 15) fprintf(spfp,"Proc %s: initializing FOB\n",proc);        /* the sample_n_bytes is required, if it is not set, there is an    */    /* error */    if (h_get_field(spstat->file_header,		    SAMPLE_N_BYTES_FIELD, T_INTEGER, (void *)&l_int) != 0)	return_err(proc,150,100,		   rsprintf("Header field '%s' is missing",			    SAMPLE_N_BYTES_FIELD));        /* if 'channel_count' is not in the header, there is an error */    if (h_get_field(spstat->file_header,		    CHANNEL_COUNT_FIELD, T_INTEGER, (void *)&l_int) != 0)	return_err(proc,151,100,		   rsprintf("Header field '%s' is missing",			    CHANNEL_COUNT_FIELD));        /*   This constraint was relaxed to allow for streams to not */    /*   have a sample_count field.  Added June 22, 1994, JGF    */    /* if (! spstat->is_disk_file)        if (h_get_field(spstat->file_header,       SAMPLE_COUNT_FIELD, T_INTEGER, (void *)&l_int) !=0)       return_err(proc,151,100,       rsprintf("Header field '%s' is missing%s",       SAMPLE_COUNT_FIELD," for stream file"));*/        /* if the sample coding field is not 'raw' the sample_rate fielda   */    /* must exist if the field is missing, it is assumed to be a pcm file*/    ret=h_get_field(spstat->file_header,		    SAMPLE_CODING_FIELD, T_STRING, (void *)&str);    if (((ret == 0) && (!strsame(str,"raw"))) || (ret != 0))	if (h_get_field(spstat->file_header,			SAMPLE_RATE_FIELD, T_INTEGER, (void *)&l_int) !=0){	    if (ret == 0) mtrf_free(str);	    return_err(proc,151,100,		       rsprintf("Header field '%s' is missing %s",				SAMPLE_RATE_FIELD,"from wave type file"));	}    if (ret == 0) mtrf_free(str);        /* if the following fields are missing from the header, default      */    /* values need to be assumed in the SP_FILE status structure         */    if (h_get_field(spstat->file_header,		    SAMPLE_BF_FIELD, T_STRING, (void *)&str) == 0)	mtrf_free(str);    else {	spstat->user_sbf =	    spstat->file_sbf =		get_natural_sbf(spstat->file_sample_n_bytes);    }            /* only add data to the header if the file is not a stream */    if (spstat->is_disk_file) {	/* if 'sample_count' is not in the header, add it to take up    */	/* space for later correction                                   */	if (h_get_field(spstat->file_header, 			SAMPLE_COUNT_FIELD, T_INTEGER, (void *)&l_int)!=0){	    l_int=(-1);	    	    spstat->file_sample_count=l_int;	    sp_h_set_field(sp, SAMPLE_COUNT_FIELD, T_INTEGER, &l_int);	}		/* if 'sample_checksum' is not in the header, add it with a fake */	/* checksum */	if (h_get_field(spstat->file_header,SAMPLE_CHECKSUM_FIELD,			T_INTEGER,(void *)&l_int)!=0){	    l_int=999999999;	    spstat->file_checksum=l_int;	    sp_h_set_field(sp, SAMPLE_CHECKSUM_FIELD, T_INTEGER, &l_int);	}    }        /* bug fixed JGF 060496, make sure the header size is saved */    /* Flush the header to the file pointer */    if (sp_write_header(spwav->sp_fp, spstat->file_header,			&(spwav->header_data_size),			&h_size) < 0)	return_err(proc,200,100,"Unable to write header to file");        if ((spstat->user_compress == SP_wc_none) &&	(spstat->file_compress != SP_wc_none)){	char *buff;	int blen;		/* The file needs to be written into a temporary place, and then */	/* compressed.  If The expected waveform size is bigger that     */	/* MAX_INTERNAL_WAVEFORM, use a temporary file. otherwise:       */	/* 1. make an MEMORY FOB struct for the uncompressed file.       */	/* 2. allocate the memory for the FOB struct,                    */	/* 3. install the memory into the FOB struct                     */		if (spstat->file_sample_count < 0)	    /* allocate a minimal size for the waveform */	    blen = MAX_INTERNAL_WAVFORM;	else	    blen = spstat->file_channel_count *spstat->file_sample_count * 		spstat->file_sample_n_bytes;		if (blen < MAX_INTERNAL_WAVFORM){	    if ((spwav->sp_fob = 		 fob_create(FPNULL)) == FOBPNULL)		return_err(proc,300,100,			   "Unable to allocate a FOB structure");	    if ((buff = mtrf_malloc(blen)) == CNULL){		fob_destroy(spwav->sp_fob);		return_err(proc,301,100,			   "Unable to malloc buffer for waveform data");	    }	    fob_bufinit(spwav->sp_fob, buff, blen);	} else {	    FILE *temp_fp;	    spstat->temp_filename = sptemp_dirfile();	    if (spstat->temp_filename == CNULL)		return_err(proc,301,100,			   "Unable to create usable temporary file");	    if (sp_verbose > 15)		fprintf(spfp,			"Proc %s: Attempting to write a big file %d%s%s\n",			proc,blen," bytes long, using temp file ",			spstat->temp_filename);	    if ((temp_fp=fopen(spstat->temp_filename,			       TRUNCATE_UPDATEMODE)) == FPNULL) 		return_err(proc,302,100,			   rsprintf("Unable to open temporary file %s",				    spstat->temp_filename));	    if ((spwav->sp_fob = fob_create(temp_fp)) == FOBPNULL)		return_err(proc,303,100,			   "Unable to allocate a FOB structure");	    spstat->is_temp_file = TRUE;	}    }    else {	/* This assumes that no pre-buffering is required */	/*	    fprintf(spfp,"Setting up for un-buffered IO \n");*/	if ((spwav->sp_fob = fob_create(spwav->sp_fp)) == FOBPNULL)	    return_err(proc,300,100,		       "Unable to allocate a FOB structure");	spwav->sp_fp = FPNULL;    }    /* allocate a translation buffer for the sample encodings */    if (spstat->user_encoding != spstat->file_encoding) {	if (((spstat->user_encoding == SP_se_ulaw ||	      spstat->user_encoding == SP_se_pculaw ||	      spstat->user_encoding == SP_se_alaw) &&	     (spstat->file_encoding == SP_se_pcm2)) ||	    ((spstat->user_encoding == SP_se_pcm2) &&	     (spstat->file_encoding == SP_se_ulaw || 	      spstat->file_encoding == SP_se_pculaw || 	      spstat->file_encoding == SP_se_alaw))) {	    	    /* allocate the memory for the translation buffer */	    /*  IF it's a legal transformation                */	    spwav->converted_buffer_len = TRANSLATION_LEN *		spstat->file_sample_n_bytes *		    spstat->user_channel_count;	    if (sp_verbose > 15)		fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes for%s\n",			proc, spwav->converted_buffer_len,			TRANSLATION_LEN, spstat->file_sample_n_bytes,			spstat->user_channel_count, " encoding buffer");	    if ((spwav->converted_buffer = 		 (void *)mtrf_malloc(spwav->converted_buffer_len)) ==		(void *)0)		return_err(proc,500,100,			   "Unable to alloc memory for the encoding buffer");	    	} else {	    return_err(proc,400,100,		       "Unable to convert sample types ... for now\n");	}    }    /* allocate a buffer for the channel conversions */    if (spstat->channels != CHANNELSNULL){	/* allocate the memory for the translation buffer */	spwav->file_data_buffer_len = TRANSLATION_LEN *	    spstat->file_sample_n_bytes * spstat->file_channel_count;	if (sp_verbose > 15)	    fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes for%s\n",		    proc, spwav->file_data_buffer_len,		    TRANSLATION_LEN, spstat->file_sample_n_bytes,		    spstat->file_channel_count, " channel mod buffer");	if ((spwav->file_data_buffer = 	     (void *)mtrf_malloc(spwav->file_data_buffer_len)) ==(void *)0)	    return_err(proc,501,100,		       "Unable to alloc memory for the channel mod buffer");    }    /* allocate a buffer for the interleaved version of incomming data */    if (spstat->user_data_fmt == SP_df_array){	/* allocate the memory for the interleaved buffer */	spwav->interleave_buffer_len = TRANSLATION_LEN *	    spstat->user_sample_n_bytes * spstat->user_channel_count;	if (sp_verbose > 15)	    fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes for%s\n",		    proc, spwav->interleave_buffer_len,		    TRANSLATION_LEN, spstat->user_sample_n_bytes,		    spstat->user_channel_count, " interleave buffer");	if ((spwav->interleave_buffer = 	     (void *)mtrf_malloc(spwav->interleave_buffer_len)) ==(void *)0)	    return_err(proc,501,100,		       "Unable to alloc memory for the interleave buffer");    }    /* allocate a buffer for byte swapping pcm data */    if (((spstat->user_encoding == SP_se_pcm2) &&	 (spstat->file_encoding == SP_se_pcm2)) &&	(spstat->user_sbf != spstat->file_sbf)){	/* allocate the memory for the byte swapping buffer */	spwav->byteswap_buffer_len = TRANSLATION_LEN *	    spstat->user_sample_n_bytes * spstat->user_channel_count;	if (sp_verbose > 15)	    fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes for%s\n",		    proc, spwav->byteswap_buffer_len,		    TRANSLATION_LEN, spstat->user_sample_n_bytes,		    spstat->user_channel_count, " byte swapping buffer");	if ((spwav->byteswap_buffer = 	     (void *)mtrf_malloc(spwav->byteswap_buffer_len)) ==(void *)0)	    return_err(proc,501,100,		       "Unable to alloc memory for the byteswap buffer");    }        spstat->write_occured_flag = TRUE;    if (sp_verbose > 15) fprintf(spfp,"Proc %s: initialization complete\n",				 proc);    return_success(proc,0,0,"ok");}static void array2interleaved(char **arr_buff, SP_INTEGER arr_offset, char *inter_buff, SP_INTEGER chcnt, SP_INTEGER snb, SP_INTEGER samples){    char *proc = "array2interleaved";    int recsize = snb * chcnt, c, s;    char *out_dat;    char *arr;	        if (sp_verbose > 15)	fprintf(spfp,"Proc %s: UN-Interleaving the data\n",proc);        for (c=0; c<chcnt; c++){	out_dat = inter_buff + (snb * c) ;	arr = arr_buff[c] + (arr_offset * snb);		for (s=0; s<samples; s++,arr+=snb,out_dat+=recsize){	    memcpy(out_dat,arr,snb);	}    }}void ulaw2pcm2(unsigned char *ulaw_data, short *pcm_data, enum SP_sample_encoding pcm_sbf, SP_INTEGER samples){    int o;    if (pcm_sbf != get_natural_sbf(2))	for (o=0; o < samples; o++) {	    *pcm_data = ulaw2linear_01_sbf_lut[*ulaw_data];	    pcm_data ++; ulaw_data ++;	}    else	for (o=0; o < samples; o++) {	    *pcm_data = ulaw2linear_10_sbf_lut[*ulaw_data];	    pcm_data ++; ulaw_data ++;	}}    void alaw2pcm2(unsigned char *alaw_data, short *pcm_data, enum SP_sample_encoding pcm_sbf, SP_INTEGER samples){    int o;    if (pcm_sbf != get_natural_sbf(2))	for (o=0; o < samples; o++) {	    *pcm_data = alaw2linear_01_sbf_lut[*alaw_data];	    pcm_data ++; alaw_data ++;	}    else	for (o=0; o < samples; o++) {	    *pcm_data = alaw2linear_10_sbf_lut[*alaw_data];	    pcm_data ++; alaw_data ++;	}}    void pculaw2pcm2(unsigned char *pculaw_data, short *pcm_data, enum SP_sample_encoding pcm_sbf, SP_INTEGER samples){    int o;    if (pcm_sbf != get_natural_sbf(2))	for (o=0; o < samples; o++) {	    *pcm_data = ulaw2linear_01_sbf_lut[uchar_bitreverse_lut[*pculaw_data]];	    pcm_data ++; pculaw_data ++;	}    else	for (o=0; o < samples; o++) {	    *pcm_data = ulaw2linear_10_sbf_lut[uchar_bitreverse_lut[*pculaw_data]];	    pcm_data ++; pculaw_data ++;	}}    void pcm22ulaw(short *pcm_data, enum SP_sample_encoding pcm_sbf, unsigned char *ulaw_data, SP_INTEGER samples){    int o;    if (pcm_sbf != get_natural_sbf(2)){	for (o=0; o < samples; o++) {	    /* Pre swap the bytes */	    char *p , temp; short odata;	    	    odata = *pcm_data;	    p = (char *) &odata;	    temp = *p;	    *p = *(p + 1);	    *(p + 1) = temp;	    	    *ulaw_data = linear2ulaw(odata);	    pcm_data ++; ulaw_data ++;	}    } else	for (o=0; o < samples; o++) {	    *ulaw_data = linear2ulaw(*pcm_data);	    /*		       if(o<30){			       fprintf(spfp,"  conv %6d-%4x    %4d-%2x",			       *pcm_data,*pcm_data,			       *ulaw_data, *ulaw_data);			       if ((o+1) % 4 == 0) fprintf(spfp,"\n");			       }*/	    pcm_data ++; ulaw_data ++;	}}void pcm22alaw(short *pcm_data, enum SP_sample_encoding pcm_sbf, unsigned char *alaw_data, SP_INTEGER samples){    int o;    if (pcm_sbf != get_natural_sbf(2)){	for (o=0; o < samples; o++) {	    /* Pre swap the bytes */	    char *p , temp; short odata;	    	    odata = *pcm_data;	    p = (char *) &odata;	    temp = *p;	    *p = *(p + 1);	    *(p + 1) = temp;	    	    *alaw_data = linear2alaw(odata);	    pcm_data ++; alaw_data ++;	}    } else	for (o=0; o < samples; o++) {	    *alaw_data = linear2alaw(*pcm_data);	    pcm_data ++; alaw_data ++;	}}void pcm22pculaw(short *pcm_data, enum SP_sample_encoding pcm_sbf, unsigned char *pculaw_data, SP_INTEGER samples){    int o;    if (pcm_sbf != get_natural_sbf(2)){	for (o=0; o < samples; o++) {	    /* Pre swap the bytes */	    char *p , temp; short odata;	    	    odata = *pcm_data;	    p = (char *) &odata;	    temp = *p;	    *p = *(p + 1);	    *(p + 1) = temp;	    	    *pculaw_data = uchar_bitreverse_lut[linear2ulaw(odata)];	    pcm_data ++; pculaw_data ++;	}    } else	for (o=0; o < samples; o++) {	    *pculaw_data = uchar_bitreverse_lut[linear2ulaw(*pcm_data)];	    pcm_data ++; pculaw_data ++;	}}

⌨️ 快捷键说明

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