|
|
@@ -0,0 +1,1391 @@
|
|
|
+/*
|
|
|
+ * 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
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <structures.h>
|
|
|
+#include <tkglobals.h>
|
|
|
+#include <globcon.h>
|
|
|
+#include <pnames.h>
|
|
|
+#include <modeno.h>
|
|
|
+#include <arrays.h>
|
|
|
+#include <flags.h>
|
|
|
+#include <blur.h>
|
|
|
+#include <cdpmain.h>
|
|
|
+#include <formants.h>
|
|
|
+#include <speccon.h>
|
|
|
+#include <sfsys.h>
|
|
|
+#include <osbind.h>
|
|
|
+#include <string.h>
|
|
|
+#include <blur.h>
|
|
|
+
|
|
|
+#define FIRST_ACCESS_OF_RANDTABLE_REACHES_END_FIRST (1)
|
|
|
+#define SECOND_ACCESS_OF_RANDTABLE_REACHES_END_FIRST (2)
|
|
|
+#define BOTH_ACCESSES_OF_RANDTABLE_REACH_END_TOGETHER (0)
|
|
|
+
|
|
|
+static int randomly_select_blokstokeep_and_sort_in_ascending_order(dataptr dz);
|
|
|
+static int delete_unwanted_bloks(dataptr dz);
|
|
|
+static int insert(int k,int n,int *iarray,int permcnt);
|
|
|
+static int shuflup(int n,int * iarray,int permcnt);
|
|
|
+static int read_domain_samps(int *reached_end_of_file,int *ssampsread,int windows_wanted,dataptr dz);
|
|
|
+static int copy_domain_to_domainbuf(int *reached_end_of_infile,int *ssampsread,int bufwlen,int permcnt,
|
|
|
+ int shuf_d_windows,float *dbufptr,float *dbufend,dataptr dz);
|
|
|
+static int copywindows_from_domain_to_image(float *domainbuf,float * dbufend,dataptr dz);
|
|
|
+static int get_randplace(int *randh,int *rande,dataptr dz);
|
|
|
+static int get_other_randplace(int *order,int randh,int rande,int *randh2,int *rande2,dataptr dz);
|
|
|
+static int chorusing(int cc,int cc2,int randend,int randend2,int order,dataptr dz);
|
|
|
+static int do_afix_ffix(int *cc,int *cc2,int *vc,dataptr dz);
|
|
|
+static int do_a(int cc,int vc,int randend,dataptr dz);
|
|
|
+static int do_fvar(int cc,int vc,int randend,dataptr dz);
|
|
|
+static int do_afix_f(int *cc,int *cc2,int *vc,dataptr dz);
|
|
|
+static int do_a_ffix(int *cc,int *cc2,int *vc,dataptr dz);
|
|
|
+static int do_a_f(int *cc,int *cc2,int *vc,dataptr dz);
|
|
|
+static int do_afix(int cc,int vc,int randend, dataptr dz);
|
|
|
+static int do_ffix(int cc,int vc,int randend,dataptr dz);
|
|
|
+static int getnewfrq_choru(int cc,int vc,dataptr dz);
|
|
|
+static int getnewfrq2_choru(int cc,int vc,dataptr dz);
|
|
|
+static int get_sbufposition_corresponding_to_frq(int *channo,double frq,dataptr dz);
|
|
|
+static int advance_to_starttime(float **inputbuf_end,int *samps_read,int *drnk_bufno,dataptr dz);
|
|
|
+static int copy_window_to_outbuf(dataptr dz);
|
|
|
+static int get_randstep(int *step,dataptr dz);
|
|
|
+static int adjust_buffers(int *step,float **inputbuf_end,int *samps_read,int *drnk_bufno, dataptr dz);
|
|
|
+static int flush_outbuf(dataptr dz);
|
|
|
+static int invert_step_back_to_step_fwd_at_start_of_file(int *step,int reflect_off_end,dataptr dz);
|
|
|
+static int place_sbufptr_in_bigbuf_range(int *bigbufs_baktrak,dataptr dz);
|
|
|
+static int invert_step_back_to_step_fwd(int *step,float *orig_sbuf,int *samps_read,
|
|
|
+ float **inputbuf_end, int reflect_off_end,int drnk_bufno,dataptr dz);
|
|
|
+static int baktrak_to_correct_bigbuf(int bigbufs_baktrak,int *samps_read,float **inputbuf_end,
|
|
|
+ int *drnk_bufno,dataptr dz);
|
|
|
+static int invert_step_fwd_to_step_back_at_end_of_file(int *step,int reflect_off_start,int drnk_bufno,dataptr dz);
|
|
|
+static int advance_to_correct_bigbuf(float **inputbuf_end,int *samps_read,int *drnk_bufno,dataptr dz);
|
|
|
+static int invert_step_fwd_to_step_back(int *step,float *orig_sbuf,int *samps_read,
|
|
|
+ float **inputbuf_end,int reflect_off_start,int drnk_bufno,dataptr dz);
|
|
|
+static int read_first_inbuf(dataptr dz);
|
|
|
+static int wrap_samps(unsigned int wrapsamps,float **insbuf,dataptr dz);
|
|
|
+static int copy_1st_window(dataptr dz);
|
|
|
+
|
|
|
+/********************************** SPECAVRG **********************************/
|
|
|
+
|
|
|
+int specavrg(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int cc, vc, k=0, n, m, q;
|
|
|
+ if(dz->brksize[AVRG_AVRG]) {
|
|
|
+ dz->iparam[AVRG_AVRGSPAN] = dz->iparam[AVRG_AVRG]/2;
|
|
|
+ dz->iparam[AVRG_AVRG] = (dz->iparam[AVRG_AVRGSPAN] * 2) + 1; /* always odd */
|
|
|
+ }
|
|
|
+ if(dz->iparam[AVRG_AVRGSPAN]>0) {
|
|
|
+ if((exit_status = get_amp(dz->flbufptr[0],dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ for(cc = 0, vc = 0; cc < dz->iparam[AVRG_AVRGSPAN]; cc++, vc+=2) {
|
|
|
+ dz->amp[cc] = 0.0f;
|
|
|
+ k = cc + dz->iparam[AVRG_AVRGSPAN] + 1; /* SMALL AVERAGE AT BOTTOM */
|
|
|
+ for(n = 0, m = 0; n < k; n++, m += 2)
|
|
|
+ dz->amp[cc] = (float)(dz->amp[cc] + dz->flbufptr[0][m]);
|
|
|
+ dz->amp[cc] = (float)(dz->amp[cc]/(double)(k));
|
|
|
+ }
|
|
|
+ q = dz->clength - dz->iparam[AVRG_AVRGSPAN];
|
|
|
+ m = dz->iparam[AVRG_AVRGSPAN] * 2;
|
|
|
+ for(cc = dz->iparam[AVRG_AVRGSPAN], vc = m; cc < q; cc++, vc += 2) {
|
|
|
+ dz->amp[cc] = 0.0f; /* TRUE AVERAGE */
|
|
|
+ for(n = vc - m;n <= vc + m; n += 2)
|
|
|
+ dz->amp[cc] = (float)(dz->amp[cc] + dz->flbufptr[0][n]);
|
|
|
+ dz->amp[cc] = (float)(dz->amp[cc]/(double)dz->iparam[AVRG_AVRG]);
|
|
|
+ }
|
|
|
+ for(cc = q, vc = k*q; cc < dz->clength; cc++, vc+=2) {
|
|
|
+ dz->amp[cc] = 0.0f;
|
|
|
+ k = cc - dz->iparam[AVRG_AVRGSPAN]; /* SMALL AVERAGE AT TOP */
|
|
|
+ for(n = k, m = k*2; n < dz->clength; n++, m += 2)
|
|
|
+ dz->amp[cc] = (float)(dz->amp[cc] + dz->flbufptr[0][m]);
|
|
|
+ dz->amp[cc] = (float)(dz->amp[cc]/(double)(dz->clength-k));
|
|
|
+ }
|
|
|
+ if((exit_status = put_amp(dz->flbufptr[0],dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** SPECSUPR *****************************/
|
|
|
+
|
|
|
+int specsupr(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ chvptr quietest, loudest;
|
|
|
+ int invtrindex, vc;
|
|
|
+ if(dz->iparam[SUPR_INDX]>(dz->clength/2)) { /* IF MORE CHANS TO SUPPRESS THAN TO KEEP */
|
|
|
+ invtrindex = dz->clength - dz->iparam[SUPR_INDX];
|
|
|
+ if((exit_status = initialise_ring_vals(invtrindex,BIGAMP,dz))<0) /* PRESET RING VALS TO MAX */
|
|
|
+ return(exit_status);
|
|
|
+ for(vc = 0; vc < dz->wanted; vc += 2) { /* IF QUIETER THAN PREVIOUS CHANS, STORE */
|
|
|
+ if((exit_status = if_one_of_quietest_chans_store_in_ring(vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ dz->flbufptr[0][vc] = 0.0f; /* ZERO ALL CHANNELS AS WE GO */
|
|
|
+ }
|
|
|
+ quietest = dz->ringhead;
|
|
|
+ do { /* REINSERT AMP OF QUIETEST CHANS ONLY */
|
|
|
+ dz->flbufptr[0][quietest->loc] = quietest->val;
|
|
|
+ } while((quietest = quietest->next)!=dz->ringhead);
|
|
|
+ } else { /* IF MORE CHANS TO KEEP THAN TO SUPPRESS */
|
|
|
+ if((exit_status = initialise_ring_vals(dz->iparam[SUPR_INDX],-BIGAMP,dz))<0)
|
|
|
+ return(exit_status); /* PRESET RING VALS TO MIN */
|
|
|
+ for(vc = 0; vc < dz->wanted; vc += 2) {
|
|
|
+ if((exit_status = if_one_of_loudest_chans_store_in_ring(vc,dz))<0)
|
|
|
+ return(exit_status); /* IF LOUDER THAN PREVIOUS CHANS, STORE */
|
|
|
+ }
|
|
|
+ loudest = dz->ringhead;
|
|
|
+ do {
|
|
|
+ dz->flbufptr[0][loudest->loc] = 0.0f; /* ZERO AMPLITUDE IN LOUDEST CHANNELS ONLY */
|
|
|
+ } while((loudest = loudest->next)!=dz->ringhead);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************ SPECSCAT *****************************/
|
|
|
+
|
|
|
+int specscat(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ double pre_totalamp = 0.0, post_totalamp;
|
|
|
+ if(dz->brksize[SCAT_CNT])
|
|
|
+ dz->iparam[SCAT_THISCNT] = dz->iparam[SCAT_CNT];
|
|
|
+ if(dz->brksize[SCAT_BLOKSIZE]) {
|
|
|
+ dz->iparam[SCAT_BLOKS_PER_WINDOW] = dz->clength/dz->iparam[SCAT_BLOKSIZE];
|
|
|
+ if((dz->iparam[SCAT_BLOKS_PER_WINDOW]*dz->iparam[SCAT_BLOKSIZE])!=dz->clength)
|
|
|
+ dz->iparam[SCAT_BLOKS_PER_WINDOW]++;
|
|
|
+ }
|
|
|
+ if((dz->brksize[SCAT_CNT] || dz->brksize[SCAT_BLOKSIZE])
|
|
|
+ && dz->iparam[SCAT_CNT] >= dz->iparam[SCAT_BLOKS_PER_WINDOW]) {
|
|
|
+ sprintf(errstr,"Blokcnt exceeds number of blocks per window at %.4lf secs\n",
|
|
|
+ dz->time - dz->frametime);
|
|
|
+ return(USER_ERROR);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!dz->vflag[SCAT_NO_NORM]) {
|
|
|
+ if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ if(dz->vflag[SCAT_RANDCNT])
|
|
|
+ dz->iparam[SCAT_THISCNT] = (int)((drand48() * dz->iparam[SCAT_CNT]) + 1.0); /* TRUNCATE */
|
|
|
+ if((exit_status = randomly_select_blokstokeep_and_sort_in_ascending_order(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = delete_unwanted_bloks(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if(!dz->vflag[SCAT_NO_NORM]) {
|
|
|
+ if((exit_status = get_totalamp(&post_totalamp,dz->flbufptr[0],dz->wanted))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = normalise(pre_totalamp,post_totalamp,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/********** RANDOMLY_SELECT_BLOKSTOKEEP_AND_SORT_IN_ASCENDING_ORDER **********
|
|
|
+ *
|
|
|
+ * (1) preset all SCAT_KEEP array vals to max.
|
|
|
+ * (2) insert blokno between 0 and SCAT_BLOKS_PER_WINDOW in 1st position in SCAT_KEEP array.
|
|
|
+ * (3) insert blokno between 0 and SCAT_BLOKS_PER_WINDOW in next position in SCAT_KEEP array.
|
|
|
+ * (4) ensure its a NEW value
|
|
|
+ * (5) if it's not a new value, try again.
|
|
|
+ * (6) order the existing new values
|
|
|
+ */
|
|
|
+
|
|
|
+int randomly_select_blokstokeep_and_sort_in_ascending_order(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int n, m, k, keepcnt, bad_value, inserted;
|
|
|
+ for(n=0;n<dz->clength+1;n++)
|
|
|
+ dz->iparray[SCAT_KEEP][n] = dz->clength+1; /* 1 */
|
|
|
+ k = (int)(drand48() * dz->iparam[SCAT_BLOKS_PER_WINDOW]);/* TRUNC */
|
|
|
+ dz->iparray[SCAT_KEEP][0] = k; /* 2 */
|
|
|
+ keepcnt = 1;
|
|
|
+ for(n=1;n<dz->iparam[SCAT_THISCNT];n++) {
|
|
|
+ k = (int)(drand48() * dz->iparam[SCAT_BLOKS_PER_WINDOW]);/* TRUNC */ /* 3 */
|
|
|
+ bad_value = 0;
|
|
|
+ inserted = 0;
|
|
|
+ for(m=0;m<keepcnt;m++) { /* 4 */
|
|
|
+ if(k==dz->iparray[SCAT_KEEP][m]) {
|
|
|
+ bad_value = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } /* 5 */
|
|
|
+ if(bad_value) {
|
|
|
+ n--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for(m=0;m<keepcnt;m++) { /* 6 */
|
|
|
+ if(k<dz->iparray[SCAT_KEEP][m]) {
|
|
|
+ if((exit_status = insert(k,m,dz->iparray[SCAT_KEEP],keepcnt))<0)
|
|
|
+ return(exit_status);
|
|
|
+ inserted = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(!inserted)
|
|
|
+ dz->iparray[SCAT_KEEP][keepcnt] = k;
|
|
|
+ keepcnt++;
|
|
|
+ }
|
|
|
+ if(keepcnt!=dz->iparam[SCAT_THISCNT]) {
|
|
|
+ sprintf(errstr,"Error in perm arithmetic.randomly_select_blokstokeep_and_sort_in_ascending_order()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** DELETE_UNWANTED_BLOKS *****************************/
|
|
|
+
|
|
|
+int delete_unwanted_bloks(dataptr dz)
|
|
|
+{
|
|
|
+ int this_blok = 0; /* INDEX TO BLKS TO RETAIN */
|
|
|
+ int n, c_end, vc_end;
|
|
|
+ int cc = 0, vc;
|
|
|
+ for(n = 0; n < dz->iparam[SCAT_BLOKS_PER_WINDOW]; n++) {
|
|
|
+ if(n==dz->iparray[SCAT_KEEP][this_blok]) { /* If keeping it */
|
|
|
+ if((cc += dz->iparam[SCAT_BLOKSIZE]) >= dz->clength)/* Jump over it, and, if at window end, break */
|
|
|
+ break;
|
|
|
+ if(++this_blok >= dz->iparam[SCAT_THISCNT]) { /* If at end of kept bloks */
|
|
|
+ vc = cc * 2;
|
|
|
+ while(vc < dz->wanted) { /* zero any remaining chans */
|
|
|
+ dz->flbufptr[0][AMPP] = 0.0F;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else { /* if NOT keeping it */
|
|
|
+ if((c_end = cc + dz->iparam[SCAT_BLOKSIZE]) >= dz->clength)
|
|
|
+ c_end = dz->clength; /* mark end of blok */
|
|
|
+ vc = cc * 2;
|
|
|
+ vc_end = c_end * 2;
|
|
|
+ while(vc < vc_end) { /* zero it */
|
|
|
+ dz->flbufptr[0][AMPP] = 0.0F;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ if(vc >= dz->wanted) /* If at window end, break */
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** INSERT ***************************/
|
|
|
+
|
|
|
+int insert(int k,int n,int *iarray,int permcnt)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ if((exit_status = shuflup(n,iarray,permcnt))<0)
|
|
|
+ return(exit_status);
|
|
|
+ iarray[n] = k;
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** SHUFLUP ***************************/
|
|
|
+
|
|
|
+int shuflup(int n,int * iarray,int permcnt)
|
|
|
+{
|
|
|
+ int z = permcnt;
|
|
|
+ while(z > n) {
|
|
|
+ iarray[z] = iarray[z-1];
|
|
|
+ z--;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/**************************** SPECSPREAD ***************************/
|
|
|
+
|
|
|
+int specspread(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int cc, vc;
|
|
|
+ double specenv_amp, ampdiff, pre_totalamp, post_totalamp;
|
|
|
+ rectify_window(dz->flbufptr[0],dz);
|
|
|
+ if((exit_status = extract_specenv(0,0,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
|
|
|
+ return(exit_status);
|
|
|
+ for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2) {
|
|
|
+ if((exit_status = getspecenvamp(&specenv_amp,(double)dz->flbufptr[0][FREQ],0,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ ampdiff = specenv_amp - dz->flbufptr[0][AMPP];
|
|
|
+ dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] + (ampdiff * dz->param[SPREAD_SPRD]));
|
|
|
+ }
|
|
|
+ if((exit_status = get_totalamp(&post_totalamp,dz->flbufptr[0],dz->wanted))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = normalise(pre_totalamp,post_totalamp,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/******************************** SPECSHUFFLE *****************************/
|
|
|
+
|
|
|
+int specshuffle(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int permcnt = 0, ssampsread;
|
|
|
+ int shuf_d_windows = dz->iparam[SHUF_DMNCNT] * dz->iparam[SHUF_GRPSIZE];
|
|
|
+ int bufwlen = dz->buflen/dz->wanted;
|
|
|
+ float *domainbuf, *dbufptr, *dbufend;
|
|
|
+ int reached_end_of_infile = FALSE;
|
|
|
+ int min_windows_to_get = min(shuf_d_windows+1,bufwlen);
|
|
|
+ dz->flbufptr[0] = dz->bigfbuf;
|
|
|
+ dz->flbufptr[1] = dz->flbufptr[2];
|
|
|
+ if(sloom)
|
|
|
+ dz->total_samps_read = 0;
|
|
|
+ if((domainbuf = (float *)malloc((size_t)(shuf_d_windows * (dz->wanted * sizeof(float)))))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY for domain buffer.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ dbufptr = domainbuf;
|
|
|
+ dbufend = domainbuf + (shuf_d_windows * dz->wanted);
|
|
|
+
|
|
|
+ if((exit_status = read_domain_samps(&reached_end_of_infile,&ssampsread,min_windows_to_get,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if(exit_status == FINISHED) {
|
|
|
+ sprintf(errstr,"Insufficient data in soundfile to do this shuffle.\n");
|
|
|
+ return(GOAL_FAILED);
|
|
|
+ }
|
|
|
+
|
|
|
+ copy_1st_window(dz);
|
|
|
+ for(;;) {
|
|
|
+ dbufptr = domainbuf;
|
|
|
+ if((exit_status = copy_domain_to_domainbuf
|
|
|
+ (&reached_end_of_infile,&ssampsread,bufwlen,permcnt,shuf_d_windows,dbufptr,dbufend,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if(exit_status==FINISHED)
|
|
|
+ break;
|
|
|
+ copywindows_from_domain_to_image(domainbuf,dbufend,dz);
|
|
|
+ permcnt++;
|
|
|
+ }
|
|
|
+ if(dz->flbufptr[1] > dz->flbufptr[2])
|
|
|
+ return write_samps(dz->flbufptr[2],(dz->flbufptr[1] - dz->flbufptr[2]),dz);
|
|
|
+ return(FINISHED);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/********************** READ_DOMAIN_SAMPS *******************/
|
|
|
+
|
|
|
+int read_domain_samps(int *reached_end_of_file,int *ssampsread,int windows_wanted,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+
|
|
|
+ if((exit_status = read_samps(dz->bigfbuf,dz)) < 0)
|
|
|
+ return exit_status;
|
|
|
+ if(dz->ssampsread < windows_wanted * dz->wanted)
|
|
|
+ return(FINISHED);
|
|
|
+ *ssampsread = dz->ssampsread;
|
|
|
+ if(dz->ssampsread < dz->buflen)
|
|
|
+ *reached_end_of_file = TRUE;
|
|
|
+ return(CONTINUE);
|
|
|
+}
|
|
|
+
|
|
|
+/********************** COPY_DOMAIN_TO_DOMAINBUF *******************/
|
|
|
+
|
|
|
+int copy_domain_to_domainbuf
|
|
|
+(int *reached_end_of_infile,int *ssampsread,int bufwlen,int permcnt,int shuf_d_windows,
|
|
|
+ float *dbufptr,float *dbufend,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int n, windows_needed;
|
|
|
+ float *data_end;
|
|
|
+ if(reached_end_of_infile)
|
|
|
+ data_end = dz->bigfbuf + *ssampsread;
|
|
|
+ else
|
|
|
+ data_end = dz->flbufptr[2];
|
|
|
+ for(n=0;n<shuf_d_windows;n++) {
|
|
|
+ if(dbufptr >= dbufend) {
|
|
|
+ sprintf(errstr,"Error in buffer arithmetic: specshuffle()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->flbufptr[0] >= data_end) {
|
|
|
+ if(!(*reached_end_of_infile)) {
|
|
|
+ windows_needed = min(shuf_d_windows-n,bufwlen);
|
|
|
+ if((exit_status = read_domain_samps(reached_end_of_infile,ssampsread,windows_needed,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if(*reached_end_of_infile)
|
|
|
+ data_end = dz->bigfbuf + *ssampsread;
|
|
|
+ dz->flbufptr[0] = dz->bigfbuf;
|
|
|
+ } else
|
|
|
+ exit_status = FINISHED;
|
|
|
+ if(exit_status==FINISHED) {
|
|
|
+ if(permcnt==0) {
|
|
|
+ sprintf(errstr,"Insufficient data in soundfile to do this shuffle.\n");
|
|
|
+ return(GOAL_FAILED);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ memmove((char *)dbufptr,(char *)dz->flbufptr[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ dbufptr += dz->wanted;
|
|
|
+ dz->flbufptr[0] += dz->wanted;
|
|
|
+ }
|
|
|
+ return(CONTINUE);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** COPYWINDOWS_FROM_DOMAIN_TO_IMAGE ********************************/
|
|
|
+
|
|
|
+int copywindows_from_domain_to_image(float *domainbuf,float * dbufend,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int n, m;
|
|
|
+ float *srcptr;
|
|
|
+ for(n=0;n<dz->iparam[SHUF_IMGCNT];n++) {
|
|
|
+ srcptr = domainbuf + (dz->iparray[SHUF_MAP][n] * dz->iparam[SHUF_GRPSIZE] * dz->wanted);
|
|
|
+ for(m=0;m < dz->iparam[SHUF_GRPSIZE]; m++) {
|
|
|
+ if(srcptr >= dbufend) {
|
|
|
+ sprintf(errstr,"Error in buffer arithmetic: copywindows_from_domain_to_image()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->flbufptr[1] >= dz->flbufptr[3]) {
|
|
|
+ if((exit_status = write_exact_samps(dz->flbufptr[2],dz->buflen,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ dz->flbufptr[1] = dz->flbufptr[2];
|
|
|
+ }
|
|
|
+ memmove((char *)dz->flbufptr[1],(char *)srcptr,(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ srcptr += dz->wanted;
|
|
|
+ dz->flbufptr[1] += dz->wanted;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************* SPECCHORUS ***************************/
|
|
|
+
|
|
|
+int specchorus(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ //TW cc2 is never set for modes other than CH_AMP_FRQ, CH_AMP_FRQ_UP, CH_AMP_FRQ_DN
|
|
|
+ int cc, cc2 = 0, order = 0;
|
|
|
+ int randhere = 0, randhere2 = 0, randend = 0, randend2 = 0;
|
|
|
+ double pre_totalamp = 0.0, post_totalamp;
|
|
|
+ if((exit_status = get_randplace(&randhere,&randend,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ cc = randhere;
|
|
|
+ if(dz->mode == CH_AMP_FRQ || dz->mode == CH_AMP_FRQ_UP || dz->mode == CH_AMP_FRQ_DN) {
|
|
|
+ if((exit_status = get_other_randplace(&order,randhere,randend,&randhere2,&randend2,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ cc2 = randhere2;
|
|
|
+ }
|
|
|
+ if(dz->iparam[CHORU_SPRTYPE]!=F_VAR && dz->iparam[CHORU_SPRTYPE]!=F_FIX) {
|
|
|
+ if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ if((exit_status = chorusing(cc,cc2,randend,randend2,order,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if(dz->iparam[CHORU_SPRTYPE]!=F_VAR && dz->iparam[CHORU_SPRTYPE]!=F_FIX) {
|
|
|
+ if((exit_status = get_totalamp(&post_totalamp,dz->flbufptr[0],dz->wanted))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = normalise(pre_totalamp,post_totalamp,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** GET_RANDPLACE *************************/
|
|
|
+
|
|
|
+int get_randplace(int *randh,int *rande,dataptr dz)
|
|
|
+{
|
|
|
+ *randh = (int)(drand48() * dz->iparam[CHORU_RTABSIZE]);
|
|
|
+ if((*rande = *randh + dz->clength) >= dz->iparam[CHORU_RTABSIZE])
|
|
|
+ *rande = dz->iparam[CHORU_RTABSIZE];
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** GET_OTHER_RANDPLACE **************************/
|
|
|
+
|
|
|
+int get_other_randplace(int *order,int randh,int rande,int *randh2,int *rande2,dataptr dz)
|
|
|
+{
|
|
|
+ int firstlen, firstlen2;
|
|
|
+ *randh2 = (int)(drand48() * dz->iparam[CHORU_RTABSIZE]);
|
|
|
+ if((*rande2 = *randh2 + dz->clength) > dz->iparam[CHORU_RTABSIZE])
|
|
|
+ *rande2 = dz->iparam[CHORU_RTABSIZE];
|
|
|
+ firstlen = rande - randh;
|
|
|
+ firstlen2 = *rande2 - *randh2;
|
|
|
+ if(firstlen<firstlen2) /* 1 */
|
|
|
+ *order = FIRST_ACCESS_OF_RANDTABLE_REACHES_END_FIRST;
|
|
|
+ else if(firstlen2<firstlen) /* 2 */
|
|
|
+ *order = SECOND_ACCESS_OF_RANDTABLE_REACHES_END_FIRST;
|
|
|
+ else
|
|
|
+ *order = BOTH_ACCESSES_OF_RANDTABLE_REACH_END_TOGETHER; /* 3 */
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/******************************* CHORUSING *****************************/
|
|
|
+
|
|
|
+int chorusing(int cc,int cc2,int randend,int randend2,int order,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int vc;
|
|
|
+ switch(dz->iparam[CHORU_SPRTYPE]) {
|
|
|
+ case(A_FIX):
|
|
|
+ vc = 0;
|
|
|
+ if((exit_status = do_afix(cc,vc,randend,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ break;
|
|
|
+ case(F_FIX):
|
|
|
+ vc = 1;
|
|
|
+ memset((char *)dz->windowbuf[0],0,(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ if((exit_status = do_ffix(cc,vc,randend,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ memmove((char *)dz->flbufptr[0],(char *)dz->windowbuf[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ break;
|
|
|
+ case(AF_FIX):
|
|
|
+ vc = 0;
|
|
|
+ memset((char *)dz->windowbuf[0],0,(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ switch(order) {
|
|
|
+ case(BOTH_ACCESSES_OF_RANDTABLE_REACH_END_TOGETHER):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(FIRST_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(cc2 < randend2) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(SECOND_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc2<randend2) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(cc < randend) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_afix_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ memmove((char *)dz->flbufptr[0],(char *)dz->windowbuf[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ break;
|
|
|
+ case(A_VAR):
|
|
|
+ vc = 0;
|
|
|
+ if((exit_status = do_a(cc,vc,randend,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ break;
|
|
|
+ case(F_VAR):
|
|
|
+ vc = 1;
|
|
|
+ memset((char *)dz->windowbuf[0],0,(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ if((exit_status = do_fvar(cc,vc,randend,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ memmove((char *)dz->flbufptr[0],(char *)dz->windowbuf[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ break;
|
|
|
+ case(A_FIX_F_VAR):
|
|
|
+ vc = 0;
|
|
|
+ memset((char *)dz->windowbuf[0],0,(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ switch(order) {
|
|
|
+ case(BOTH_ACCESSES_OF_RANDTABLE_REACH_END_TOGETHER):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(FIRST_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(cc2 < randend2) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(SECOND_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc2<randend2) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(cc < randend) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_afix_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"Impossible order value %d: chorusing()\n",order);
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ memmove((char *)dz->flbufptr[0],(char *)dz->windowbuf[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ break;
|
|
|
+ case(A_VAR_F_FIX):
|
|
|
+ vc = 0;
|
|
|
+ memset((char *)dz->windowbuf[0],0,(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ switch(order) {
|
|
|
+ case(BOTH_ACCESSES_OF_RANDTABLE_REACH_END_TOGETHER):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(FIRST_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(cc2 < randend2) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(SECOND_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc2<randend2) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(cc < randend) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_a_ffix(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"Impossible (2) order value %d: chorusing()\n",order);
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ memmove((char *)dz->flbufptr[0],(char *)dz->windowbuf[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ break;
|
|
|
+ case(AF_VAR):
|
|
|
+ vc = 0;
|
|
|
+ memset((char *)dz->windowbuf[0],0,(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ switch(order) {
|
|
|
+ case(BOTH_ACCESSES_OF_RANDTABLE_REACH_END_TOGETHER):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(FIRST_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc<randend) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(cc2 < randend2) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(SECOND_ACCESS_OF_RANDTABLE_REACHES_END_FIRST):
|
|
|
+ while(cc2<randend2) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc2 = 0;
|
|
|
+ while(cc < randend) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = do_a_f(&cc,&cc2,&vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"Impossible (3) order value %d: chorusing()\n",order);
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ memmove((char *)dz->flbufptr[0],(char *)dz->windowbuf[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"Impossible sprtype value %d in chorusing()\n",dz->iparam[CHORU_SPRTYPE]);
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/******************************* DO_AFIX_FFIX *********************/
|
|
|
+
|
|
|
+int do_afix_ffix(int *cc,int *cc2,int *vc,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ dz->flbufptr[0][*vc] = (float)(dz->flbufptr[0][*vc] * dz->parray[CHORU_RTABA][*cc]);
|
|
|
+ (*cc)++;
|
|
|
+ (*vc)++;
|
|
|
+ if((exit_status = getnewfrq_choru(*cc2,*vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ (*cc2)++;
|
|
|
+ (*vc)++;
|
|
|
+ return(FINISHED); /* number in flbufptr[0] */
|
|
|
+}
|
|
|
+
|
|
|
+/*************************** DO_A ****************************/
|
|
|
+
|
|
|
+int do_a(int cc,int vc,int randend,dataptr dz)
|
|
|
+{
|
|
|
+ while(cc < randend) {
|
|
|
+ dz->flbufptr[0][vc] = (float)(pow(dz->param[CHORU_AMPR],dz->parray[CHORU_RTABA][cc]) * dz->flbufptr[0][vc]);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ dz->flbufptr[0][vc] = (float)(pow(dz->param[CHORU_AMPR],dz->parray[CHORU_RTABA][cc]) * dz->flbufptr[0][vc]);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/***************************** DO_FVAR *****************************/
|
|
|
+
|
|
|
+int do_fvar(int cc,int vc,int randend,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ while(cc < randend) {
|
|
|
+ if((exit_status = getnewfrq2_choru(cc,vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = getnewfrq2_choru(cc,vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/******************************* DO_AFIX_F *********************/
|
|
|
+
|
|
|
+int do_afix_f(int *cc,int *cc2,int *vc,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ dz->flbufptr[0][*vc] = (float)(dz->flbufptr[0][*vc] * dz->parray[CHORU_RTABA][*cc]);
|
|
|
+ (*cc)++;
|
|
|
+ (*vc)++;
|
|
|
+ if((exit_status = getnewfrq2_choru(*cc2,*vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ (*cc2)++;
|
|
|
+ (*vc)++;
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************* DO_A_FFIX ***************************/
|
|
|
+
|
|
|
+int do_a_ffix(int *cc,int *cc2,int *vc,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ dz->flbufptr[0][*vc] = (float)(dz->flbufptr[0][*vc] * pow(dz->param[CHORU_AMPR],dz->parray[CHORU_RTABA][*cc]));
|
|
|
+ (*cc)++;
|
|
|
+ (*vc)++;
|
|
|
+ if((exit_status = getnewfrq_choru(*cc2,*vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ (*cc2)++;
|
|
|
+ (*vc)++;
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************* DO_A_F ***************************/
|
|
|
+
|
|
|
+int do_a_f(int *cc,int *cc2,int *vc,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ dz->flbufptr[0][*vc] = (float)(dz->flbufptr[0][*vc] * pow(dz->param[CHORU_AMPR],dz->parray[CHORU_RTABA][*cc]));
|
|
|
+ (*cc)++;
|
|
|
+ (*vc)++;
|
|
|
+ if((exit_status = getnewfrq_choru(*cc2,*vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ (*cc2)++;
|
|
|
+ (*vc)++;
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/***************************** DO_AFIX *************************/
|
|
|
+
|
|
|
+int do_afix(int cc,int vc,int randend, dataptr dz)
|
|
|
+{
|
|
|
+ while(cc < randend) {
|
|
|
+ dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] * dz->parray[CHORU_RTABA][cc]);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] * dz->parray[CHORU_RTABA][cc]);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/*************************** DO_FFIX *************************/
|
|
|
+
|
|
|
+int do_ffix(int cc,int vc,int randend,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ while(cc < randend) {
|
|
|
+ if((exit_status = getnewfrq_choru(cc,vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ cc = 0;
|
|
|
+ while(vc < dz->wanted) {
|
|
|
+ if((exit_status = getnewfrq_choru(cc,vc,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ cc++;
|
|
|
+ vc += 2;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************* GETNEWFRQ_CHORU ****************************
|
|
|
+ *
|
|
|
+ * (1) If scatter takes frq > current chan, do the scatter downwards instead.
|
|
|
+ * (1) If scatter takes frq < current chan, do the scatter upwards instead.
|
|
|
+ * (3) Otherwise, keep originally calculated value.
|
|
|
+ */
|
|
|
+
|
|
|
+int getnewfrq_choru(int cc,int vc,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ float amp;
|
|
|
+ double newval;
|
|
|
+ int new_chan;
|
|
|
+ newval = dz->flbufptr[0][vc] * dz->parray[CHORU_RTABF][cc];
|
|
|
+ if(newval > dz->nyquist || newval < dz->halfchwidth)
|
|
|
+ return(FINISHED);
|
|
|
+ if((exit_status = get_sbufposition_corresponding_to_frq(&new_chan,newval,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((amp = dz->flbufptr[0][vc-1]) > dz->windowbuf[0][new_chan]) {
|
|
|
+ dz->windowbuf[0][new_chan++] = amp;
|
|
|
+ dz->windowbuf[0][new_chan] = (float)newval;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** GETNEWFRQ2_CHORU *************************/
|
|
|
+
|
|
|
+int getnewfrq2_choru(int cc,int vc,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ float amp;
|
|
|
+ double newval, newscat = pow(dz->param[CHORU_FRQR],dz->parray[CHORU_RTABF][cc]);
|
|
|
+ int new_vc;
|
|
|
+ newval = dz->flbufptr[0][vc] * newscat;
|
|
|
+ if(newval > dz->nyquist || newval < dz->halfchwidth)
|
|
|
+ return(FINISHED);
|
|
|
+ if((exit_status = get_sbufposition_corresponding_to_frq(&new_vc,newval,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((amp = dz->flbufptr[0][vc-1]) > dz->windowbuf[0][new_vc]) {
|
|
|
+ dz->windowbuf[0][new_vc++] = amp;
|
|
|
+ dz->windowbuf[0][new_vc] = (float)newval;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** GET_SBUFPOSITION_CORRESPONDING_TO_FRQ ****************************/
|
|
|
+
|
|
|
+int get_sbufposition_corresponding_to_frq(int *channo,double frq,dataptr dz)
|
|
|
+{
|
|
|
+ frq += dz->halfchwidth;
|
|
|
+ *channo = (int)(frq/dz->chwidth);/* TRUNCATE */ /* find channel number */
|
|
|
+ *channo = min(dz->clength-1,max(0,*channo)); /* Outside range TRAP */
|
|
|
+ (*channo) *= 2;
|
|
|
+ return(FINISHED); /* number in flbufptr[0] */
|
|
|
+}
|
|
|
+
|
|
|
+/**************************** SPECNOISE ***************************/
|
|
|
+
|
|
|
+int specnoise(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int vc;
|
|
|
+ double totalamp;
|
|
|
+ if((exit_status = get_totalamp(&totalamp,dz->flbufptr[0],dz->wanted))<0)
|
|
|
+ return(exit_status);
|
|
|
+ totalamp /= dz->clength;
|
|
|
+ for(vc = 0; vc < dz->wanted; vc += 2)
|
|
|
+ dz->flbufptr[0][vc] =
|
|
|
+ (float)(((totalamp - dz->flbufptr[0][vc]) * dz->param[NOISE_NOIS]) + dz->flbufptr[0][vc]);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** SPECDRUNK ***************************/
|
|
|
+
|
|
|
+int specdrunk(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int samps_read=0, step;
|
|
|
+ float *inputbuf_end;
|
|
|
+ int drnk_bufno = -1;
|
|
|
+ dz->time = 0.0f;
|
|
|
+ if((exit_status = advance_to_starttime(&inputbuf_end,&samps_read,&drnk_bufno,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ dz->flbufptr[1] = dz->flbufptr[2];
|
|
|
+ for(;;) {
|
|
|
+ if((exit_status = copy_window_to_outbuf(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((dz->time = (float)(dz->time + dz->frametime)) >= dz->param[DRNK_DUR])
|
|
|
+ break;
|
|
|
+ if((exit_status = get_randstep(&step,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ dz->flbufptr[0] += step * dz->wanted;
|
|
|
+ if(dz->flbufptr[0] < dz->bigfbuf || dz->flbufptr[0] >= inputbuf_end) {
|
|
|
+ if((exit_status = adjust_buffers(&step,&inputbuf_end,&samps_read,&drnk_bufno,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if((exit_status = flush_outbuf(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** ADVANCE_TO_STARTTIME ***************************/
|
|
|
+
|
|
|
+int advance_to_starttime(float **inputbuf_end,int *samps_read,int *drnk_bufno,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ double time_read = 0.0, previous_time_read = 0.0, time_in_buf;
|
|
|
+ int startwindow_in_buf, w_to_buf;
|
|
|
+ while(time_read <= dz->param[DRNK_STIME]) {
|
|
|
+ if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
|
|
|
+ sprintf(errstr,"No data found in input analysis file.\n");
|
|
|
+ return(SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->ssampsread == 0) {
|
|
|
+ sprintf(errstr,"No data found in input analysis file.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ *samps_read = dz->ssampsread;
|
|
|
+
|
|
|
+ (*drnk_bufno)++;
|
|
|
+ w_to_buf = dz->ssampsread/dz->wanted;
|
|
|
+ previous_time_read = time_read;
|
|
|
+ time_read += (w_to_buf * dz->frametime);
|
|
|
+ }
|
|
|
+ *inputbuf_end = dz->bigfbuf + dz->ssampsread;
|
|
|
+ time_in_buf = dz->param[DRNK_STIME] - previous_time_read;
|
|
|
+ startwindow_in_buf = round(time_in_buf/dz->frametime);
|
|
|
+ dz->flbufptr[0] = dz->bigfbuf + (startwindow_in_buf * dz->wanted);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** COPY_WINDOW_TO_OUTBUF ***************************/
|
|
|
+
|
|
|
+int copy_window_to_outbuf(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int vc;
|
|
|
+ for(vc = 0; vc < dz->wanted; vc++)
|
|
|
+ dz->flbufptr[1][vc] = dz->flbufptr[0][vc];
|
|
|
+ if((dz->flbufptr[1] += dz->wanted) >= dz->flbufptr[3]) {
|
|
|
+ if((exit_status = write_exact_samps(dz->flbufptr[2],dz->buflen,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ dz->flbufptr[1] = dz->flbufptr[2];
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** GET_RANDSTEP ***************************/
|
|
|
+
|
|
|
+int get_randstep(int *step,dataptr dz)
|
|
|
+{
|
|
|
+ switch(dz->vflag[DRNK_NO_ZEROSTEPS]) {
|
|
|
+ case(FALSE):
|
|
|
+ *step = (int)(drand48() * dz->iparam[DRNK_TWICERANGE]); /* TRUNCATE */
|
|
|
+ *step -= dz->iparam[DRNK_RANGE];
|
|
|
+ break;
|
|
|
+ case(TRUE):
|
|
|
+ do {
|
|
|
+ *step = (int)(drand48() * dz->iparam[DRNK_TWICERANGE]); /* TRUNCATE */
|
|
|
+ *step -= dz->iparam[DRNK_RANGE];
|
|
|
+ } while(*step==0);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"unknown case in get_randstep()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** ADJUST_BUFFERS ***********************/
|
|
|
+
|
|
|
+int adjust_buffers(int *step,float **inputbuf_end,int *samps_read,int *drnk_bufno, dataptr dz)
|
|
|
+{
|
|
|
+ //TW UPDATED
|
|
|
+ int exit_status;
|
|
|
+ int bigbufs_baktrak = 0;
|
|
|
+ int baksamps, total_samps_read, seektest;
|
|
|
+ int reflect_off_start = FALSE, reflect_off_end = FALSE;
|
|
|
+ if(*drnk_bufno < 0) {
|
|
|
+ sprintf(errstr,"ADJUST_BUFFERS START bufno = %d (less than zero)\n",*drnk_bufno);
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ do {
|
|
|
+ if(dz->flbufptr[0] < dz->bigfbuf) { /* IF OFF START OF BUFFER */
|
|
|
+ if(*drnk_bufno == 0) { /* IF OFF START OF FILE */
|
|
|
+ if((exit_status = invert_step_back_to_step_fwd_at_start_of_file(step,reflect_off_end,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ reflect_off_start = TRUE;
|
|
|
+ } else { /* ELSE NOT OFF START OF FILE */
|
|
|
+ if((exit_status = place_sbufptr_in_bigbuf_range(&bigbufs_baktrak,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ baksamps = (bigbufs_baktrak * dz->buflen) + *samps_read;
|
|
|
+ if((seektest = sndseekEx(dz->ifd[0],-baksamps,1)) <= 0) { /* IF FELL OF FILE START */
|
|
|
+ if(seektest<0) {
|
|
|
+ sprintf(errstr,"sndseekEx() failed.\n");
|
|
|
+ return(SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ if((exit_status = invert_step_back_to_step_fwd
|
|
|
+ (step,dz->flbufptr[0],samps_read,inputbuf_end,reflect_off_end,*drnk_bufno,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ reflect_off_start = TRUE;
|
|
|
+ } else {
|
|
|
+ if((exit_status = baktrak_to_correct_bigbuf(bigbufs_baktrak,samps_read,inputbuf_end,drnk_bufno,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ reflect_off_start = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ reflect_off_start = FALSE;
|
|
|
+ total_samps_read = min(dz->insams[0],(*drnk_bufno+1) * dz->buflen);
|
|
|
+
|
|
|
+ if(dz->flbufptr[0] >= *inputbuf_end) { /* IF OFF END OF BUFFER */
|
|
|
+ if(total_samps_read >= dz->insams[0]) { /* IF OFF END OF FILE */
|
|
|
+ if((exit_status = invert_step_fwd_to_step_back_at_end_of_file(step,reflect_off_start,*drnk_bufno,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ reflect_off_end = TRUE;
|
|
|
+ } else { /* ELSE NOT END OF FILE */
|
|
|
+ if((exit_status = advance_to_correct_bigbuf(inputbuf_end,samps_read,drnk_bufno,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if(dz->flbufptr[0] >= *inputbuf_end) { /* IF FELL OFF END OF FILE */
|
|
|
+ if((exit_status = invert_step_fwd_to_step_back
|
|
|
+ (step,dz->flbufptr[0],samps_read,inputbuf_end,reflect_off_start,*drnk_bufno,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ reflect_off_end = TRUE;
|
|
|
+ } else
|
|
|
+ reflect_off_end = FALSE;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ reflect_off_end = FALSE;
|
|
|
+ } while(reflect_off_end);
|
|
|
+ if(*drnk_bufno < 0) {
|
|
|
+ sprintf(errstr,"ADJUST_BUFFERS END bufno = %d (less than zero)\n",*drnk_bufno);
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** FLUSH_OUTBUF ***************************/
|
|
|
+
|
|
|
+int flush_outbuf(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int samps_to_write;
|
|
|
+ if(dz->flbufptr[1] != dz->flbufptr[2]) {
|
|
|
+ samps_to_write = dz->flbufptr[1] - dz->flbufptr[2];
|
|
|
+ if((exit_status = write_samps(dz->flbufptr[2],samps_to_write,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** INVERT_STEP_BACK_TO_STEP_FWD_AT_START_OF_FILE ***********************/
|
|
|
+
|
|
|
+int invert_step_back_to_step_fwd_at_start_of_file(int *step,int reflect_off_end,dataptr dz)
|
|
|
+{
|
|
|
+ if(reflect_off_end) {
|
|
|
+ sprintf(errstr,"Step turned out to be too large.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ *step = -(*step); /* REFLECT FROM START OF FILE */
|
|
|
+ dz->flbufptr[0] += (*step) * 2 * dz->wanted;
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** PLACE_SBUFPTR_IN_BIGBUF_RANGE ***********************/
|
|
|
+
|
|
|
+int place_sbufptr_in_bigbuf_range(int *bigbufs_baktrak,dataptr dz)
|
|
|
+{
|
|
|
+ while(dz->flbufptr[0] < dz->bigfbuf) { /* GO BACK THROUGH BUFS */
|
|
|
+ dz->flbufptr[0] += dz->big_fsize;
|
|
|
+ (*bigbufs_baktrak)++;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** INVERT_STEP_BACK_TO_STEP_FWD ***********************/
|
|
|
+
|
|
|
+int invert_step_back_to_step_fwd
|
|
|
+(int *step,float *orig_sbuf,int *samps_read,float **inputbuf_end, int reflect_off_end,int drnk_bufno,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ if(reflect_off_end) {
|
|
|
+ sprintf(errstr,"Step turned out ot be too large.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if(sndseekEx(dz->ifd[0],drnk_bufno * dz->buflen,0)<0) {
|
|
|
+ sprintf(errstr,"Seek problem in invert_step_back_to_step_fwd().\n");
|
|
|
+ return(SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
|
|
|
+ sprintf(errstr,"Problem reading buffer:in invert_step_back_to_step_fwd().\n");
|
|
|
+ return(SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->ssampsread == 0) {
|
|
|
+ sprintf(errstr,"Problem reading buffer:in invert_step_back_to_step_fwd().\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ *samps_read = dz->ssampsread;
|
|
|
+ *inputbuf_end = dz->bigfbuf + dz->ssampsread;
|
|
|
+ *step = -(*step); /* REVERSE STEP */
|
|
|
+ dz->flbufptr[0] = orig_sbuf + ((*step) * 2 * dz->wanted);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** BAKTRAK_TO_CORRECT_BIGBUF ***********************/
|
|
|
+
|
|
|
+int baktrak_to_correct_bigbuf(int bigbufs_baktrak,int *samps_read,float **inputbuf_end,int *drnk_bufno,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ *drnk_bufno -= bigbufs_baktrak;
|
|
|
+ if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
|
|
|
+ sprintf(errstr,"Problem reading buffer in baktrak_to_correct_bigbuf().\n");
|
|
|
+ return(SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->ssampsread == 0) {
|
|
|
+ sprintf(errstr,"Problem reading buffer in baktrak_to_correct_bigbuf().\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ *samps_read = dz->ssampsread;
|
|
|
+ *inputbuf_end = dz->bigfbuf + dz->ssampsread;
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** INVERT_STEP_FWD_TO_STEP_BACK_AT_END_OF_FILE ***********************/
|
|
|
+
|
|
|
+int invert_step_fwd_to_step_back_at_end_of_file(int *step,int reflect_off_start,int drnk_bufno,dataptr dz)
|
|
|
+{
|
|
|
+ if(reflect_off_start) { /* IF OFF END OF FILE */
|
|
|
+ sprintf(errstr,"Step turned out ot be too large.\n");
|
|
|
+ return(DATA_ERROR); /* REFLECTED FROM BOTH ENDS !! */
|
|
|
+ }
|
|
|
+ *step = -(*step); /* REFLECT FROM END OF FILE */
|
|
|
+ dz->flbufptr[0] += (*step) * 2 * dz->wanted;
|
|
|
+ if(dz->flbufptr[0] < dz->bigfbuf && drnk_bufno == 0) {
|
|
|
+ sprintf(errstr,"Step turned out ot be too large.\n");
|
|
|
+ return(DATA_ERROR); /* REFLECTED FROM BOTH ENDS !! */
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** ADVANCE_TO_CORRECT_BIGBUF ***********************/
|
|
|
+
|
|
|
+int advance_to_correct_bigbuf(float **inputbuf_end,int *samps_read,int *drnk_bufno,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ if(*drnk_bufno < 0) {
|
|
|
+ sprintf(errstr,"advance_to_correct_bigbuf: drnk_bufno = %d (less than zero)\n",*drnk_bufno);
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ while(dz->flbufptr[0] >= *inputbuf_end) { /* ADVANCE ALONG FILE */
|
|
|
+ if((exit_status = read_samps(dz->bigfbuf,dz)) < 0)
|
|
|
+ return(exit_status);
|
|
|
+ *samps_read = dz->ssampsread;
|
|
|
+ if(dz->ssampsread == 0)
|
|
|
+ break;
|
|
|
+ *inputbuf_end = dz->bigfbuf + dz->ssampsread;
|
|
|
+ (*drnk_bufno)++;
|
|
|
+ dz->flbufptr[0] -= dz->big_fsize;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** INVERT_STEP_FWD_TO_STEP_BACK ***********************/
|
|
|
+
|
|
|
+int invert_step_fwd_to_step_back
|
|
|
+(int *step,float *orig_sbuf,int *samps_read,float **inputbuf_end,int reflect_off_start,int drnk_bufno,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ if(reflect_off_start) {
|
|
|
+ sprintf(errstr,"Step turned out ot be too large.\n");
|
|
|
+ return(DATA_ERROR); /* REFLECTED FROM BOTH ENDS!! */
|
|
|
+ }
|
|
|
+ if(sndseekEx(dz->ifd[0],drnk_bufno * dz->buflen,0)<0) {
|
|
|
+ sprintf(errstr,"Seek problem in invert_step_fwd_to_step_back().\n");
|
|
|
+ return(SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
|
|
|
+ sprintf(errstr,"Problem reading buffer in invert_step_fwd_to_step_back().\n");
|
|
|
+ return exit_status;
|
|
|
+ }
|
|
|
+ if(dz->ssampsread == 0) {
|
|
|
+ sprintf(errstr,"Problem reading buffer in invert_step_fwd_to_step_back().\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ *samps_read = dz->ssampsread;
|
|
|
+ *inputbuf_end = dz->bigfbuf + dz->ssampsread;
|
|
|
+ *step = -(*step); /* REVERSE STEP */
|
|
|
+ dz->flbufptr[0] = orig_sbuf + ((*step) * 2 * dz->wanted);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** SPECWEAVE ***************************/
|
|
|
+
|
|
|
+int specweave(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int vc;
|
|
|
+ int samps_to_write, n = 0;
|
|
|
+ float *insbuf = dz->flbufptr[0];
|
|
|
+ float *outsbuf = dz->flbufptr[2];
|
|
|
+ unsigned int wrapsamps = dz->iparam[WEAVE_BAKTRAK] * dz->wanted;
|
|
|
+ if((exit_status = read_first_inbuf(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ for(;;) {
|
|
|
+ for(vc = 0; vc < dz->wanted; vc++)
|
|
|
+ outsbuf[vc] = insbuf[vc];
|
|
|
+ insbuf += dz->iparray[WEAVE_WEAV][n] * dz->wanted;
|
|
|
+ if(insbuf < dz->bigfbuf) {
|
|
|
+ sprintf(errstr,"Backtracking failure in specweave().\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ if(insbuf >= dz->flbufptr[1]) {
|
|
|
+ if((exit_status = wrap_samps(wrapsamps,&insbuf,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if(exit_status == FINISHED) {
|
|
|
+ outsbuf += dz->wanted;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(++n>=dz->itemcnt)
|
|
|
+ n = 0;
|
|
|
+ if((outsbuf += dz->wanted)>= dz->flbufptr[3]) { /* outbuf full */
|
|
|
+ if((exit_status = write_exact_samps(dz->flbufptr[2],dz->buflen,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ outsbuf = dz->flbufptr[2];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(outsbuf != dz->flbufptr[2]) {
|
|
|
+ samps_to_write = outsbuf - dz->flbufptr[2];
|
|
|
+ if((exit_status = write_samps(dz->flbufptr[2],samps_to_write,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** READ_FIRST_INBUF ***************************/
|
|
|
+
|
|
|
+int read_first_inbuf(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ if((exit_status = read_samps(dz->flbufptr[0],dz)) < 0) {
|
|
|
+ sprintf(errstr,"Failed to read data from infile.\n");
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ dz->flbufptr[1] = dz->flbufptr[0] + dz->ssampsread; /* mark current end of inbuf */
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************** WRAP_SAMPS ***************************/
|
|
|
+
|
|
|
+int wrap_samps(unsigned int wrapsamps,float **insbuf,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ memmove((char *)dz->bigfbuf,(char *)dz->flbufptr[4],(size_t)(wrapsamps * sizeof(float)));
|
|
|
+ if((exit_status = read_samps(dz->flbufptr[0],dz)) < 0)
|
|
|
+ return exit_status;
|
|
|
+ if(dz->ssampsread == 0)
|
|
|
+ return(FINISHED); /* no more data in infile */
|
|
|
+ dz->flbufptr[1] = dz->flbufptr[0] + dz->ssampsread; /* mark current end of inbuf */
|
|
|
+ if((*insbuf -= dz->big_fsize) >= dz->flbufptr[1])/* must have weaved off end of infile */
|
|
|
+ return(FINISHED);
|
|
|
+ return(CONTINUE);
|
|
|
+}
|
|
|
+
|
|
|
+/*************************** COPY_1ST_WINDOW ***********************/
|
|
|
+
|
|
|
+int copy_1st_window(dataptr dz)
|
|
|
+{
|
|
|
+ memmove((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],(size_t)(dz->wanted * sizeof(float)));
|
|
|
+ dz->flbufptr[0] += dz->wanted;
|
|
|
+ dz->flbufptr[1] += dz->wanted;
|
|
|
+ return(FINISHED);
|
|
|
+}
|