/* * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd * http://www.trevorwishart.co.uk * http://www.composersdesktop.com * This file is part of the CDP System. The CDP System is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The CDP System is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the CDP System; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* floatsam version */ #include #include #include #include #include #include #include #include #include #include #include #include #define MARGIN (16) #define BASE_REDUCE ENV_DEFAULT_DATAREDUCE static int read_envel_from_envfile(float **env,float **envend,int fileno,dataptr dz); static int envcopy(float *envel1,float *envend1,float **envel2,float **envend2); static int convert_envelope_to_brkpnt_table(int envcnt,double window_size,double infiledur,dataptr dz); static int convert_brktable_to_envtable(double window_size,float **env,float **envend,dataptr dz); static int write_brkpnt_data_to_file(dataptr dz); static int write_envel_to_envfile(float *env,float *envend,dataptr dz); static double *datareduce(double *q,double datareduction,int *bcnt,int paramno,dataptr dz); static int rejig_buffering(dataptr dz); static int adjust_last_val_of_brk(double *brk,double *brkend,int *datacnt,double endtime); static int store_brkpnt_envelope(int cnt,dataptr dz); static int read_value_from_brktable_from_brkpntfile(double thistime,float *thisval,dataptr dz); static int convert_brkvals_db_to_gain(int paramno,dataptr dz); static int convert_brkvals_gain_to_dB(int paramno,dataptr dz); static int convert_normalised_gain_val_to_dB(double *val); /************************** PROCESS_ENVELOPE ************************/ int process_envelope(dataptr dz) { int exit_status; int bufcnt, envcnt, cnt, other_envcnt; switch(dz->process) { case(ENV_CURTAILING): case(ENV_DOVETAILING): case(ENV_SWELL): case(ENV_ATTACK): if((exit_status = create_envelope(&cnt,dz))<0) return(exit_status); if((exit_status = store_brkpnt_envelope(cnt,dz))<0) return(exit_status); if((exit_status = apply_brkpnt_envelope(dz))<0) return(exit_status); break; case(ENV_CREATE): if((exit_status = create_envelope(&cnt,dz))<0) return(exit_status); if((exit_status = store_brkpnt_envelope(cnt,dz))<0) return(exit_status); switch(dz->mode) { case(ENV_ENVFILE_OUT): if((exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz))<0) return(exit_status); if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0) return(exit_status); break; case(ENV_BRKFILE_OUT): if((exit_status = write_brkpnt_data_to_file(dz))<0) return(exit_status); break; default: sprintf(errstr,"Unknown case: ENV_CREATE in process_envelope()\n"); return(PROGRAM_ERROR); } break; case(ENV_EXTRACT): if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->env,&dz->envend,0,dz))<0) return(exit_status); switch(dz->mode) { case(ENV_ENVFILE_OUT): if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0) return(exit_status); break; case(ENV_BRKFILE_OUT): if((exit_status = convert_envelope_to_brkpnt_table(envcnt,dz->outfile->window_size * MS_TO_SECS,dz->duration,dz))<0) return(exit_status); if((exit_status = write_brkpnt_data_to_file(dz))<0) return(exit_status); break; default: sprintf(errstr,"Unknown case: ENV_EXTRACT in process_envelope()\n"); return(PROGRAM_ERROR); } break; case(ENV_ENVTOBRK): case(ENV_ENVTODBBRK): if((exit_status = read_envel_from_envfile(&dz->env,&dz->envend,0,dz))<0) return(exit_status); envcnt = dz->envend - dz->env; if((exit_status = convert_envelope_to_brkpnt_table(envcnt,dz->infile->window_size * MS_TO_SECS,dz->duration,dz))<0) return(exit_status); if(dz->process==ENV_ENVTODBBRK) { if((exit_status = convert_brkvals_gain_to_dB(dz->extrabrkno,dz))<0) return(exit_status); } if((exit_status = write_brkpnt_data_to_file(dz))<0) return(exit_status); break; case(ENV_BRKTODBBRK): if((exit_status = convert_brkvals_gain_to_dB(dz->extrabrkno,dz))<0) return(exit_status); if((exit_status = write_brkpnt_data_to_file(dz))<0) return(exit_status); break; case(ENV_DBBRKTOBRK): if((exit_status = convert_brkvals_db_to_gain(dz->extrabrkno,dz))<0) return(exit_status); if((exit_status = write_brkpnt_data_to_file(dz))<0) return(exit_status); break; case(ENV_DBBRKTOENV): if((exit_status = convert_brkvals_db_to_gain(dz->extrabrkno,dz))<0) return(exit_status); /* fall thro */ case(ENV_BRKTOENV): if((exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz))<0) return(exit_status); if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0) return(exit_status); break; case(ENV_WARPING): if(sloom) { fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n"); fflush(stdout); } if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->origenv,&dz->origend,0,dz))<0) return(exit_status); if((exit_status = envcopy(dz->origenv,dz->origend,&dz->env,&dz->envend))<0) return(exit_status); if((exit_status = envelope_warp(&dz->env,&dz->envend,dz))<0) return(exit_status); switch(dz->mode) { case(ENV_CORRUGATING): /* generated envelope applied directly to source */ case(ENV_TRIGGERING): /* generated envelope applied directly to source */ case(ENV_PEAKCNT): break; default: if((exit_status = envreplace(dz->env,&dz->envend,dz->origenv,dz->origend))<0) return(exit_status); break; } if(dz->mode == ENV_PEAKCNT) return(FINISHED); if((exit_status = impose_envel_on_sndfile(dz->env,envcnt,bufcnt,0,dz))<0) return(exit_status); break; case(ENV_RESHAPING): if((exit_status = read_envel_from_envfile(&dz->env,&dz->envend,0,dz))<0) return(exit_status); if((exit_status = envelope_warp(&dz->env,&dz->envend,dz))<0) return(exit_status); if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0) return(exit_status); break; case(ENV_REPLOTTING): if((exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz))<0) return(exit_status); if((exit_status = envelope_warp(&dz->env,&dz->envend,dz))<0) return(exit_status); envcnt = dz->envend - dz->env; if((exit_status = convert_envelope_to_brkpnt_table(envcnt,dz->param[ENV_WSIZE] * MS_TO_SECS,dz->duration,dz))<0) return(exit_status); if((exit_status = write_brkpnt_data_to_file(dz))<0) return(exit_status); break; //TW NEW CASE case(ENV_PROPOR): return apply_brkpnt_envelope(dz); case(ENV_IMPOSE): switch(dz->mode) { case(ENV_BRKFILE_IN): case(ENV_DB_BRKFILE_IN): return apply_brkpnt_envelope(dz); case(ENV_ENVFILE_IN): exit_status = read_envel_from_envfile(&dz->env,&dz->envend,1,dz); break; case(ENV_SNDFILE_IN): if(sloom) { fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n"); fflush(stdout); } if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->env,&dz->envend,1,dz))<0) return(exit_status); exit_status = rejig_buffering(dz); /* deals with file2 having different srate or channels */ reset_filedata_counters(dz); break; default: sprintf(errstr,"Unknown case for ENV_IMPOSE: in process_envelope()\n"); return(PROGRAM_ERROR); } if(exit_status<0) return(exit_status); bufcnt = buffers_in_sndfile(/*dz->bigbufsize*/dz->buflen,0,dz); envcnt = dz->envend - dz->env; if((exit_status = impose_envel_on_sndfile(dz->env,envcnt,bufcnt,0,dz))<0) return(exit_status); break; case(ENV_REPLACE): switch(dz->mode) { case(ENV_ENVFILE_IN): exit_status = read_envel_from_envfile(&dz->env,&dz->envend,1,dz); if(sloom) { fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n"); fflush(stdout); } break; case(ENV_BRKFILE_IN): case(ENV_DB_BRKFILE_IN): // exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz); exit_status = convert_brktable_to_envtable ((double)(dz->iparam[ENV_SAMP_WSIZE]/dz->infile->channels)/(double)dz->infile->srate,&dz->env,&dz->envend,dz); if(sloom) { fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n"); fflush(stdout); } break; case(ENV_SNDFILE_IN): if(sloom) { fprintf(stdout,"INFO: Extracting envelope from 1st input soundfile.\n"); fflush(stdout); } if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->env,&dz->envend,1,dz))<0) return(exit_status); exit_status = rejig_buffering(dz); /* deals with file2 having different srate or channels */ reset_filedata_counters(dz); break; default: sprintf(errstr,"Unknown case for ENV_REPLACE: in process_envelope()\n"); return(PROGRAM_ERROR); } if(exit_status<0) return(exit_status); envcnt = dz->envend - dz->env; if(sloom) { fprintf(stdout,"INFO: Extracting envelope from 2nd input soundfile.\n"); fflush(stdout); } if((exit_status = extract_env_from_sndfile(&bufcnt,&other_envcnt,&dz->origenv,&dz->origend,0,dz))<0) return(exit_status); if((exit_status = envreplace(dz->env,&dz->envend,dz->origenv,dz->origend))<0) return(exit_status); if((exit_status = impose_envel_on_sndfile(dz->env,envcnt,bufcnt,0,dz))<0) return(exit_status); break; case(ENV_PLUCK): if((exit_status = envelope_pluck(dz))<0) return(exit_status); break; case(ENV_TREMOL): if((exit_status = envelope_tremol(dz))<0) return(exit_status); break; default: sprintf(errstr,"Unknown case in process_envelope()\n"); return(PROGRAM_ERROR); } return FINISHED; } /**************************** REJIG_BUFFERING ****************************** * * recreates buffering to deal with 1ST file, once 2ND file has been dealt with!! */ int rejig_buffering(dataptr dz) { int exit_status; if(dz->otherfile->srate != dz->infile->srate || dz->otherfile->channels != dz->infile->channels) { if((exit_status = generate_samp_windowsize(dz->infile,dz)) < 0) return(exit_status); free(dz->bigbuf); if((exit_status = create_sndbufs_for_envel(dz)) < 0) return(exit_status); } return(FINISHED); } /*************************** READ_ENVEL_FROM_ENVFILE **************************/ int read_envel_from_envfile(float **env,float **envend,int fileno,dataptr dz) { int samps_read /*, samps_to_read, secs_to_read*/; int envlen = dz->insams[fileno]; #ifdef NOTDEF if(((secs_to_read = dz->infilesize[fileno]/SECSIZE)*SECSIZE)!=dz->infilesize[fileno]) secs_to_read++; bytes_to_read = secs_to_read * SECSIZE; #endif if((*env = (float *)malloc(/*bytes_to_read*/envlen * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n"); return(MEMORY_ERROR); } if((samps_read = fgetfbufEx(*env, envlen,dz->ifd[fileno],0)) < 0) { sprintf(errstr,"Can't read samples from input envelfile\n"); return(SYSTEM_ERROR); } #ifdef NOTDEF if((*env = (float *)realloc(*env,dz->insams[fileno]))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate envelope array.\n"); return(MEMORY_ERROR); } #endif *envend = *env + envlen; return(FINISHED); } /*************************** ENVCOPY [ENVMOVE] ***************************** * moves envelope from array env1 to array pointed to by env2. * returns the end+1 address of env2 array. */ int envcopy(float *envel1,float *envend1,float **envel2,float **envend2) { float *p, *q; int tabsize = envend1 - envel1; if(*envel2 != NULL) free(*envel2); if((*envel2 = (float *)malloc(tabsize * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to copy envelope array.\n"); return(MEMORY_ERROR); } p = envel1; q = *envel2; while(penv; double inc = window_size, lasttime, thisreduce = BASE_REDUCE; int bcnt, n, final_size; int paramno = dz->extrabrkno; int add_last_val = FALSE; int orig_bcnt; if(window_size <= 0.0) { sprintf(errstr,"No window_size set: convert_envelope_to_brkpnt_table()\n"); return(PROGRAM_ERROR); } if(paramno < 0) { sprintf(errstr,"extrabuf not set up: convert_envelope_to_brkpnt_table()\n"); return(PROGRAM_ERROR); } if(dz->brk[paramno]!=NULL) free(dz->brk[paramno]); if((dz->brk[paramno] = (double *)malloc(envcnt * sizeof(double) * 2))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to convert envelope to brkpnt table.\n"); return(MEMORY_ERROR); } q = dz->brk[paramno]; for(n=0;n= 6 && thisreduce < dz->param[ENV_DATAREDUCE]) { /* RWD improvement --> */ q = dz->brk[paramno] + 4; /* incremental datareduction */ orig_bcnt = bcnt; for(n=4;n= 6) { q = dz->brk[paramno] + 4; orig_bcnt = bcnt; for(n=4;nparam[ENV_DATAREDUCE],&bcnt,paramno,dz); } } n = bcnt; if(ODD(n)) { sprintf(errstr,"convert_envelope_to_brkpnt_table(): Problem of event pairing.\n"); return(PROGRAM_ERROR); } lasttime = *(q-2); final_size = n; if(flteq(lasttime,infiledur)) { *(q-2) = infiledur; final_size = n; } else if(lasttime < infiledur) { final_size = n+2; add_last_val = TRUE; } else { if(q-4 >= dz->brk[paramno]) { if((exit_status = adjust_last_val_of_brk(dz->brk[paramno],q,&final_size,infiledur))<0) return(exit_status); } } if((dz->brk[paramno] = (double *)realloc(dz->brk[paramno],final_size * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new brkpnt table.\n"); return(MEMORY_ERROR); } if(add_last_val) { *(dz->brk[paramno] + final_size - 2) = infiledur; *(dz->brk[paramno] + final_size - 1) = *(dz->brk[paramno] + final_size - 3); } dz->brkptr[paramno] = dz->brk[paramno]; dz->brksize[paramno] = final_size/2; return(FINISHED); } /***************************** DATAREDUCE ********************** * Reduce data on passing from envelope to brkpnt representation. * * Take last 3 points, and if middle point has (approx) same value as * a point derived by interpolating between first and last points, then * ommit midpoint from brkpnt representation. */ double *datareduce(double *q,double datareduction,int *bcnt,int paramno,dataptr dz) { double *p = q-6, *midpair = q-4, *endpair = q-2, *tabend; double startime = *p++; double startval = sqrt(*p++); /* RWD improvement: in power case, take sqrt */ double midtime = *p++; double midval = sqrt(*p++); double endtime = *p++; double endval = sqrt(*p); double valrange = endval - startval; double midtimeratio = (midtime-startime)/(endtime-startime); double guessval = (valrange * midtimeratio) + startval; if(fabs(guessval - midval) < datareduction) { tabend = dz->brk[paramno] + (*bcnt); while (endpair < tabend) { *midpair++ = *endpair++; } (*bcnt) -= 2; q -= 2; } return(q); } /****************************** CONVERT_BRKTABLE_TO_ENVTABLE [BRKTOENV] ********************************* * convert brkpnt table to envelope table * * Assume envelope space has already beem mallocd(). * * window_size is in SECS. */ int convert_brktable_to_envtable(double window_size,float **env,float **envend,dataptr dz) { int exit_status; int n, envlen; float *q; double here = 0.0; double inc = window_size; int paramno = dz->extrabrkno; double duration; if(paramno < 0) { sprintf(errstr,"extrabuf not set up: convert_brktable_to_envtable()\n"); return(PROGRAM_ERROR); } duration = *(dz->brk[paramno] + ((dz->brksize[paramno]-1)*2)); if(window_size <= 0.0) { sprintf(errstr,"No window_size set: convert_brktable_to_envtable()\n"); return(PROGRAM_ERROR); } if(inc < ENV_MIN_WSIZE * MS_TO_SECS) { sprintf(errstr,"Invalid window_size: convert_brktable_to_envtable()\n"); return(PROGRAM_ERROR); } if(duration < inc) { sprintf(errstr,"Brktable duration less than window_size: Cannot proceed.\n"); return(DATA_ERROR); } envlen = (int)((duration/inc) + 1.0); /* round up */ envlen += MARGIN; /* allow for errors in float-calculation */ if(dz->brk[paramno]==NULL) { sprintf(errstr,"No existing brkpnt table. convert_brktable_to_envtable()\n"); return(PROGRAM_ERROR); } if(dz->brksize[paramno]<2) { sprintf(errstr,"Brkpnt table length invalid: convert_brktable_to_envtable()\n"); return(PROGRAM_ERROR); } if(*env != NULL) free(*env); if((*env = (float *)malloc(envlen * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n"); return(MEMORY_ERROR); } q = *env; n = 0; while(n(duration+FLTERR)) break; if((exit_status = read_value_from_brktable_from_brkpntfile(here,q,dz))<0) return(exit_status); q++; n++; } if(hereextrabrkno; if(paramno < 0) { sprintf(errstr,"extrabrkno not set: write_brkpnt_data_to_file()\n"); return(PROGRAM_ERROR); } p = dz->brk[paramno]; cnt = dz->brksize[paramno]; for(n=0;nfp,"%lf\t%lf\n",*p,*(p+1)))<2) { sprintf(errstr,"fput_brk(): Problem writing brkpnt data to file.\n"); return(PROGRAM_ERROR); } p += 2; } /* if(fclose(dz->fp)<0) { fprintf(stdout,"WARNING: Failure to close brkpnt data output file.\n"); fflush(stdout); } */ return(FINISHED); } /*************************** WRITE_ENVEL_TO_ENVFILE ***************************/ int write_envel_to_envfile(float *env,float *envend,dataptr dz) { int envlen = envend - env; int samps_to_write = envlen /* * sizeof(float)*/; int exit_status; #ifdef NOTDEF int pseudo_bytes_to_write; int secs_to_write = bytes_to_write/SECSIZE; int bytes_written; if((secs_to_write * SECSIZE)!=bytes_to_write) secs_to_write++; pseudo_bytes_to_write = secs_to_write * SECSIZE; #else int samps_written; #endif if(samps_to_write > 0) { if((exit_status = write_samps_no_report(env,samps_to_write,&samps_written,dz))<0) return(SYSTEM_ERROR); else if(samps_written == 0) { sprintf(errstr,"No data written to output envelfile.\n"); return(SYSTEM_ERROR); } } return(FINISHED); } /*************************** ADJUST_LAST_VAL_OF_BRK ***************************/ int adjust_last_val_of_brk(double *brk,double *brkend,int *datacnt,double endtime) { double *q = brkend - 4; double penulttime, penultval, lasttime, lastval, timeratio, valdiff; while(*q > endtime+FLTERR) { q -= 2; if(q < brk) { sprintf(errstr,"Cannot adjust last brkval: adjust_last_val_of_brk()\n"); return(PROGRAM_ERROR); } } if(flteq(*q,endtime)) { *q = endtime; q += 2; *datacnt = (q - brk)/2; } else { penulttime = *(q); penultval = *(q+1); lasttime = *(q+2); lastval = *(q+3); timeratio = (endtime - penulttime)/(lasttime - penulttime); valdiff = timeratio * (lastval - penultval); *(q+2) = lasttime; *(q+3) = penultval + valdiff; q += 4; *datacnt = (q - brk)/2; } return(FINISHED); } /***************************** STORE_BRKPNT_ENVELOPE *****************************/ int store_brkpnt_envelope(int cnt,dataptr dz) { int paramno = dz->extrabrkno; int n; double *p; if(paramno < 0) { sprintf(errstr,"extrabrkno not established: store_brkpnt_envelope()\n"); return(PROGRAM_ERROR); } if(dz->brk[paramno]!=NULL) { sprintf(errstr,"extrabrktable already exists: store_brkpnt_envelope()\n"); return(PROGRAM_ERROR); } if((dz->brk[paramno] = (double *)malloc(cnt * 2 * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for brkpnt envelope array.\n"); return(MEMORY_ERROR); } p = dz->brk[paramno]; for(n=0;nparray[ENV_CREATE_TIME][n]; *p++ = dz->parray[ENV_CREATE_LEVL][n]; } dz->brksize[paramno] = cnt; dz->brkptr[paramno] = dz->brk[paramno]; free(dz->parray[ENV_CREATE_TIME]); free(dz->parray[ENV_CREATE_LEVL]); dz->parray[ENV_CREATE_TIME] = (double *)0; dz->parray[ENV_CREATE_LEVL] = (double *)0; return(FINISHED); } /**************************** READ_VALUE_FROM_BRKTABLE_FROM_BRKPNTFILE *****************************/ int read_value_from_brktable_from_brkpntfile(double thistime,float *thisval,dataptr dz) { double *endpair, *p, val; double hival, loval, hiind, loind; int paramno = dz->extrabrkno; if(!dz->brkinit[paramno]) { dz->brkptr[paramno] = dz->brk[paramno]; dz->firstval[paramno] = *(dz->brk[paramno]+1); endpair = dz->brk[paramno] + ((dz->brksize[paramno]-1)*2); dz->lastind[paramno] = *endpair; dz->lastval[paramno] = *(endpair+1); dz->brkinit[paramno] = 1; } p = dz->brkptr[paramno]; if(thistime <= *(dz->brk[paramno])) { *thisval = (float)dz->firstval[paramno]; return(FINISHED); } else if(thistime >= dz->lastind[paramno]) { *thisval = (float)dz->lastval[paramno]; return(FINISHED); } if(thistime > *p) { while(*p < thistime) p += 2; } else { while(*p >= thistime) p -= 2; p += 2; } hival = *(p+1); hiind = *p; loval = *(p-1); loind = *(p-2); val = (thistime - loind)/(hiind - loind); val *= (hival - loval); val += loval; *thisval = (float)val; dz->brkptr[paramno] = p; return(FINISHED); } /******************************** CONVERT_BRKVALS_DB_TO_GAIN *************************/ int convert_brkvals_db_to_gain(int paramno,dataptr dz) { int exit_status; double *p = dz->brk[paramno]; double *pend = p + (dz->brksize[paramno] * 2); p++; while(p < pend) { if((exit_status = convert_dB_at_or_below_zero_to_gain(p))<0) return(exit_status); p += 2; } return(FINISHED); } /******************************** CONVERT_BRKVALS_GAIN_TO_DB *************************/ int convert_brkvals_gain_to_dB(int paramno,dataptr dz) { int exit_status; double *p = dz->brk[paramno]; double *pend = p + (dz->brksize[paramno] * 2); p++; while(p < pend) { if((exit_status = convert_normalised_gain_val_to_dB(p))<0) return(exit_status); p += 2; } return(FINISHED); } /**************************** CONVERT_NORMALISED_GAIN_VAL_TO_DB ********************************/ int convert_normalised_gain_val_to_dB(double *val) { double thisval = *val; double mingain = 1.0/pow(10,(-MIN_DB_ON_16_BIT/20.0)); if(thisval > 1.0 || thisval < 0.0) { sprintf(errstr,"convert_normalised_gain_vals_to_dB() received non-normalised gain\n"); return(PROGRAM_ERROR); } if(thisval <= mingain) *val = MIN_DB_ON_16_BIT; else { thisval = 1.0/thisval; thisval = log10(thisval); thisval *= 20.0; thisval = -thisval; *val = thisval; } return(FINISHED); }