| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880 |
- /*
- * Copyright (c) 1983-2023 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 <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <structures.h>
- #include <processno.h>
- #include <tkglobals.h>
- #include <mix.h>
- #include <globcon.h>
- #include <cdpmain.h>
- #include <filetype.h>
- #include <sfsys.h>
- #ifdef unix
- #define round(x) lround((x))
- #endif
- static int establish_action_value_storage_for_mix(dataptr dz);
- static int open_file_and_get_props(int filecnt,char *filename,int *srate,int chans,dataptr dz);
- static int allocate_actions(int filecnt,dataptr dz);
- static int assign_stereo_sense(int chans,double lpan,double rpan,double llevel,double rlevel,dataptr dz);
- static int unmark_freeable_bufs(int **bufsflag,int *bufsflagcnt,int startpos,int this,int longbitsize,dataptr dz);
- static int get_free_buf(int **bufsflag,int *bufsflagcnt,int longbitsize,int *thisbuf,dataptr dz);
- #ifdef NOTDEF
- static int assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
- int *llscale,int *rrscale,int *lrscale,int *rlscale,dataptr dz);
- #else
- static int d_assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
- double *llscale,double *rrscale,double *lrscale,double *rlscale,dataptr dz);
- #endif
- static int check_right_level(char *str,double *rlevel,int filecnt);
- static int check_right_pan(char *str,double *pan,int filecnt);
- static int check_left_pan(char *str,double *pan,int filecnt);
- static int check_left_level(char *str,double *level,int filecnt);
- static int unmark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize);
- static int mark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize,dataptr dz);
- static int reallocate_bufsflag(int z,int **bufsflag,int *bufsflagcnt);
- /********************** SET_UP_MIX ****************************/
- int set_up_mix(dataptr dz)
- {
- int exit_status;
- double time, llevel, lpan, rlevel, rpan;
- int chans;
- int startpos, endpos, n;
- int *bufsflag = NULL;
- int bufsflagcnt = 0;
- double filetime, eventend;
- int longbitsize = sizeof(int) * CHARBITSIZE;
- int srate=0, end_of_mix = -1;
- int mix_end_set = FALSE;
- int mix_end_specified = FALSE;
- int mix_start_set = FALSE;
- char *filename;
- int filecnt = 0;
- int total_words = 0;
- if(dz->param[MIX_START] >= dz->param[MIX_END]) {
- sprintf(errstr,"Mix starts after it ends.\n");
- return(USER_ERROR);
- }
- dz->iparam[MIX_STRTPOS] = 0;
- dz->iparam[MIX_STRTPOS_IN_ACTION] = 0;
- dz->iparam[MIX_TOTAL_ACTCNT] = 0;
- if((exit_status = establish_file_data_storage_for_mix(dz->linecnt,dz))<0)
- return(exit_status);
- if((exit_status = establish_action_value_storage_for_mix(dz))<0)
- return(exit_status);
- for(n=0;n<dz->linecnt;n++) { /* for each mixfile line */
- filename = dz->wordstor[total_words]; /* get the filename */
- if(strlen(filename)<=0) {
- sprintf(errstr,"filename error: line %d: parse_mixfile_for_data()\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- if((exit_status = get_mixdata_in_line
- (dz->wordcnt[n],dz->wordstor,total_words,&time,&chans,&llevel,&lpan,&rlevel,&rpan,filecnt,dz))<0)
- return(exit_status);
- total_words += dz->wordcnt[n];
- if(time >= dz->param[MIX_END]) /* If line starts after specified mix end, ignore */
- continue;
- if((exit_status = finalise_and_check_mixdata_in_line(dz->wordcnt[n],chans,llevel,&lpan,&rlevel,&rpan))<0)
- return(exit_status);
- if((exit_status = open_file_and_get_props(filecnt,filename,&srate,chans,dz))<0)
- return(exit_status);
- filetime = (double)(dz->insams[filecnt]/chans)/(double)srate;
- if((eventend = time + filetime) < dz->param[MIX_START]) /* If line ends before specified mix start, ignore */
- continue;
- if(!mix_start_set) { /* if mix start param not set yet, set it */
- dz->iparam[MIX_STRTPOS] = (int)round(dz->param[MIX_START] * (double)(srate * dz->out_chans));
- dz->iparam[MIX_STRTPOS_IN_ACTION] = dz->iparam[MIX_STRTPOS];
- mix_start_set = TRUE;
- }
- if(!mix_end_set) { /* if mix end param not set yet, set it */
- if(!flteq(dz->param[MIX_END],dz->application->default_val[MIX_END])) { /* if mixend param given by user */
- end_of_mix = round(dz->param[MIX_END] * (double)srate) * dz->out_chans;
- if(end_of_mix < 0) {
- sprintf(errstr,"Error in end_of_mix logic: parse_mixfile_for_data()\n");
- return(PROGRAM_ERROR);
- }
- mix_end_specified = TRUE;
- }
- mix_end_set = TRUE;
- }
- if((exit_status = allocate_actions(filecnt,dz))<0) /* assign values to mix ON and OFF actions */
- return(exit_status);
- startpos = round(time * (double)srate) * chans; /* startposition, in samples, of this file */
- dz->valstor[filecnt]->stereo = assign_stereo_sense(chans,lpan,rpan,llevel,rlevel,dz);
- if(dz->valstor[filecnt]->stereo == MONO_TO_STEREO
- || dz->valstor[filecnt]->stereo == MONO_TO_CENTRE
- || dz->valstor[filecnt]->stereo == MONO_TO_LEFT
- || dz->valstor[filecnt]->stereo == MONO_TO_RIGHT) {
- startpos *= STEREO; /* startposition, in output samples, of this file */
- dz->insams[filecnt] *= STEREO; /* EFFECTIVE sample-dur of file: it's converted to stereo */
- }
- if((exit_status = unmark_freeable_bufs /* finds buffers which are not (any longer) in use */
- (&bufsflag,&bufsflagcnt,startpos,dz->iparam[MIX_TOTAL_ACTCNT],longbitsize,dz))<0)
- return(exit_status);
- dz->valstor[filecnt]->ifd = dz->ifd[filecnt];
- if((exit_status = get_free_buf(&bufsflag,&bufsflagcnt,longbitsize,&(dz->valstor[filecnt]->bufno),dz))<0)
- return(exit_status); /* Allocate a buffer which is not currently in use */
- if((exit_status = d_assign_scaling(dz->iparam[MIX_TOTAL_ACTCNT],llevel,rlevel,lpan,rpan,
- &(dz->valstor[filecnt]->llscale),&(dz->valstor[filecnt]->rrscale),
- &(dz->valstor[filecnt]->lrscale),&(dz->valstor[filecnt]->rlscale),dz))<0)
- return(exit_status); /* Assign the input sound amplitude scaling */
- endpos = startpos + dz->insams[filecnt]; /* Find end-of-current-file in output stream */
- if(mix_end_specified && (end_of_mix < endpos)) { /* If file ends aftert mix ends */
- endpos = end_of_mix; /* curtail (effective) length */
- dz->insams[filecnt] = end_of_mix - startpos;
- }
- dz->valstor[filecnt]->samplen = dz->insams[filecnt]; /* store (effective) length */
- dz->act[dz->iparam[MIX_TOTAL_ACTCNT]++]->position = startpos; /* store outputstream-position of mix start */
- dz->act[dz->iparam[MIX_TOTAL_ACTCNT]++]->position = endpos; /* store outputstream-position of mix end */
- filecnt++; /* count the ACTUALLY USED lines */
- }
- if(!mix_end_set || filecnt==0) {
- sprintf(errstr,"No mixfile line is active within the time limits specified.\n");
- return(DATA_ERROR);
- }
- if(bufsflagcnt)
- free(bufsflag);
- dz->bufcnt++; /* bufcnt is number assigned to highest assigned buf, COUNTING FROM ZERO */
- /* Hence, actual bufcnt is 1 more than this */
- dz->infile->channels = dz->out_chans; /* output channels(evenutally derived from dz->infile->channels) */
- //TW SET UP AFTER OUTCHANS KNOWN
- if(dz->process!=MIXMAX) {
- if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
- return(exit_status);
- }
- return(FINISHED); /* is highest number of channels encountered in infiles */
- }
- /**************************** ESTABLISH_FILE_DATA_STORAGE_FOR_MIX ********************************/
- int establish_file_data_storage_for_mix(int filecnt,dataptr dz)
- {
- int n;
- if(dz->insams!=NULL)
- free(dz->insams); /* in TK insams[0] also used in parse accounting */
- if(dz->ifd!=NULL)
- free(dz->ifd);
- if((dz->insams = (int *)malloc(filecnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to allocate infile samplesize array.\n");
- return(MEMORY_ERROR);
- }
- if((dz->ifd = (int *)malloc(filecnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to allocate infile pointers array.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<filecnt;n++)
- dz->ifd[n] = -1;
- return(FINISHED);
- }
- /**************************** ESTABLISH_ACTION_VALUE_STORAGE_FOR_MIX ********************************/
- int establish_action_value_storage_for_mix(dataptr dz)
- {
- int n;
- if((dz->valstor = (actvalptr *)malloc(dz->linecnt * sizeof(actvalptr)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for mix action values store.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->linecnt;n++) {
- dz->valstor[n] = NULL;
- if((dz->valstor[n]=(actvalptr)malloc(sizeof(struct actval)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for mix action value store %d\n",n+1);
- return(MEMORY_ERROR);
- }
- }
- return(FINISHED);
- }
- /**************************** GET_MIXDATA_IN_LINE ********************************/
- int get_mixdata_in_line(int wordcnt,char **wordstor,int total_words,double *time,int *chans,
- double *llevel,double *lpan,double *rlevel,double *rpan,int filecnt,dataptr dz)
- {
- int exit_status;
- switch(wordcnt) {
- case(MIX_MAXLINE):
- if((exit_status = check_right_level(wordstor[total_words+MIX_RLEVELPOS],rlevel,filecnt))<0) /* 6d */
- return(exit_status);
- if((exit_status = check_right_pan(wordstor[total_words+MIX_RPANPOS],rpan,filecnt))<0)
- return(exit_status);
- /* fall thro */
- case(MIX_MIDLINE):
- if((exit_status = check_left_pan(wordstor[total_words+MIX_PANPOS],lpan,filecnt))<0) /* 6c */
- return(exit_status);
- /* fall thro */
- case(MIX_MINLINE):
- if(sscanf(dz->wordstor[total_words+1],"%lf",time)!=1
- || sscanf(dz->wordstor[total_words+2],"%d",chans)!=1) {
- sprintf(errstr,"Error scanning data: get_mixdata_in_line()\n");
- return(PROGRAM_ERROR);
- }
- if((exit_status = check_left_level(wordstor[total_words+3],llevel,filecnt))<0)
- return(exit_status);
- break;
- default:
- sprintf(errstr,"Illegal line length: get_mixdata_in_line()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /**************************** FINALISE_AND_CHECK_MIXDATA_IN_LINE ********************************/
- int finalise_and_check_mixdata_in_line(int wordcnt,int chans,double llevel,
- double *lpan,double *rlevel,double *rpan)
- {
- switch(wordcnt) {
- case(MIX_MINLINE):
- switch(chans) {
- case(1):
- *lpan = 0.0; /* 6a */
- break;
- case(2):
- *rlevel = llevel; /* 6b */
- *lpan = -1.0;
- *rpan = 1.0;
- }
- break;
- case(MIX_MIDLINE):
- if(chans!=1) {
- sprintf(errstr,"Error parsing data: finalise_and_check_mixdata_in_line()\n");
- return(PROGRAM_ERROR);
- }
- break;
- case(MIX_MAXLINE):
- if(chans!=2) {
- sprintf(errstr,"Error parsing data: finalise_and_check_mixdata_in_line()\n");
- return(PROGRAM_ERROR);
- }
- break;
- }
- return(FINISHED);
- }
- /************************* OPEN_FILE_AND_GET_PROPS *******************************/
- int open_file_and_get_props(int filecnt,char *filename,int *srate,int chans,dataptr dz)
- {
- int exit_status;
- double maxamp, maxloc;
- int maxrep;
- int getmax = 0, getmaxinfo = 0;
- infileptr ifp;
- if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store data on files.\n");
- return(MEMORY_ERROR);
- }
- if((dz->ifd[filecnt] = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
- sprintf(errstr,"Failed to open sndfile %s: %s\n",filename,sferrstr());
- return(SYSTEM_ERROR);
- }
- if((exit_status = readhead(ifp,dz->ifd[filecnt],filename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
- return(exit_status);
- copy_to_fileptr(ifp,dz->infile);
- if(dz->infile->filetype!=SNDFILE) {
- sprintf(errstr,"Non soundfile encountered [%s]: open_file_and_get_props()\n",filename);
- return(PROGRAM_ERROR);
- }
- if(dz->infile->channels!=chans) {
- sprintf(errstr,"Incorrect channels found [%s]: open_file_and_get_props()\n",filename);
- return(PROGRAM_ERROR);
- }
- if(filecnt==0)
- *srate = dz->infile->srate;
- else if(dz->infile->srate != *srate) {
- sprintf(errstr,"incompatible srates: [file %s] open_file_and_get_props()\n",filename);
- return(PROGRAM_ERROR);
- }
- if((dz->insams[filecnt] = sndsizeEx(dz->ifd[filecnt]))<0) {
- sprintf(errstr, "Can't read size of input file %s: open_file_and_get_props()\n",filename);
- return(PROGRAM_ERROR);
- }
- if(dz->insams[filecnt] <=0) {
- sprintf(errstr, "Zero size for input file %s: open_file_and_get_props()\n",filename);
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /*********************** ALLOCATE_ACTIONS *************************/
- int allocate_actions(int filecnt,dataptr dz)
- {
- int new_total = dz->iparam[MIX_TOTAL_ACTCNT] + 2;
- if(dz->iparam[MIX_TOTAL_ACTCNT]==0) {
- if((dz->act = (actptr *)malloc(new_total * sizeof(actptr)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for mix actions store.\n");
- return(MEMORY_ERROR);
- }
- } else {
- if((dz->act=(actptr *)realloc(dz->act,new_total * sizeof(actptr)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY ro reallocate mix actions store.\n");
- return(MEMORY_ERROR);
- }
- }
- if((dz->act[dz->iparam[MIX_TOTAL_ACTCNT]] = (actptr)malloc(sizeof(struct action)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for final mix action store.\n");
- return(MEMORY_ERROR);
- }
- dz->act[dz->iparam[MIX_TOTAL_ACTCNT]]->val = dz->valstor[filecnt];
- dz->act[dz->iparam[MIX_TOTAL_ACTCNT]]->role = MIX_ACTION_ON;
- if((dz->act[dz->iparam[MIX_TOTAL_ACTCNT]+1] = (actptr)malloc(sizeof(struct action)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for further mix action store.\n");
- return(MEMORY_ERROR);
- }
- dz->act[dz->iparam[MIX_TOTAL_ACTCNT]+1]->val = dz->valstor[filecnt];
- dz->act[dz->iparam[MIX_TOTAL_ACTCNT]+1]->role = MIX_ACTION_OFF;
- return(FINISHED);
- }
- /********************* ASSIGN_STEREO_SENSE **************************/
- int assign_stereo_sense(int chans,double lpan,double rpan,double llevel,double rlevel,dataptr dz)
- {
- switch(chans) {
- case(MONO):
- if(dz->out_chans==MONO) return(MONO);
- else if(lpan <= -1.0) return(MONO_TO_LEFT);
- else if(lpan >= 1.0) return(MONO_TO_RIGHT);
- else if(flteq(lpan,0.0)) return(MONO_TO_CENTRE);
- else return(MONO_TO_STEREO);
- break;
- case(STEREO):
- if(flteq(rlevel,0.0)) {
- if(lpan <= -1.0) return(STEREOLEFT_TO_LEFT);
- else if(lpan >= 1.0) return(STEREOLEFT_TO_RIGHT);
- else return(STEREOLEFT_PANNED);
- }
- else if(flteq(llevel,0.0)) {
- if(rpan <= -1.0) return(STEREORIGHT_TO_LEFT);
- else if(rpan >= 1.0) return(STEREORIGHT_TO_RIGHT);
- else return(STEREORIGHT_PANNED);
- } else if(lpan <= -1.0 && rpan >= 1.0) return(STEREO);
- else if(lpan >= 1.0 && rpan <= -1.0) return(STEREO_MIRROR);
- else if(flteq(lpan,0.0) && flteq(rpan,0.0) && flteq(rlevel,llevel)) return(STEREO_TO_CENTRE);
- else if((lpan <= -1.0) && flteq(rpan,lpan) && flteq(rlevel,llevel)) return(STEREO_TO_LEFT);
- else if((rpan >= 1.0) && flteq(rpan,lpan) && flteq(rlevel,llevel)) return(STEREO_TO_RIGHT);
- break;
- }
- return(STEREO_PANNED);
- }
- /************************* UNMARK_FREEABLE_BUFS ***********************
- *
- * (1) If a buffer has been switched off BEFORE now, then it is
- * available for use!! unmark it!!
- * (2) If a buffer is subsequently turned back on, this catches it!!
- * A buffer can ONLY be turned back on LATER (!), and is hence
- * LATER in this list EVEN though it is not yet fully time-sorted!! (1998 ???)
- */
- int unmark_freeable_bufs(int **bufsflag,int *bufsflagcnt,int startpos,int this,int longbitsize,dataptr dz)
- {
- int exit_status;
- int n;
- for(n=0;n<this;n++) {
- switch(dz->act[n]->role) {
- case(MIX_ACTION_ON): /* 2 */
- if((exit_status = mark_buf(bufsflag,bufsflagcnt,dz->act[n]->val->bufno,longbitsize,dz))<0)
- return(exit_status);
- break;
- case(MIX_ACTION_OFF): /* 1 */
- if(dz->act[n]->position < startpos) {
- if((exit_status = unmark_buf(bufsflag,bufsflagcnt,dz->act[n]->val->bufno,longbitsize))<0)
- return(exit_status);
- }
- break;
- }
- }
- return(FINISHED);
- }
- /************************** GET_FREE_BUF ***************************
- *
- * Get the FIRST available free buffer.
- * (1) Going through each int.
- * (2) Set the mask to start of int.
- * (3) For each position in the int..
- * (4) If that byte is NOT set, break, thisbuf counts which byte
- * and therefore which buffer it is.
- * (5) Advance the mask.
- * (6) Advance the buffer counter.
- * (7) Set the appropriate bit for this buffer, return buffer no.
- */
- int get_free_buf(int **bufsflag,int *bufsflagcnt,int longbitsize,int *thisbuf,dataptr dz)
- {
- int exit_status=0;
- int y=0, z=0, got_it = 0;
- int mask=0;
- *thisbuf = 0;
- for(z=0;z<*bufsflagcnt;z++) { /* 1 */
- mask = 1; /* 2 */
- for(y=0;y<longbitsize;y++) { /* 3 */
- if(!(mask & (*bufsflag)[z])) { /* 4 */
- got_it = 1;
- break;
- }
- mask <<= 1; /* 5 */
- (*thisbuf)++; /* 6 */
- }
- if(got_it)
- break;
- }
- if((exit_status = mark_buf(bufsflag,bufsflagcnt,*thisbuf,longbitsize,dz))<0) /* 7 */
- return(exit_status);
- return(FINISHED);
- }
- /*************************** ASSIGN_SCALING ***************************/
- /*RWD gulp! */
- #ifdef NOTDEF
- int assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
- int *llscale,int *rrscale,int *lrscale,int *rlscale,dataptr dz)
- {
- switch(dz->act[here]->val->stereo) {
- case(MONO):
- if(lpan < -1.0 - FLTERR) *llscale = round(llevel * TWO_POW_15/(-lpan));
- else if(lpan > 1.0 + FLTERR) *llscale = round(llevel * TWO_POW_15/lpan);
- else *llscale = round(llevel * TWO_POW_15);
- break;
- case(MONO_TO_CENTRE):
- case(STEREO_TO_CENTRE): *llscale = round(llevel * TWO_POW_15);
- break;
- case(MONO_TO_LEFT):
- case(STEREO_TO_LEFT):
- case(STEREOLEFT_TO_LEFT):
- if(lpan<(-1. - FLTERR)) *llscale = round(llevel * TWO_POW_15/(-lpan));
- else *llscale = round(llevel * TWO_POW_15);
- break;
- case(STEREORIGHT_TO_LEFT):
- if(lpan<(-1. - FLTERR)) *llscale = round(rlevel * TWO_POW_15/(-lpan));
- else *llscale = round(rlevel * TWO_POW_15);
- break;
- case(MONO_TO_RIGHT):
- case(STEREOLEFT_TO_RIGHT):
- if(lpan>(1. + FLTERR)) *rrscale = round(llevel * TWO_POW_15/(lpan));
- else *rrscale = round(llevel * TWO_POW_15);
- break;
- case(STEREO_TO_RIGHT):
- case(STEREORIGHT_TO_RIGHT):
- if(rpan>(1. + FLTERR)) *rrscale = round(rlevel * TWO_POW_15/rpan);
- else *rrscale = round(rlevel * TWO_POW_15);
- break;
- case(STEREO):
- if(lpan < -1.0 - FLTERR) *llscale = round(llevel * TWO_POW_15/(-lpan));
- else *llscale = round(llevel * TWO_POW_15);
- if(rpan > 1.0 + FLTERR) *rrscale = round(rlevel * TWO_POW_15/rpan);
- else *rrscale = round(rlevel * TWO_POW_15);
- break;
- case(STEREO_MIRROR):
- if(lpan > 1.0 + FLTERR) *llscale = round(llevel * TWO_POW_15/(lpan));
- else *llscale = round(llevel * TWO_POW_15);
- if(rpan < -1.0 - FLTERR) *rrscale = round(rlevel * TWO_POW_15/(-rpan));
- else *rrscale = round(rlevel * TWO_POW_15);
- break;
- case(MONO_TO_STEREO):
- case(STEREOLEFT_PANNED):
- if(lpan < -1.0 - FLTERR) { /* VERY LEFT */
- *llscale = round(llevel * TWO_POW_15/(-lpan));
- *rrscale = 0;
- } else if(lpan < 0.0) { /* LEFTWARDS */
- *llscale = round(llevel * TWO_POW_15);
- *rrscale = round(llevel * (1.0+lpan) * TWO_POW_15);
- } else if(lpan <= 1.0) { /* RIGHTWARDS */
- *llscale = round(llevel * (1.0-lpan) * TWO_POW_15);
- *rrscale = round(llevel * TWO_POW_15);
- } else { /* VERY RIGHT */
- *llscale = 0;
- *rrscale = round(llevel * TWO_POW_15/(lpan));
- }
- break;
- case(STEREORIGHT_PANNED):
- if(rpan < -1.0) { /* VERY LEFT */
- *llscale = round(rlevel * TWO_POW_15/(-rpan));
- *rrscale = 0;
- } else if(rpan < 0.0) { /* LEFTWARDS */
- *llscale = round(rlevel * TWO_POW_15);
- *rrscale = round(rlevel * (1.0+rpan) * TWO_POW_15);
- } else if(rpan <= 1.0) { /* RIGHTWARDS */
- *llscale = round(rlevel * (1.0-rpan) * TWO_POW_15);
- *rrscale = round(rlevel * TWO_POW_15);
- } else { /* VERY RIGHT */
- *llscale = 0;
- *rrscale = round(rlevel * TWO_POW_15/rpan);
- }
- break;
- case(STEREO_PANNED):
- /* LEFT STEREO INPUT PANNED ... */
- if(lpan < -1.0) { /* VERY LEFT */
- *llscale = round(llevel * TWO_POW_15/(-lpan));
- *lrscale = 0;
- } else if(lpan < 0.0) { /* LEFTWARDS */
- *llscale = round(llevel * TWO_POW_15);
- *lrscale = round(llevel * (1.0+lpan) * TWO_POW_15);
- } else if(lpan <= 1.0) { /* RIGHTWARDS */
- *llscale = round(llevel * (1.0-lpan) * TWO_POW_15);
- *lrscale = round(llevel * TWO_POW_15);
- } else { /* VERY RIGHT */
- *llscale = 0;
- *lrscale = round(llevel * TWO_POW_15/(lpan));
- }
- /* RIGHT STEREO INPUT PANNED ... */
- if(rpan < -1.0) { /* VERY LEFT */
- *rlscale = round(rlevel * TWO_POW_15/(-rpan));
- *rrscale = 0;
- } else if(rpan < 0.0) { /* LEFTWARDS */
- *rlscale = round(rlevel * TWO_POW_15);
- *rrscale = round(rlevel * (1.0+rpan) * TWO_POW_15);
- } else if(rpan <= 1.0) { /* RIGHTWARDS */
- *rlscale = round(rlevel * (1.0-rpan) * TWO_POW_15);
- *rrscale = round(rlevel * TWO_POW_15);
- } else { /* VERY RIGHT */
- *rlscale = 0;
- *rrscale = round(rlevel * TWO_POW_15/(rpan));
- }
- break;
- default:
- sprintf(errstr,"Unknown case in assign_scaling()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- #else
- int d_assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
- double *llscale,double *rrscale,double *lrscale,double *rlscale,dataptr dz)
- {
- switch(dz->act[here]->val->stereo) {
- case(MONO):
- if(lpan < -1.0 - FLTERR) *llscale = llevel/(-lpan);
- else if(lpan > 1.0 + FLTERR) *llscale = llevel/lpan;
- else *llscale = llevel;
- break;
- case(MONO_TO_CENTRE):
- case(STEREO_TO_CENTRE): *llscale = llevel;
- break;
- case(MONO_TO_LEFT):
- case(STEREO_TO_LEFT):
- case(STEREOLEFT_TO_LEFT):
- if(lpan<(-1. - FLTERR)) *llscale = llevel/(-lpan);
- else *llscale = llevel;
- break;
- case(STEREORIGHT_TO_LEFT):
- if(lpan<(-1. - FLTERR)) *llscale = rlevel/(-lpan);
- else *llscale = rlevel;
- break;
- case(MONO_TO_RIGHT):
- case(STEREOLEFT_TO_RIGHT):
- if(lpan>(1. + FLTERR)) *rrscale = llevel/lpan;
- else *rrscale = llevel;
- break;
- case(STEREO_TO_RIGHT):
- case(STEREORIGHT_TO_RIGHT):
- if(rpan>(1. + FLTERR)) *rrscale = rlevel/rpan;
- else *rrscale = rlevel;
- break;
- case(STEREO):
- if(lpan < -1.0 - FLTERR) *llscale = llevel/(-lpan);
- else *llscale = llevel;
- if(rpan > 1.0 + FLTERR) *rrscale = rlevel/rpan;
- else *rrscale = rlevel;
- break;
- case(STEREO_MIRROR):
- if(lpan > 1.0 + FLTERR) *llscale = llevel/lpan;
- else *llscale = llevel;
- if(rpan < -1.0 - FLTERR) *rrscale = rlevel/(-rpan);
- else *rrscale = rlevel;
- break;
- case(MONO_TO_STEREO):
- case(STEREOLEFT_PANNED):
- if(lpan < -1.0 - FLTERR) { /* VERY LEFT */
- *llscale = llevel/(-lpan);
- *rrscale = 0.0;
- } else if(lpan < 0.0) { /* LEFTWARDS */
- *llscale = llevel;
- *rrscale = llevel * (1.0+lpan);
- } else if(lpan <= 1.0) { /* RIGHTWARDS */
- *llscale = llevel * (1.0-lpan);
- *rrscale = llevel;
- } else { /* VERY RIGHT */
- *llscale = 0.0;
- *rrscale = llevel/lpan;
- }
- break;
- case(STEREORIGHT_PANNED):
- if(rpan < -1.0) { /* VERY LEFT */
- *llscale = rlevel/(-rpan);
- *rrscale = 0.0;
- } else if(rpan < 0.0) { /* LEFTWARDS */
- *llscale = rlevel;
- *rrscale = rlevel * (1.0+rpan);
- } else if(rpan <= 1.0) { /* RIGHTWARDS */
- *llscale = rlevel * (1.0-rpan);
- *rrscale = rlevel;
- } else { /* VERY RIGHT */
- *llscale = 0.0;
- *rrscale = rlevel/rpan;
- }
- break;
- case(STEREO_PANNED):
- /* LEFT STEREO INPUT PANNED ... */
- if(lpan < -1.0) { /* VERY LEFT */
- *llscale = llevel /(-lpan);
- *lrscale = 0.0;
- } else if(lpan < 0.0) { /* LEFTWARDS */
- *llscale = llevel;
- *lrscale = llevel * (1.0+lpan);
- } else if(lpan <= 1.0) { /* RIGHTWARDS */
- *llscale = llevel * (1.0-lpan);
- *lrscale = llevel;
- } else { /* VERY RIGHT */
- *llscale = 0.0;
- *lrscale = llevel/lpan;
- }
- /* RIGHT STEREO INPUT PANNED ... */
- if(rpan < -1.0) { /* VERY LEFT */
- *rlscale = rlevel/(-rpan);
- *rrscale = 0.0;
- } else if(rpan < 0.0) { /* LEFTWARDS */
- *rlscale = rlevel;
- *rrscale = rlevel * (1.0+rpan);
- } else if(rpan <= 1.0) { /* RIGHTWARDS */
- *rlscale = rlevel * (1.0-rpan);
- *rrscale = rlevel ;
- } else { /* VERY RIGHT */
- *rlscale = 0.0;
- *rrscale = rlevel/rpan;
- }
- break;
- default:
- sprintf(errstr,"Unknown case in assign_scaling()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- #endif
- /************************** CHECK_RIGHT_LEVEL ************************/
- int check_right_level(char *str,double *rlevel,int filecnt)
- {
- if(is_dB(str)) {
- if(!get_leveldb(str,rlevel)) {
- sprintf(errstr,"Error1 scanning chan2 level: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- } else {
- if(sscanf(str,"%lf",rlevel)!=1) {
- sprintf(errstr,"Error2 scanning chan2 level: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- }
- if(*rlevel < 0.0) {
- sprintf(errstr,"Error3 scanning chan2 level: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /*********************** CHECK_RIGHT_PAN **********************/
- int check_right_pan(char *str,double *pan,int filecnt)
- {
- switch(str[0]) {
- case('L'): *pan = -1.0; break;
- case('R'): *pan = 1.0; break;
- case('C'): *pan = 0.5; break;
- default:
- if(sscanf(str,"%lf",pan)!=1) {
- sprintf(errstr,"Error1 scanning chan2 pan: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- if(*pan < MINPAN || *pan > MAXPAN) {
- sprintf(errstr,"Error2 scanning chan2 pan: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- break;
- }
- return(FINISHED);
- }
- /************************** CHECK_LEFT_PAN ************************/
- int check_left_pan(char *str,double *pan,int filecnt)
- {
- switch(str[0]) {
- case('L'): *pan = -1.0; break;
- case('R'): *pan = 1.0; break;
- case('C'): *pan = 0.0; break;
- default:
- if(sscanf(str,"%lf",pan)!=1) {
- sprintf(errstr,"Error1 scanning (chan1) pan: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- if(*pan < MINPAN || *pan > MAXPAN) {
- sprintf(errstr,"Error2 scanning (chan1) pan: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- }
- return(FINISHED);
- }
- /*************** CHECK_LEFT_LEVEL ******************/
- int check_left_level(char *str,double *level,int filecnt)
- {
- if(is_dB(str)) {
- if(!get_leveldb(str,level)) {
- sprintf(errstr,"Error1 scanning (chan1) level: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- } else {
- if(sscanf(str,"%lf",level)!=1) {
- sprintf(errstr,"Error2 scanning (chan1) level: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- }
- if(*level < 0.0) {
- sprintf(errstr,"Error3 scanning (chan1) level: line %d\n",filecnt+1);
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /************************** UNMARK_BUF ***************************/
- int unmark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize)
- {
- int exit_status;
- int mask = 1;
- int z = thisbuf/longbitsize;
- /* 1998 --> */
- if(z >= *bufsflagcnt) {
- if((exit_status = reallocate_bufsflag(z,bufsflag,bufsflagcnt))<0)
- return(exit_status);
- }
- /* <-- 1998 */
- thisbuf -= (z * longbitsize);
- mask <<= thisbuf;
- mask = ~mask;
- (*bufsflag)[z] &= mask;
- return(FINISHED);
- }
- /************************** MARK_BUF ***************************
- *
- * (1) Which int is the appropriate byte in.
- * (2) What is it's index into this int.
- * (3) Move mask along the int.
- * (4) Set bit.
- * (5) Keep note of max number of bufs in use.
- */
- int mark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize,dataptr dz)
- {
- int exit_status;
- int mask = 1;
- int z = thisbuf/longbitsize; /* 1 */
- /* 1998 --> */
- if(z >= *bufsflagcnt) {
- if((exit_status = reallocate_bufsflag(z,bufsflag,bufsflagcnt))<0)
- return(exit_status);
- }
- /* <-- 1998 */
- if(thisbuf > dz->bufcnt)
- dz->bufcnt = thisbuf;
- thisbuf -= (z * longbitsize); /* 2 */
- mask <<= thisbuf; /* 3 */
- (*bufsflag)[z] |= mask; /* 4 */
- return(FINISHED);
- }
- /**************************** REALLOCATE_BUFSFLAG ********************************/
- int reallocate_bufsflag(int z,int **bufsflag,int *bufsflagcnt)
- {
- int n;
- if(*bufsflagcnt==0)
- // *bufsflag = (int *) malloc((z+1) * sizeof(int));
- *bufsflag = (int *) calloc((z+1),sizeof(int)); //RWD 2013 needs init values
- else if((*bufsflag = (int *)realloc(*bufsflag,(z+1) * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for buffer flags store.\n");
- return(MEMORY_ERROR);
- }
- for(n=*bufsflagcnt;n<z;n++)
- *bufsflag[n] = 0;
- *bufsflagcnt = z+1;
- return(FINISHED);
- }
- /**************************** MIX_MODEL ********************************/
- int mix_model(dataptr dz)
- {
- int n, m, k;
- int total_words = 0,filestart;
- char temp[200];
- filestart = dz->itemcnt;
- for(n=0,k=filestart;n<dz->linecnt;n++,k++) {
- for(m = 0;m < dz->wordcnt[n];m++) {
- if(m==0)
- strcpy(temp,dz->wordstor[k]);
- else {
- strcat(temp," ");
- strcat(temp,dz->wordstor[total_words]);
- }
- total_words++;
- }
- strcat(temp,"\n");
- if(fputs(temp,dz->fp)<0) {
- sprintf(errstr,"Failed to print new mixfile line %d to output file.\n",n+1);
- return(SYSTEM_ERROR);
- }
- }
- return FINISHED;
- }
|