int zig_or_zag (int direction,int *here,int *next,int is_startsplice,int is_endsplice, int *outbuf_space,int obufno, int splbufno, dataptr dz) { int exit_status; int bufno; int incnt = abs(*next - *here), advance; int orig_incnt = incnt; int samps_remain; float *sbufend = dz->sampbuf[NORMAL] + dz->buflen; switch(direction) { case(ZIG): bufno = NORMAL; break; case(ZAG): switch(dz->process) { case(ZIGZAG): if((exit_status = reverse_it(incnt,dz))<0) return(exit_status); bufno = REVERSE; break; case(LOOP): case(SCRAMBLE): incnt = *next - *here; if((dz->sbufptr[NORMAL] += incnt) < dz->sampbuf[NORMAL] || dz->sbufptr[NORMAL] >= sbufend) { sprintf(errstr,"Error in buffer accounting: zig_or_zag()\n"); return(PROGRAM_ERROR); } return(FINISHED); default: sprintf(errstr,"Unknown case in zig_or_zag()\n"); return(PROGRAM_ERROR); } break; default: sprintf(errstr,"Unknown case in zig_or_zag\n"); return(PROGRAM_ERROR); } if(is_startsplice) { if((exit_status = add_to_splicebuf(dz->sbufptr[bufno],dz))<0) return(exit_status); } if(*outbuf_space >= incnt) { /* ENOUGH SPACE IN OUTBUFFER To DO EVERYTHING */ if(is_startsplice) { if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno], (char *)dz->extrabuf[ZIGZAG_SPLBUF],dz->iparam[ZIG_SPLSAMPS]* sizeof(float)))<0) return(exit_status); dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; dz->sbufptr[obufno] += dz->iparam[ZIG_SPLSAMPS]; *outbuf_space -= dz->iparam[ZIG_SPLSAMPS]; advance = incnt-(2*dz->iparam[ZIG_SPLSAMPS]); } else advance = incnt - dz->iparam[ZIG_SPLSAMPS]; if(!is_endsplice) advance += dz->iparam[ZIG_SPLSAMPS]; if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0) return(exit_status); dz->sbufptr[obufno] += advance; dz->sbufptr[bufno] += advance; *outbuf_space -= advance; if(is_endsplice) { memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF], (char *)dz->sbufptr[bufno],dz->iparam[ZIG_SPLSAMPS]* sizeof(float)); do_down_splice(dz); dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; } if(*outbuf_space <= 0) { if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0) return(exit_status); dz->sbufptr[obufno] = dz->sampbuf[obufno]; *outbuf_space = dz->buflen; } } else if(is_startsplice && (*outbuf_space <= dz->iparam[ZIG_SPLSAMPS])) { /* OUTBUFFER SPACE LESS THAN (START)SPLICELEN */ samps_remain = dz->iparam[ZIG_SPLSAMPS]; dz->extrabufptr[ZIGZAG_SPLBUF] = dz->extrabuf[ZIGZAG_SPLBUF]; if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->extrabufptr[ZIGZAG_SPLBUF],(*outbuf_space) * sizeof(float)))<0) return(exit_status); if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0) return(exit_status); dz->extrabufptr[ZIGZAG_SPLBUF] += *outbuf_space; dz->sbufptr[obufno] = dz->sampbuf[obufno]; samps_remain -= *outbuf_space; *outbuf_space = dz->buflen; if(samps_remain > 0) { if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)(dz->extrabufptr[ZIGZAG_SPLBUF]),samps_remain * sizeof(float)))<0) return(exit_status); dz->sbufptr[obufno] += samps_remain; *outbuf_space -= samps_remain; } dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; advance = incnt - (2 *dz->iparam[ZIG_SPLSAMPS]); if(!is_endsplice) advance += dz->iparam[ZIG_SPLSAMPS]; if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0) return(exit_status); dz->sbufptr[obufno] += advance; dz->sbufptr[bufno] += advance; *outbuf_space -= advance; if(is_endsplice) { memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF], (char *)dz->sbufptr[bufno],(size_t)dz->iparam[ZIG_SPLSAMPS]* sizeof(float)); do_down_splice(dz); dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; } } else if(*outbuf_space <= incnt - dz->iparam[ZIG_SPLSAMPS]) { /* OUTBUFFER SPACE DOESN'T REACH UP INTO ENDSPLICE */ if(is_startsplice) { if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->extrabuf[ZIGZAG_SPLBUF], (int)dz->iparam[ZIG_SPLSAMPS]* sizeof(float)))<0) return(exit_status); dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; dz->sbufptr[obufno] += dz->iparam[ZIG_SPLSAMPS]; advance = *outbuf_space - dz->iparam[ZIG_SPLSAMPS]; } else advance = *outbuf_space; if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0) return(exit_status); if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0) return(exit_status); dz->sbufptr[bufno] += advance; dz->sbufptr[obufno] = dz->sampbuf[obufno]; incnt -= *outbuf_space; *outbuf_space = dz->buflen; advance = incnt - dz->iparam[ZIG_SPLSAMPS]; if(!is_endsplice) advance += dz->iparam[ZIG_SPLSAMPS]; if(advance > 0) { if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0) return(exit_status); dz->sbufptr[obufno] += advance; dz->sbufptr[bufno] += advance; *outbuf_space -= advance; } if(is_endsplice) { memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF],(char *)dz->sbufptr[bufno], (size_t)dz->iparam[ZIG_SPLSAMPS]* sizeof(float)); do_down_splice(dz); dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; } } else { /* OUTBUFFER SPACE REACHES INTO MIDDLE OF ENDSPLICE */ if(is_startsplice) { if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno], (char *)dz->extrabuf[ZIGZAG_SPLBUF],dz->iparam[ZIG_SPLSAMPS]* sizeof(float)))<0) return(exit_status); dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; dz->sbufptr[obufno] += dz->iparam[ZIG_SPLSAMPS]; *outbuf_space -= dz->iparam[ZIG_SPLSAMPS]; advance = incnt - (2*dz->iparam[ZIG_SPLSAMPS]); } else advance = incnt - dz->iparam[ZIG_SPLSAMPS]; if(!is_endsplice) { advance += dz->iparam[ZIG_SPLSAMPS]; if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],(*outbuf_space) * sizeof(float)))<0) return(exit_status); if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0) return(exit_status); dz->sbufptr[bufno] += *outbuf_space; dz->sbufptr[obufno] = dz->sampbuf[obufno]; advance -= *outbuf_space; *outbuf_space = dz->buflen; if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0) return(exit_status); dz->sbufptr[bufno] += advance; dz->sbufptr[obufno] += advance; *outbuf_space -= advance; } else { if((exit_status = memcpy_with_check ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0) return(exit_status); dz->sbufptr[obufno] += advance; dz->sbufptr[bufno] += advance; memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF], (char *)dz->sbufptr[bufno],dz->iparam[ZIG_SPLSAMPS]* sizeof(float)); do_down_splice(dz); dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS]; *outbuf_space = dz->sampbuf[splbufno] - dz->sbufptr[obufno]; if(*outbuf_space > dz->iparam[ZIG_SPLSAMPS]) { sprintf(errstr,"Error in counting logic: zig_or_zag()\n"); return(PROGRAM_ERROR); } if(*outbuf_space <= 0) { sprintf(errstr,"Error 2 in counting logic: zig_or_zag()\n"); return(PROGRAM_ERROR); } } } if(direction ==ZAG) { dz->sbufptr[0] -= orig_incnt; dz->sbufptr[1] = dz->sampbuf[1]; } return(FINISHED); }
void ExpIFCT( float *data, float *result, float *workspace, int n, int k, int permflag) { int j, loopcntr; int levelsize, divsize; float *dividend, *remres; const double *modptr; float *divptr, *remptr; float divptr0, divptr1, divptr2, divptr3; double tmpmod, tmpmod2; /* assign workspace locations */ remres = workspace; dividend = workspace + n; /* first reverse the Chebyshev series to order from high to low */ reverse_it(data, dividend, k); /* compute initial values of variables */ /* levelsize is the number of supermoduli at first level of division */ /* divsize is the size of each divisor */ /* modptr points to list of supermods at this level */ levelsize = 2 * (n/k); divsize = k; modptr = get_mods(levelsize); divptr = dividend; remptr = remres; loopcntr = 0; /* now do divisions */ for(j = 0; j < levelsize; j += 2) { ChebyDivRem(divptr,modptr[j],remptr,divsize); remptr += (divsize>>1); ChebyDivRem(divptr,modptr[j+1],remptr,divsize); remptr += (divsize>>1); } /* now reset everything */ divptr = remres; remptr = dividend; loopcntr++; divsize /= 2; levelsize *= 2; modptr = get_mods(levelsize); /*** now loopcntr = 1 ***/ while (divsize > 4) { for(j = 0 ; j < levelsize; j += 2) { ChebyDivRem(divptr,modptr[j],remptr,divsize); remptr += (divsize>>1); ChebyDivRem(divptr,modptr[j+1],remptr,divsize); remptr += (divsize>>1); divptr += divsize; } /* now reset everything */ if ( (loopcntr % 2) == 0 ) { divptr = remres; remptr = dividend; } else { divptr = dividend; remptr = remres; } loopcntr++; divsize /= 2; levelsize *= 2; modptr = get_mods(levelsize); } /***** in what follows, am using the fact that modptr[i+1] = -modptr[i] for i even ****/ if(divsize == 4) { for (j=0; j<levelsize; j+=2) { divptr0 = divptr[0]; divptr1 = divptr[1]; divptr2 = divptr[2]; divptr3 = divptr[3]; tmpmod = modptr[j]; tmpmod2 = 2.0 * modptr[j]; remptr[0] = divptr2 - divptr0 - (tmpmod2 * divptr0); remptr[1] = (divptr3 - (tmpmod * divptr1)); remptr[2] = divptr2 - divptr0 + (tmpmod2 * divptr0); remptr[3] = (divptr3 + (tmpmod * divptr1)); remptr += 4; divptr += 4; } /* now reset everything */ if ( (loopcntr % 2) == 0) { divptr = remres; remptr = dividend; } else { divptr = dividend; remptr = remres; } loopcntr++; divsize /= 2; levelsize *= 2; modptr = get_mods(levelsize); } if(divsize == 2) { for( j = 0; j < levelsize; j += 2) { divptr0 = divptr[0]; divptr1 = divptr[1]; remptr[0] = divptr1 - (modptr[j] * divptr0); remptr[1] = divptr1 + (modptr[j] * divptr0); remptr += 2; divptr += divsize; } /* now reset everything */ if ( (loopcntr % 2) == 0 ) { divptr = remres; remptr = dividend; } else { divptr = dividend; remptr = remres; } } /******** *********/ /* divptr now points to result - copy into result space after checking permute flag */ if ( permflag == 0 ) { memcpy(result, divptr, sizeof(float) * n); } else OURpermute(divptr,result,n); /* later */ }