/* * Initialize stream for WAVE COMP 360 format (do *not* allocate the buffer) */ int sig_sphere_stream_init(sigstream_t *f, const char *fn) { long n, rate; /* open file */ if (fn) { if ((f->name = strdup(fn)) == NULL) { fprintf(stderr, "sig_wave_stream_init(): cannot set stream name %s\n", fn); return(SPRO_ALLOC_ERR); } } if ((f->f = sp_open((fn) ? (char *)(fn) : "-", "r")) == NULL) { fprintf(stderr, "sig_wave_stream_init(): cannot open SPHERE stream %s\n", (fn) ? (fn) : "stdin"); return(SPRO_SIG_READ_ERR); } /* set convertion to PCM16 */ if (sp_set_data_mode(f->f, "SE-PCM-2:DF-RAW") != 0) { fprintf(stderr, "sig_sphere_stream_init(): cannot set convertion mode to 16 bits/sample PCM\n"); return(SPRO_SIG_READ_ERR); } /* read header fields */ if (sp_h_get_field(f->f, "channel_count", T_INTEGER, (void *)&n) != 0 || sp_h_get_field(f->f, "sample_rate", T_INTEGER, (void *)&rate) != 0) { fprintf(stderr, "sig_sphere_stream_init(): cannot read SPHERE header from stream %s \n", (fn) ? (fn) : "stdin"); return(SPRO_SIG_READ_ERR); } f->Fs = (float)rate; f->nchannels = (unsigned short)n; f->nbps = 2; return(0); }
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 diff_waveforms(char *file1, char *file2, char *conv_str1, char *conv_str2, int verbose, FILE *fp) { SP_FILE *sp1, *sp2; char *buff1=CNULL, *buff2=CNULL; int n1, n2, i, fail=0, blocksize=512; int return_value = 0; SP_INTEGER samples_processed=0, file1_snb, file2_snb, file1_chcnt; SP_INTEGER file2_chcnt; if ((sp1 = sp_open(file1, "r")) == SPNULL){ fail=1; if (verbose) fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",file1,file2); if (verbose) fprintf(fp,"sp_open failed on file %s\n",file1); sp_print_return_status(fp); } if ((sp2 = sp_open(file2, "r")) == SPNULL){ if (fail == 0) if (verbose) fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n", file1,file2); fail=1; if (verbose) fprintf(fp,"sp_open failed on file %s\n",file2); sp_print_return_status(fp); goto FATAL_QUIT; } if (fail) goto FATAL_QUIT; if (conv_str1 != CNULL) if (sp_set_data_mode(sp1,conv_str1) != 0){ fail=1; if (verbose) fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n", file1,file2); if (verbose) fprintf(fp,"sp_set_data_mode failed on file %s\n",file1); sp_print_return_status(fp); } if (conv_str2 != CNULL) if (sp_set_data_mode(sp2,conv_str2) != 0){ if (fail == 0) if (verbose) fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n", file1,file2); fail=1; if (verbose) fprintf(fp,"sp_set_data_mode failed on file %s\n",file2); sp_print_return_status(fp); } if (fail) goto FATAL_QUIT; if (sp_h_get_field(sp1,SAMPLE_N_BYTES_FIELD, T_INTEGER,(void *)&file1_snb) != 0){ fprintf(spfp,"Unable to retieve %s field from file '%s'\n", SAMPLE_N_BYTES_FIELD,file1); goto FATAL_QUIT; } if (sp_h_get_field(sp2,SAMPLE_N_BYTES_FIELD, T_INTEGER,(void *)&file2_snb) != 0){ fprintf(spfp,"Unable to retieve %s field from file '%s'\n", SAMPLE_N_BYTES_FIELD,file2); goto FATAL_QUIT; } if (sp_h_get_field(sp1,CHANNEL_COUNT_FIELD, T_INTEGER,(void *)&file1_chcnt) != 0){ fprintf(spfp,"Unable to retieve %s field from file '%s'\n", CHANNEL_COUNT_FIELD,file1); goto FATAL_QUIT; } if (sp_h_get_field(sp2,CHANNEL_COUNT_FIELD, T_INTEGER,(void *)&file2_chcnt) != 0){ fprintf(spfp,"Unable to retieve %s field from file '%s'\n", CHANNEL_COUNT_FIELD,file2); goto FATAL_QUIT; } if ((buff1 = (char *)sp_data_alloc(sp1,blocksize)) == CNULL){ if (verbose) fprintf(fp,"Unable to malloc memory for buffer 1\n"); goto FATAL_QUIT; } if ((buff2 = (char *)sp_data_alloc(sp2,blocksize)) == CNULL){ if (verbose) fprintf(fp,"Unable to malloc memory for buffer 2\n"); goto FATAL_QUIT; } if (file1_snb != file2_snb){ if (verbose){ fprintf(fp,"Files '%s' and '%s' do not have the same", file1,file2); fprintf(fp," sample_n_bytes value, %d and %d respectively\n", file1_snb,file2_snb); } goto FATAL_QUIT; } if (file1_chcnt != file2_chcnt){ if (verbose){ fprintf(fp,"Files '%s' and '%s' do not have the same", file1,file2); fprintf(fp," channel_count value, %d and %d respectively\n", file1_chcnt,file2_chcnt); } goto FATAL_QUIT; } do { int record_size = file1_snb * file1_chcnt; n1 = sp_read_data((char *)buff1,blocksize,sp1); if ((n1 == 0) && (sp1->read_spifr->waveform->samples_read != sp1->read_spifr->status->user_sample_count)){ sp_print_return_status(fp); goto FATAL_QUIT; } n2 = sp_read_data((char *)buff2,blocksize,sp2); if ((n2 == 0) && (sp2->read_spifr->waveform->samples_read != sp2->read_spifr->status->user_sample_count)){ sp_print_return_status(fp); goto FATAL_QUIT; } if (n1 != n2){ if (verbose) fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n", file1,file2); if (verbose) fprintf(fp," %d samples read from '%s'\n",n1,file1); if (verbose) fprintf(fp," %d samples read from '%s'\n",n2,file2); goto FATAL_QUIT; } for (i=0; i<n1; i++) { if (memcmp(buff1 + i*record_size, buff2 + i*record_size,record_size)){ int bn; if (verbose){ fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s sample %d\n", file1,file2,samples_processed+i); fprintf(fp," File 1: "); for (bn=0; bn < record_size; bn++) { fprintf(fp,"%2x ", *((unsigned char *)(buff1 + i*record_size + bn))); if ((bn+1) % file1_snb == 0) fprintf(fp,"| "); } fprintf(fp,"\n File 2: "); for (bn=0; bn < record_size; bn++) { fprintf(fp,"%2x ", *((unsigned char *)(buff2 + i*record_size + bn))); if ((bn+1) % file1_snb == 0) fprintf(fp,"| "); } fprintf(fp,"\n"); } goto FATAL_QUIT; } } samples_processed += n1; } while (!sp_eof(sp1)); if (!sp_eof(sp2)){ if (verbose) fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",file1,file2); if (verbose) fprintf(fp," file %s not at eof\n",file2); goto FATAL_QUIT; } return_value = 0; goto CLEAN_UP; FATAL_QUIT: /* Failed routine */ return_value = 100; CLEAN_UP: if (sp1 != SPNULL) { if (buff1 != (char *)NULL) sp_data_free(sp1,buff1); sp_close(sp1); } if (sp2 != SPNULL) { if (buff2 != (char *)NULL) sp_data_free(sp2,buff2); sp_close(sp2); } return(return_value); }