| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767 |
- /*
- * 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 <cdpmain.h>
- #include <tkglobals.h>
- #include <pnames.h>
- #include <distort.h>
- #include <processno.h>
- #include <modeno.h>
- #include <globcon.h>
- #include <logic.h>
- #include <filetype.h>
- #include <mixxcon.h>
- #include <distort1.h>
- #include <flags.h>
- #include <speccon.h>
- #include <arrays.h>
- #include <special.h>
- #include <formants.h>
- #include <sfsys.h>
- #include <osbind.h>
- #include <string.h>
- #include <arrays.h>
- #include <math.h>
- #include <ctype.h>
- /*
- PRESCALE PULSE-ENVELOPE FILE BETWEEN 0 and 1 in time and copy into parray[PULSENV]
- PRESCALE PULSE-TRANSPOS FILE BETWEEN 0 and 1 in time and copy into parray[PULSTRN]
- NB randomisation pulse-transposition only works if it's a brktable
- HAS TO BE MONO SNDFILE;
- */
- static int write_pulse_to_output(int *pbufpos,int *obufpos,dataptr dz);
- static void randomise_pulse_transposition(dataptr dz);
- static int randomise_pulse_envelope(int obufpos,dataptr dz);
- static double gen_sndtabindex(int obufpos,double *sndtabindex,double *pulsenvindex,double *envstep,
- int insertsmps,double tablen,int randomise_transpos,dataptr dz);
- static int extract_waveform(int *waveset_start,dataptr dz);
- static int get_wavesetstart(int ibufpos,dataptr dz);
- /* in ap_distort */
- static int prescale_pulse_transpos(dataptr dz);
- static int read_impulse_amp_val(double thistime,double *amp,dataptr dz);
- /************************************* PREPROCESS_PULSE *************************************/
- int preprocess_pulse(dataptr dz)
- {
- double k;
- int exit_status;
- if(dz->iparam[PULSE_ENVSIZE] > 0) {
- if((dz->parray[PULSENV] = (double *)malloc((dz->iparam[PULSE_ENVSIZE] * 2) * sizeof(double)))==NULL) {
- sprintf(errstr,"Out of memory for storing backup of original pulse envelope.\n");
- return(MEMORY_ERROR);
- }
- memcpy((char *)dz->parray[PULSENV],(char *)dz->parray[ORIG_PULSENV],(dz->iparam[PULSE_ENVSIZE] * 2) * sizeof(double));
- /* copy original envelope into parray */
- if((dz->iparray[0] = (int *)malloc(dz->iparam[PULSE_ENVSIZE] * sizeof(int)))==NULL) {
- sprintf(errstr,"Out of memory for storing markers for envelope warping.\n");
- return(MEMORY_ERROR);
- }
- }
- if(dz->brksize[PULSE_TRANSPOS] > 0) {
- if((exit_status = prescale_pulse_transpos(dz))<0)
- return(exit_status);
- } else {
- k = dz->param[PULSE_TRANSPOS] / 12.0;
- dz->param[PULSE_TRANSPOS] = pow(2.0,k); /* convert semitones to frq-ratio */
- }
- return(FINISHED);
- }
- /*********************************** PRESCALE_PULSE_TRANSPOS *************************************/
- int prescale_pulse_transpos(dataptr dz)
- {
- int brklen = dz->brksize[PULSE_TRANSPOS] * 2;
- int maxtimindx = brklen - 2;
- int n,m;
- double maxtime = dz->brk[PULSE_TRANSPOS][maxtimindx], scaler;
- scaler = 1.0/maxtime;
- for(n=0,m=1;n<brklen;n+=2,m+=2)
- dz->brk[PULSE_TRANSPOS][n] *= scaler; /* scale to 0 to 1 time range */
- dz->brk[PULSE_TRANSPOS][maxtimindx] = 1.0;
- if((dz->parray[PULSTRN] = (double *)malloc(brklen * sizeof(double)))==NULL) {
- sprintf(errstr,"Out of memory for storing backup of original pulse transposition envelope\n");
- return(MEMORY_ERROR);
- }
- memcpy((char *)dz->parray[PULSTRN],(char *)dz->brk[PULSE_TRANSPOS],brklen * sizeof(double));
- return(FINISHED);
- }
- /************************************* DO_PULSETRAIN *************************************/
- int do_pulsetrain(dataptr dz)
- {
- int exit_status;
- float *ibuf = dz->sampbuf[0]; /* stores input */
- float *obuf = dz->sampbuf[1]; /* stores output */
- float *sbuf = dz->sampbuf[2]; /* stores waveset cycoes, for SYN option */
- float *pbuf = dz->sampbuf[3]; /* stores pulse, before writing to output */
- int srate = dz->infile->srate;
- float *spliceptr, *obufend = obuf + dz->buflen;
- int startsamp = round(dz->param[PULSE_STARTTIME] * srate);
- int insertdur = round(dz->param[PULSE_DUR] * srate);
- int last_total_ssampsread, total_ssampsread = 0, ssampsread = 0, insertsmps = 0;
- int smpsecsize = F_SECSIZE, secsleft, edit_todo = (int)round(ENDBIT_SPLICE);
- int ibufpos = 0, ibufleft, obufpos = 0, pbufpos = 0, obufleft;
- double amp, frq, sndtabindex, pulsenvindex;
- int waveset_len = 0;
- double envstep;
- int randomise_transpos = 0, firsttime = 1;
- int smps_pretime, waveset_start;
- double interp, valdiff, k;
- float val, upval;
- int here, n, m;
- if(dz->mode == PULSE_SYNI)
- startsamp = dz->iparam[PULSE_STARTTIME];
- else
- startsamp = round(dz->param[PULSE_STARTTIME] * srate);
- /* PROCESS FILE PRIOR TO PULSE-TRAIN'S START, IF NESS */
- if(dz->mode == PULSE_IMP) {
- k = dz->duration;
- if(!dz->vflag[PULSE_KEEPSTART]) {
- k -= dz->param[PULSE_STARTTIME];
- if(!dz->vflag[PULSE_KEEPEND])
- k = min(dz->param[PULSE_DUR],k);
- } else if(!dz->vflag[PULSE_KEEPEND]) {
- k = dz->param[PULSE_STARTTIME] + dz->param[PULSE_DUR];
- k = min(dz->duration,k);
- }
- } else {
- k = dz->param[PULSE_DUR];
- if(dz->vflag[PULSE_KEEPEND]) {
- k += dz->duration;
- if(!dz->vflag[PULSE_KEEPSTART])
- k -= dz->param[PULSE_STARTTIME];
- } else if(dz->vflag[PULSE_KEEPSTART])
- k += dz->param[PULSE_STARTTIME];
- }
- dz->tempsize = (int)round(k * (dz->infile->srate));
- while(total_ssampsread + dz->buflen < startsamp) {
- if(( exit_status = read_samps(ibuf,dz)) < 0) {
- sprintf(errstr, "Can't read samps from input soundfile\n");
- return(SYSTEM_ERROR);
- }
- ssampsread = dz->ssampsread;
- last_total_ssampsread = total_ssampsread;
- total_ssampsread += ssampsread;
- if(dz->vflag[PULSE_KEEPSTART]) {
- if(ssampsread > 0) {
- if((exit_status = write_samps(ibuf,ssampsread,dz))<0)
- return(exit_status);
- }
- }
- }
- if((secsleft = (startsamp - total_ssampsread)/smpsecsize)> 0) {
- if(( ssampsread = fgetfbufEx(ibuf,secsleft * F_SECSIZE, dz->ifd[0],0)) < 0) {
- sprintf(errstr, "Can't read samps from input soundfile\n");
- return(SYSTEM_ERROR);
- }
- last_total_ssampsread = total_ssampsread;
- total_ssampsread += ssampsread;
- if(dz->vflag[PULSE_KEEPSTART]) {
- if(ssampsread > 0) {
- if((exit_status = write_samps(ibuf,ssampsread,dz))<0)
- return(exit_status);
- }
- }
- }
- smps_pretime = startsamp - total_ssampsread; /* no of samples before param-specified time */
- if(( ssampsread = fgetfbufEx(ibuf, dz->buflen + F_SECSIZE, dz->ifd[0],0)) < 0) {
- sprintf(errstr, "Can't read samples from input soundfile\n"); /* To get wraparound points */
- return(SYSTEM_ERROR);
- }
- last_total_ssampsread = total_ssampsread;
- if(ssampsread > dz->buflen) {
- sndseekEx(dz->ifd[0],last_total_ssampsread + dz->buflen,0);
- total_ssampsread = last_total_ssampsread + dz->buflen;
- } else { /* We'RE AT END oF FILE... */
- total_ssampsread = last_total_ssampsread + ssampsread;
- ibuf[ssampsread] = 0.0; /* CREATE zero-val wraparound points */
-
- }
- /* FIND START OF WAVESETS */
- if((waveset_start = get_wavesetstart(smps_pretime,dz)) < 0) {
- sprintf(errstr,"Can't find the required waveset start within a single buffer.\n");
- return(GOAL_FAILED);
- }
- if((waveset_start > 0) && dz->vflag[PULSE_KEEPSTART]) {
- memcpy((char *)obuf,(char *)ibuf,waveset_start * sizeof(float));
- obufpos = waveset_start; /* copy any inbuf remnant prior to pulsing, to outbuf */
- }
- ibufpos = waveset_start;
- if(dz->mode!=PULSE_IMP) {
- if((waveset_len = extract_waveform(&waveset_start,dz))<0) { /* NB copy rounding sample[s] at end */
- sprintf(errstr,"Can't find the required wavesets within a single buffer.\n");
- return(GOAL_FAILED);
- }
- sndtabindex = 0.0; /* position in storage buffer */
- } else
- sndtabindex = (double)waveset_start; /* position in input buffer */
- /* INITIALISE SHAPE AND LENGTH OF FIRST IMPULSE */
- if(dz->iparam[PULSE_ENVSIZE] > 0)
- randomise_pulse_envelope(obufpos,dz); /* randomise shape of pulse, and copy reshaped pulse to read-env-table */
- /* +insert edit shoulders at start and end */
- if(!flteq(dz->param[PULSE_PITCHRAND],0.0)) {
- randomise_transpos = 1;
- if(dz->brksize[PULSE_TRANSPOS] <= 0) {
- fprintf(stdout,"WARNING: Randomisation of transposition only applies to a transposition TABLE\n");
- fflush(stdout);
- randomise_transpos = 0;
- } else
- randomise_pulse_transposition(dz);
- } else if (dz->brksize[PULSE_TRANSPOS] > 0) { /* if NOT randomised, convert to frqratio NOW */
- for(n=0,m=1;n<dz->brksize[PULSE_TRANSPOS];n++,m+=2) {
- k = dz->parray[PULSTRN][m]/SEMITONES_PER_OCTAVE;
- dz->brk[PULSE_TRANSPOS][m] = pow(2.0,k);
- }
- }
- pulsenvindex = 0.0;
- if(dz->iparam[PULSE_ENVSIZE] <= 0)
- amp = 1.0;
- else
- amp = dz->parray[PULSENV][0];
- if(dz->brksize[PULSE_FRQ] > 0) {
- if((exit_status = read_value_from_brktable(0.0,PULSE_FRQ,dz))<0)
- return exit_status;
- }
- frq = dz->param[PULSE_FRQ];
- if(dz->param[PULSE_FRQRAND] > 0.0) {
- k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_FRQRAND];
- k /= SEMITONES_PER_OCTAVE;
- k = pow(2.0,k);
- frq *= k;
- }
- envstep = frq/srate;
- /* DO IMPULSE TRAIN */
- while(insertsmps < insertdur) {
- if(!firsttime && flteq(pulsenvindex,0.0)) { /* if at start of new pulse */
- if((exit_status = write_pulse_to_output(&pbufpos,&obufpos,dz))<0)
- return(exit_status);
- }
- firsttime = 0;
- if(dz->mode!=PULSE_IMP) {
- interp = fmod(sndtabindex,1.0);
- here = (int)floor(sndtabindex);
- val = sbuf[here++];
- upval = sbuf[here];
- valdiff = (upval - val) * interp;
- pbuf[pbufpos++] = (float)((val + valdiff) * amp);
- if(pbufpos >= dz->buflen) {
- sprintf(errstr,"Pulse length exceeds length of internal buffer : cannot proceed.\n");
- return(GOAL_FAILED);
- }
- } else {
- interp = fmod(sndtabindex,1.0);
- ibufpos = (int)floor(sndtabindex);
- while(ibufpos >= ssampsread) {
- /* read extra sector, for wraparound vals for interpolation */
- if(( ssampsread = fgetfbufEx(ibuf, dz->buflen + F_SECSIZE, dz->ifd[0],0)) < 0) {
- sprintf(errstr, "Can't read samps from input soundfile\n"); /* read failed */
- return(SYSTEM_ERROR);
- }
- if(ssampsread <= 0) { /* read zero bytes = EOF */
- if(obufpos > 0) {
- if((exit_status = write_samps(obuf,obufpos,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- if(ssampsread <= dz->buflen) { /* generate zero-val wraparound points if buffer+wrap not full */
- ibuf[ssampsread] = 0.0;
- total_ssampsread += ssampsread;
- } else {
- last_total_ssampsread = total_ssampsread;
- ssampsread = dz->buflen; /* effective read is a buffer-full */
- total_ssampsread += ssampsread;
- sndseekEx(dz->ifd[0],last_total_ssampsread + dz->buflen,0);
- }
- ibufpos -= dz->buflen; /* as current read succeeded, last input buffer was full: so this val is >= 0 */
- sndtabindex -= (double)dz->buflen;
- }
- val = ibuf[ibufpos++];
- upval = ibuf[ibufpos];
- valdiff = (upval - val) * interp;
- pbuf[pbufpos++] = (float)((val + valdiff) * amp);
- if(pbufpos >= dz->buflen) {
- sprintf(errstr,"Pulse length exceeds length of internal buffer : cannot proceed\n");
- return(GOAL_FAILED);
- }
- }
- amp = gen_sndtabindex(obufpos,&sndtabindex,&pulsenvindex,&envstep,insertsmps,(double)waveset_len,randomise_transpos,dz);
- insertsmps++;
- }
- if(pbufpos > 0) {
- if((exit_status = write_pulse_to_output(&pbufpos,&obufpos,dz))<0)
- return(exit_status);
- }
- /* DO REST OF INPUT FILE AFTER PULSETRAIN, IF NESS */
- if(dz->vflag[PULSE_KEEPEND]) {
- for(;;) {
- ibufleft = ssampsread - ibufpos;
- obufleft = dz->buflen - obufpos;
- spliceptr = obuf+obufpos;
- if(ibufleft >= obufleft) {
- memcpy((char *)(obuf+obufpos),(char *)(ibuf+ibufpos),obufleft * sizeof(float));
- while(edit_todo > 0) {
- k = *spliceptr * ((ENDBIT_SPLICE - (double)edit_todo)/ENDBIT_SPLICE);
- *spliceptr++ = (float)k;
- edit_todo--;
- if(spliceptr >= obufend)
- break;
- }
- ibufpos += obufleft;
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- obufpos = 0;
- } else {
- memcpy((char *)(obuf+obufpos),(char *)(ibuf+ibufpos),ibufleft * sizeof(float));
- while(edit_todo > 0) {
- k = *spliceptr * ((ENDBIT_SPLICE - (double)edit_todo)/ENDBIT_SPLICE);
- *spliceptr++ = (float)k;
- edit_todo--;
- if(spliceptr >= obufend)
- break;
- }
- obufpos += ibufleft;
- if(( exit_status = read_samps(ibuf, dz)) < 0) {
- sprintf(errstr, "Can't read samps from input soundfile\n");
- return(SYSTEM_ERROR);
- }
- ssampsread = dz->ssampsread;
- if(ssampsread <= 0)
- break;
- ibufpos = 0;
- }
- }
- }
- if(obufpos > 0) {
- if((exit_status = write_samps(obuf,obufpos,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
-
- /************************************* GET_WAVESETSTART *************************************/
- int get_wavesetstart(int ibufpos,dataptr dz)
- {
- float *ibuf = dz->sampbuf[0];
-
- if(ibuf[ibufpos] > 0.0) {
- while(ibuf[ibufpos] > 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- }
- } else if(ibuf[ibufpos] < 0.0) {
- while(ibuf[ibufpos] < 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- }
- } else {
- while(smpflteq(ibuf[ibufpos],0.0)) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- }
- }
- return(ibufpos);
- }
- /************************************* EXTRACT_WAVEFORM *************************************/
- // NOV 2002 MAXSAMP -> F_MAXSAMP as well as short -> float
- int extract_waveform(int *waveset_start,dataptr dz)
- {
- int ibufpos = *waveset_start, waveform_len = 0;
- float *ibuf = dz->sampbuf[0];
- float *sbuf = dz->sampbuf[2];
- double frqlimit = dz->infile->srate/PULSE_FRQLIM;
- double amplimit = dbtogain((double)PULSE_DBLIM) * F_MAXSAMP;
- int capture_samps = 0, capture_wavesets = 0;
- int last_waveform_len = 0;
- double maxval, last_maxval = 0.0, wcntr = 0;
- if(dz->mode == PULSE_SYN)
- capture_samps = (int)round(dz->param[PULSE_WAVETIME] * dz->infile->srate);
- else
- capture_wavesets = dz->iparam[PULSE_WAVETIME];
- while(smpflteq(ibuf[ibufpos],0.0)) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- }
- *waveset_start = ibufpos;
- maxval = fabs(ibuf[ibufpos]);
- switch(dz->mode) {
- case(PULSE_SYN):
- for(;;) {
- if(ibuf[ibufpos] > 0.0) {
- while(ibuf[ibufpos] > 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- while(ibuf[ibufpos] <= 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- } else if(ibuf[ibufpos] < 0.0) {
- while(ibuf[ibufpos] < 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- while(ibuf[ibufpos] >= 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- }
- if((waveform_len = ibufpos - *waveset_start) >= capture_samps)
- break;
- else {
- last_waveform_len = waveform_len;
- last_maxval = maxval;
- }
- }
- if(capture_samps - last_waveform_len < waveform_len - capture_samps) {
- waveform_len = last_waveform_len;
- maxval = last_maxval;
- }
- break;
- case(PULSE_SYNI):
- while(wcntr < capture_wavesets) {
- if(ibuf[ibufpos] > 0.0) {
- while(ibuf[ibufpos] > 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- while(ibuf[ibufpos] <= 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- } else if(ibuf[ibufpos] < 0.0) {
- while(ibuf[ibufpos] < 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- while(ibuf[ibufpos] >= 0.0) {
- if(++ibufpos >= dz->buflen)
- return(-1);
- maxval = max(maxval,fabs(ibuf[ibufpos]));
- }
- }
- wcntr++;
- }
- waveform_len = ibufpos - *waveset_start;
- break;
- }
- if(waveform_len <= 0) {
- sprintf(errstr,"Failed to establish a viable sound to loop\n");
- return(GOAL_FAILED);
- } else if((double)waveform_len <= frqlimit) {
- frqlimit = (double)dz->infile->srate/(double)waveform_len;
- fprintf(stdout,"WARNING: Waveset length is only %d samples, corresponding to frq >= %.1lf hz\n",waveform_len,frqlimit);
- fflush(stdout);
- }
- if((double)maxval <= amplimit) {
- fprintf(stdout,"WARNING: Waveset amplitude is <= %lf dB\n",(double)PULSE_DBLIM);
- fflush(stdout);
- }
- memcpy((char *)sbuf,(char *)(ibuf + *waveset_start),waveform_len * sizeof(float));
- return(waveform_len);
- }
- /************************************* GEN_TABINDEX *************************************/
- double gen_sndtabindex(int obufpos,double *sndtabindex,double *pulsenvindex,double *envstep,
- int insertsmps,double tablen,int randomise_transpos,dataptr dz)
- {
- int exit_status;
- double thistime, amp, frq, k;
- *pulsenvindex += *envstep;
- if(*pulsenvindex >= 1.0) {
- if(dz->iparam[PULSE_ENVSIZE] <= 0) { /* no impulse: must continue to end of sndtable (zero-cross) to avoid glitch */
- *sndtabindex += dz->param[PULSE_TRANSPOS]; /* transpos sticks at previous value as table end has been reached */
- if(*sndtabindex >= tablen) {
- *pulsenvindex = 0.0; /* reset to start of envelope */
- *sndtabindex = 0.0;
- thistime = (double)insertsmps/(double)dz->infile->srate;
- if(dz->brksize[PULSE_FRQ] > 0) {
- if((exit_status = read_value_from_brktable(thistime,PULSE_FRQ,dz))<0)
- return exit_status;
- }
- frq = dz->param[PULSE_FRQ];
- if(dz->param[PULSE_FRQRAND] > 0.0) {
- k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_FRQRAND];
- k /= SEMITONES_PER_OCTAVE;
- k = pow(2.0,k);
- frq *= k;
- }
- *envstep = frq/dz->infile->srate;
- if(randomise_transpos && (dz->param[PULSE_PITCHRAND] > 0.0))
- randomise_pulse_transposition(dz);
- }
- return(1.0); /* no impulse: amplitude is always 1.0 */
- }
- /* GET NEW VALUE OF PULSE FRQ, AND HENCE OF STEP IN ENVEL TABLE */
- thistime = (double)insertsmps/(double)dz->infile->srate;
- if(dz->brksize[PULSE_FRQ] > 0) {
- if((exit_status = read_value_from_brktable(thistime,PULSE_FRQ,dz))<0)
- return exit_status;
- }
- frq = dz->param[PULSE_FRQ];
- if(dz->param[PULSE_FRQRAND] > 0.0) {
- k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_FRQRAND];
- k /= SEMITONES_PER_OCTAVE;
- k = pow(2.0,k);
- frq *= k;
- }
- *envstep = frq/dz->infile->srate;
- if(dz->iparam[PULSE_ENVSIZE] > 0)
- randomise_pulse_envelope(obufpos,dz); /* randomise shape of pulse, and copy reshaped pulse to read-env-table */
- /* insert edit shoulders at start and end */
- /* orig envelope has been copied to parray[PULSENV], variant copied back to brk[] */
-
- if(randomise_transpos && (dz->param[PULSE_PITCHRAND] > 0.0))
- randomise_pulse_transposition(dz);
-
- *pulsenvindex = 0.0; /* reset to start of envelope */
- if((exit_status = read_impulse_amp_val(*pulsenvindex,&,dz))<0)
- return exit_status;
- if(dz->mode!=PULSE_IMP)
- *sndtabindex = 0.0;
- else
- *sndtabindex = floor(*sndtabindex + 1.0); /* sync table pointer with actual samples in input stream */
- } else {
- if(dz->iparam[PULSE_ENVSIZE] <= 0) { /* no impulse */
- if(dz->brksize[PULSE_TRANSPOS]) {
- if((exit_status = read_value_from_brktable(*pulsenvindex,PULSE_TRANSPOS,dz))<0)
- return exit_status;
- }
- *sndtabindex += dz->param[PULSE_TRANSPOS];
- *sndtabindex = fmod(*sndtabindex,tablen); /* cycle around soundtable */
- return(1.0); /* no impulse: amplitude is always 1.0 */
- }
- if((exit_status = read_impulse_amp_val(*pulsenvindex,&,dz))<0)
- return exit_status;
- if(dz->brksize[PULSE_TRANSPOS]) {
- if((exit_status = read_value_from_brktable(*pulsenvindex,PULSE_TRANSPOS,dz))<0)
- return exit_status;
- }
- *sndtabindex += dz->param[PULSE_TRANSPOS];
- if(dz->mode!=PULSE_IMP)
- *sndtabindex = fmod(*sndtabindex,tablen);
- }
- return amp;
- }
- /************************************* RANDOMISE_PULSE_ENVELOPE *************************************/
- int randomise_pulse_envelope(int obufpos,dataptr dz)
- {
- int n, m, kk, maxpos, maxmark;
- int *mark = dz->iparray[0];
- double ratio, above, below, randmove, k, maxi, timearound;
- double convertor = (dz->param[PULSE_FRQ] * ENDBIT_SPLICE)/(double)dz->infile->srate;
- double abovestep, belowstep, minbelowtime, minabovetime;
- int not_above, not_below;
- dz->parray[PULSENV][0] = dz->parray[ORIG_PULSENV][0];
- for(n=3;n<dz->iparam[PULSE_ENVSIZE]*2;n+=2) {
- if(dz->parray[ORIG_PULSENV][n] < dz->parray[ORIG_PULSENV][n-2]) {
- ratio = dz->parray[PULSENV][n-2]/dz->parray[ORIG_PULSENV][n-2]; /* ratio of previous val's new height to it's old height */
- above = (dz->parray[ORIG_PULSENV][n-2] - dz->parray[ORIG_PULSENV][n]) * ratio; /* vert distance twixt preceding point & this, scaled */
- below = (dz->parray[ORIG_PULSENV][n]) * ratio; /* vert distance twixt 0 & this, scaled */
- k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_SHAPERAND];
- if(k >= 0.0)
- randmove = above * k;
- else
- randmove = below * k;
- dz->parray[PULSENV][n] = below + randmove;
- } else if(dz->parray[ORIG_PULSENV][n] > dz->parray[ORIG_PULSENV][n-2]) {
- ratio = (1.0 - dz->parray[PULSENV][n-2])/(1.0 - dz->parray[ORIG_PULSENV][n-2]); /* simil ratio of dist from top [1.0] */
- above = (1.0 - dz->parray[ORIG_PULSENV][n]) * ratio; /* vert distance twixt top [1.0] & this point, scaled */
- below = (dz->parray[ORIG_PULSENV][n] - dz->parray[ORIG_PULSENV][n-2]) * ratio; /* vert distance preceeding pnt & this, scaled */
- k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_SHAPERAND];
- if(k >= 0.0)
- randmove = above * k;
- else
- randmove = below * k;
- dz->parray[PULSENV][n] = dz->parray[PULSENV][n-2] + below + randmove;
- } else {
- dz->parray[PULSENV][n] = dz->parray[PULSENV][n-2];
- }
- }
- /* randomise pulse-env timings */
- for(m=1;m < dz->iparam[PULSE_ENVSIZE]-1; m++)
- mark[m] = 0;
- kk = dz->iparam[PULSE_ENVSIZE] - 2;
- while(kk>0) {
- maxi = 0.0;
- maxpos = 0;
- maxmark = 0;
- not_above = 0;
- not_below = 0;
- for(m=1,n=2;n < (dz->iparam[PULSE_ENVSIZE]-1) * 2; n+=2,m++) {
- if(mark[m]==0) {
- timearound = dz->parray[PULSENV][n+2] - dz->parray[PULSENV][n-2];
- if(timearound > maxi) {
- maxi = timearound;
- maxpos = n;
- maxmark = m;
- }
- }
- }
- abovestep = dz->parray[PULSENV][maxpos+3] - dz->parray[PULSENV][maxpos+1];
- belowstep = dz->parray[PULSENV][maxpos+1] - dz->parray[PULSENV][maxpos-1];
- minbelowtime = fabs(convertor * belowstep);
- minabovetime = fabs(convertor * abovestep);
- if((above = dz->parray[PULSENV][maxpos+2] - dz->parray[PULSENV][maxpos]) < minabovetime)
- not_above = 1;
- if((below = dz->parray[PULSENV][maxpos] - dz->parray[PULSENV][maxpos-2]) < minbelowtime)
- not_below = 1;
- if(not_above) {
- if(not_below) {
- sprintf(errstr,"WARNING: possible glitch, due to sudden envelope change, after %lf secs\n",
- (dz->total_samps_written + obufpos)/(double)dz->infile->srate);
- fflush(stdout);
- k = 0.0;
- } else
- k = drand48() * -1.0 * dz->param[PULSE_TIMERAND];
- } else if(not_below)
- k = drand48() * dz->param[PULSE_TIMERAND];
- else
- k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_TIMERAND];
- /* KLUDGE --> */
- k *= 0.5;
- /* <-- KLUDGE */
- if(k >= 0.0)
- randmove = above * k;
- else
- randmove = below * k;
- dz->parray[PULSENV][maxpos] += randmove;
- mark[maxmark] = 1;
- kk--;
- }
- return(FINISHED);
- }
- /************************************* RANDOMISE_PULSE_TRANSPOSITION *************************************/
- void randomise_pulse_transposition(dataptr dz)
- {
- int n, m;
- double k;
- for(n=0,m=1;n<dz->brksize[PULSE_TRANSPOS];n++,m+=2) {
- if(flteq(dz->brk[PULSE_TRANSPOS][m],0.0))
- dz->brk[PULSE_TRANSPOS][m] = 1.0;
- else {
- k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_PITCHRAND];
- k *= dz->parray[PULSTRN][m]/SEMITONES_PER_OCTAVE;
- dz->brk[PULSE_TRANSPOS][m] = pow(2.0,k);
- }
- }
- }
- /************************************* WRITE_PULSE_TO_OUTPUT *************************************/
- int write_pulse_to_output(int *pbufpos,int *obufpos,dataptr dz)
- {
- int exit_status;
- float *obuf = dz->sampbuf[1];
- float *pbuf = dz->sampbuf[3];
- int n, m;
- if(dz->iparam[PULSE_ENVSIZE] > 0) {
- for(n=0;n<round(ENDBIT_SPLICE);n++) /* WRITE PULSE-BUFFER TO OUTPUT, with relevant splices if there's an impulse envelope */
- pbuf[n] = (float)(pbuf[n] * (double)n/ENDBIT_SPLICE);
- for(m = *pbufpos-1,n=0;n<round(ENDBIT_SPLICE);n++,m--)
- pbuf[m] = (float)(pbuf[m] * (double)n/ENDBIT_SPLICE);
- }
- for(n=0;n<*pbufpos;n++) {
- obuf[(*obufpos)++] = pbuf[n];
- if(*obufpos >= dz->buflen) {
- if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
- return(exit_status);
- *obufpos = 0;
- }
- }
- *pbufpos = 0;
- return(FINISHED);
- }
- /**************************** READ_IMPULSE_AMP_VAL *****************************/
- int read_impulse_amp_val(double thistime,double *amp,dataptr dz)
- {
- double *p, lotime, loval, hitime, hival, timediff, step, ratio;
- p = dz->parray[PULSENV];
- if(flteq(thistime,0.0)) {
- *amp = dz->parray[PULSENV][1];
- return(FINISHED);
- }
- while(*p < thistime)
- p += 2;
- p -= 2;
- lotime = *p++;
- loval = *p++;
- hitime = *p++;
- hival = *p++;
- timediff = thistime - lotime;
- step = hival - loval;
- ratio = timediff/(hitime-lotime);
- *amp = loval + (step * ratio);
- return(FINISHED);
- }
|