📄 spwrite.c
字号:
#include <stdio.h>#define SPHERE_LIBRARY_CODE#include <sp/sphere.h>#include <sp/ulaw.h>#include <string.h>/* * * sp_write_data() * */int sp_mc_write_data(void *buffer, size_t num_sample, SP_FILE *sp){ char *proc="sp_write_data " SPHERE_VERSION_STR, *str; int ret; SP_INTEGER l_int, header_size; SPIFR *spifr; SPSTATUS *spstat; SPWAVEFORM *spwav; if (sp_verbose > 10) fprintf(spfp, "Proc %s: file %s, %d bytes/sample, %d channels, %d samples\n", proc,sp->write_spifr->status->external_filename, sp->write_spifr->status->user_sample_n_bytes, sp->write_spifr->status->user_channel_count, num_sample); 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,0, "Unable to write data to a file opened for reading");#ifdef isnotansi if (num_sample < 0) return_err(proc,103,0, rsprintf("Negative sample count %d",num_sample));#endif spifr = sp->write_spifr; spstat = spifr->status; spwav = spifr->waveform; /*************************************************************************/ /* Perform all initializations to the sphere file to begin reading */ /* set up the FoB Structure for reading */ if (spstat->write_occured_flag == FALSE) { /******************************************************/ /* 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,0, 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,0, 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,0, 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,0, 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); } } /* Flush the header to the file pointer */ if (sp_write_header(spwav->sp_fp, spstat->file_header, &header_size, &(spwav->header_data_size)) < 0) return_err(proc,200,0,"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,0, "Unable to allocate a FOB structure"); if ((buff = mtrf_malloc(blen)) == CNULL){ fob_destroy(spwav->sp_fob); return_err(proc,301,0, "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,0, "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,0, rsprintf("Unable to open temporary file %s", spstat->temp_filename)); if ((spwav->sp_fob = fob_create(temp_fp)) == FOBPNULL) return_err(proc,303,0, "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,0, "Unable to allocate a FOB structure"); spwav->sp_fp = FPNULL; } /* Set up byte format the conversions */ if (spstat->user_sbf != spstat->file_sbf) if (((spstat->user_sbf == SP_sbf_01) && (spstat->file_sbf == SP_sbf_10)) || ((spstat->user_sbf == SP_sbf_10) && (spstat->file_sbf == SP_sbf_01))) { if (sp_verbose > 15) fprintf(spfp,"Proc %s: Swapping byte in FOB utilities\n",proc); fob_write_byte_swap(spwav->sp_fob); } /* allocate a translation buffer for the sample encodings */ if (spstat->user_encoding != spstat->file_encoding) { if (((spstat->user_encoding == SP_se_ulaw) && (spstat->file_encoding == SP_se_pcm2)) || ((spstat->user_encoding == SP_se_pcm2) && (spstat->file_encoding == SP_se_ulaw))) { /* 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,0, "Unable to alloc memory for the encoding buffer"); } else { return_err(proc,400,0, "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,0, "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,0, "Unable to alloc memory for the interleave buffer"); } spstat->write_occured_flag = TRUE; if (sp_verbose > 15) fprintf(spfp,"Proc %s: initialization complete\n", proc); } /* WRITE THE DATA INTO FOB */ { int samples_written = 0; int out_samples=0, o, c, s; int block=0; void *out_block = (void *)0, *end_of_input_block=(void *)0; void *out_inter_block = (void *)0; short *sh_data=(short *)0; char *arr, **arr_buff=(char **)0; unsigned char *ulaw_data = (unsigned char *)0; SP_CHECKSUM checksum=0; while (samples_written < num_sample){ if (sp_verbose > 16) fprintf(spfp,"Proc %s: Beginning Block %d\n",proc,block); /* if conversions are neccessary, restrict the size of the */ /* data to that of the translation buffers */ if ((spstat->user_encoding != spstat->file_encoding) || (spstat->channels != CHANNELSNULL) || spstat->user_data_fmt == SP_df_array){ if ((out_samples = (num_sample - samples_written)) > TRANSLATION_LEN) out_samples = TRANSLATION_LEN; } else out_samples = num_sample;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -