/* * 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 static int do_up_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf, int *lastzero,int *bufcrosing,int *obufpos,dataptr dz); static int do_dn_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf, int *lastzero,int *bufcrosing,int *obufpos,dataptr dz); static int do_cycle_loud(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz); static int do_cycle_quiet(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz); static int do_cycle_loud_crosbuf(int cyclecnt,int current_buf,int current_pos_in_buf, int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz); static int do_cycle_quiet_crosbuf(int cyclecnt,int current_buf,int current_pos_in_buf, int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz); static int get_loudest_cycle(int cyclecnt,dataptr dz); static int get_quietest_cycle(int cyclecnt,dataptr dz); static int write_cycle(int start, int end,float *buf,int *obufpos,dataptr dz); /********************************** DISTORT_DEL ******************************/ int distort_del (int *current_buf,int *current_pos_in_buf,int phase,int *obufpos,int *cnt,dataptr dz) { int exit_status; int n; float *b = dz->sampbuf[*current_buf]; int bufcrosing = FALSE; int lastzero = *current_pos_in_buf; switch(phase) { case(1): if((exit_status = do_up_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); if((exit_status = do_dn_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); break; case(-1): if((exit_status = do_dn_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); if((exit_status = do_up_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); break; } if((*current_pos_in_buf - lastzero)!=0) { if((exit_status = write_cycle(lastzero,*current_pos_in_buf,b,obufpos,dz))<0) return(exit_status); } lastzero = *current_pos_in_buf; for(n=0;niparam[DISTDEL_CYCLECNT];n++) { /* FOR NUMBER OF UNWANTED CYCLES */ switch(phase) { case(1): if((exit_status = do_up_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); if((exit_status = do_dn_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); break; case(-1): if((exit_status = do_dn_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); if((exit_status = do_up_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE) return(exit_status); break; } } (*cnt)++; return(CONTINUE); } /******************************* DISTORT_DEL_WITH_LOUDNESS ******************************/ int distort_del_with_loudness(int *current_buf,int phase,int *obufpos,int *current_pos_in_buf,int *cnt,dataptr dz) { int exit_status = CONTINUE; int cyclecnt = 0; /* RWD added init */ //TW CONFIRM DELETE *int bufcross = 0; register int i = *current_pos_in_buf; //TW CONFIRM DELETE int cyclestart = i; float *b = dz->sampbuf[*current_buf]; int cycleno_in_group_at_bufcros = -1; switch(phase) { case(1): for(cyclecnt=0;cyclecntiparam[DISTDEL_CYCLECNT];cyclecnt++) { /* RWD 4:2002 use lfarray as this now contains amplitudes */ dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] = 0.0; dz->lparray[DISTDEL_STARTCYC][cyclecnt] = i; while(b[i]>=0) { dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] += b[i]; if(++i >= dz->ssampsread) { if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0) return(exit_status); cycleno_in_group_at_bufcros = cyclecnt; if(exit_status !=CONTINUE) break; i = 0; } } if(exit_status !=CONTINUE) break; while(b[i]<=0.0) { dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] -= b[i]; if(++i >= dz->ssampsread) { if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0) return(exit_status); cycleno_in_group_at_bufcros = cyclecnt; if(exit_status !=CONTINUE) break; i = 0; } } if(exit_status !=CONTINUE) break; } break; case(-1): for(cyclecnt=0;cyclecntiparam[DISTDEL_CYCLECNT];cyclecnt++) { dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] = 0.0; dz->lparray[DISTDEL_STARTCYC][cyclecnt] = i; while(b[i]<=0.0) { dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] -= b[i]; if(++i >= dz->ssampsread) { if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0) return(exit_status); cycleno_in_group_at_bufcros = cyclecnt; if(exit_status !=CONTINUE) break; i = 0; } } if(exit_status !=CONTINUE) break; while(b[i]>=0.0) { dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] += b[i]; if(++i >= dz->ssampsread) { if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0) return(exit_status); cycleno_in_group_at_bufcros = cyclecnt; if(exit_status !=CONTINUE) break; i = 0; } } if(exit_status !=CONTINUE) break; } break; } if(cyclecnt) { if(cycleno_in_group_at_bufcros >= 0) { /* cycle set crosses between buffers */ switch(dz->mode) { case(KEEP_STRONGEST): if((exit_status = do_cycle_loud_crosbuf(cyclecnt,*current_buf,i,cycleno_in_group_at_bufcros,obufpos,dz))<0) return(exit_status); break; case(DELETE_WEAKEST): if((exit_status = do_cycle_quiet_crosbuf(cyclecnt,*current_buf,i,cycleno_in_group_at_bufcros,obufpos,dz))<0) return(exit_status); break; } } else { switch(dz->mode) { case(KEEP_STRONGEST): if((exit_status = do_cycle_loud(b,cyclecnt,i,obufpos,dz))<0) return(exit_status); break; case(DELETE_WEAKEST): if((exit_status = do_cycle_quiet(b,cyclecnt,i,obufpos,dz))<0) return(exit_status); break; } } } *current_pos_in_buf = i; (*cnt)++; return(exit_status); } /*************************** DO_UP_CYCLE ******************************/ int do_up_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf, int *lastzero,int *bufcrosing,int *obufpos,dataptr dz) { int exit_status; while((*buf)[*current_pos_in_buf]>=0.0) { if(++(*current_pos_in_buf) >= dz->ssampsread) { if(keep_or_loose ==KEEP) { if((exit_status= write_cycle(*lastzero,*current_pos_in_buf,*buf,obufpos,dz))< 0) return(exit_status); } if((exit_status = change_buf(current_buf,bufcrosing,buf,dz))!=CONTINUE) return(exit_status); *lastzero = *current_pos_in_buf = 0; } } return(CONTINUE); } /************************* DO_DN_CYCLE ******************************/ int do_dn_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf, int *lastzero,int *bufcrosing,int *obufpos,dataptr dz) { int exit_status; while((*buf)[*current_pos_in_buf]<=0.0) { if(++(*current_pos_in_buf) >= dz->ssampsread) { if(keep_or_loose ==KEEP) { if((exit_status= write_cycle(*lastzero,*current_pos_in_buf,*buf,obufpos,dz))< 0) return(exit_status); } if((exit_status = change_buf(current_buf,bufcrosing,buf,dz))!=CONTINUE) return(exit_status); *lastzero = *current_pos_in_buf = 0; } } return(CONTINUE); } /************************ DO_CYCLE_LOUD **************************/ int do_cycle_loud(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz) { int loudest = get_loudest_cycle(cyclecnt,dz); dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf; return write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz); } /************************ DO_CYCLE_LOUD_CROSBUF **************************/ int do_cycle_loud_crosbuf (int cyclecnt,int current_buf,int current_pos_in_buf,int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz) { int exit_status; int loudest; float *buf; loudest = get_loudest_cycle(cyclecnt,dz); dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf; if(cycleno_in_group_at_bufcros == loudest) { buf = dz->sampbuf[!current_buf]; /* GO TO PREVIOUS BUFFER */ if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->buflen,buf,obufpos,dz))<0) return(exit_status); buf = dz->sampbuf[current_buf]; exit_status = write_cycle(0L,dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz); } else if (cycleno_in_group_at_bufcros > loudest) { buf = dz->sampbuf[!current_buf]; /* GO TO PREVIOUS BUFFER */ exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz); } else { buf = dz->sampbuf[current_buf]; /* GO TO PREVIOUS BUFFER */ exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz); } return(exit_status); } /************************ GET_LOUDEST_CYCLE ******************************* * * Find loudest cycle. */ int get_loudest_cycle(int cyclecnt,dataptr dz) { int /*ffcycle = 0,*/ position = 0; float ffcycle = 0.0; int n; for(n=0;nlfarray[DISTDEL_CYCLEVAL][n] > ffcycle) { ffcycle = dz->lfarray[DISTDEL_CYCLEVAL][n]; position = n; } } return(position); } /***************************** DO_CYCLE_QUIET *************************/ int do_cycle_quiet(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz) { int exit_status; int quietest = get_quietest_cycle(cyclecnt,dz); dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf; if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0) return(exit_status); return write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz); } /************************** DO_CYCLE_QUIET_CROSBUF *************************/ int do_cycle_quiet_crosbuf (int cyclecnt,int current_buf,int current_pos_in_buf,int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz) { int exit_status; int quietest = get_quietest_cycle(cyclecnt,dz); float *buf; dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf; if(cycleno_in_group_at_bufcros == quietest) { buf = dz->sampbuf[!current_buf]; if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0) return(exit_status); buf = dz->sampbuf[current_buf]; exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz); } else if(cycleno_in_group_at_bufcros > quietest) { buf = dz->sampbuf[!current_buf]; if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0) return(exit_status); if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->buflen,buf,obufpos,dz))<0) return(exit_status); buf = dz->sampbuf[current_buf]; exit_status = write_cycle(0L,dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz); } else { buf = dz->sampbuf[!current_buf]; if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->buflen,buf,obufpos,dz))<0) return(exit_status); buf = dz->sampbuf[current_buf]; if((exit_status = write_cycle(0L,dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0) return(exit_status); exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz); } return(exit_status); } /************************ GET_QUIETEST_CYCLE ******************************* * * Find quietest cycle. */ int get_quietest_cycle(int cyclecnt,dataptr dz) { //TW FIXED // int quiestest_cycle = dz->lparray[DISTDEL_CYCLEVAL][0], position = 0; float quiestest_cycle = dz->lfarray[DISTDEL_CYCLEVAL][0]; int position = 0; int n; for(n=1;nlfarray[DISTDEL_CYCLEVAL][n] < quiestest_cycle) { quiestest_cycle = dz->lfarray[DISTDEL_CYCLEVAL][n]; position = n; } } return(position); } /***************************** WRITE_CYCLE **********************************/ int write_cycle(int start,int end,float *buf,int *obufpos,dataptr dz) { int exit_status; float *obuf = dz->sampbuf[2] + *obufpos; int partoutbuf = dz->buflen - *obufpos; /* FIND HOW MUCH ROOM LEFT IN OUTBUF */ int insamps_to_write = end - start; /* FIND HOW MANY SAMPLES TO WRITE */ int outoverflow; /* IF SAMPS-TO-WRITE WON'T FIT IN OUTBUF */ buf += start; while((outoverflow = insamps_to_write - partoutbuf) > 0) { memmove((char *)obuf,(char *)buf,partoutbuf * sizeof(float)); obuf = dz->sampbuf[2]; buf += partoutbuf; if((exit_status = write_samps(obuf,dz->buflen,dz))<0) return(exit_status); *obufpos = 0; insamps_to_write = outoverflow; partoutbuf = dz->buflen; } memmove((char *)obuf,(char *)buf,insamps_to_write * sizeof(float)); *obufpos += insamps_to_write; return(CONTINUE); }