| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887 |
- /*
- * 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 <stdio.h>
- #include <stdlib.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <globcon.h>
- #include <processno.h>
- #include <modeno.h>
- #include <arrays.h>
- #include <envel.h>
- #include <cdpmain.h>
- #include <sfsys.h>
- #include <osbind.h>
- static int create_initial_envelope_params(double infiledur,dataptr dz);
- static int reallocate_initial_envelope_params(dataptr dz);
- static int allocate_initial_envelope_params(dataptr dz);
- static int find_and_test_attack_peak(dataptr dz);
- static int find_attack_point(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
- static int find_attack_point_using_gate(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
- static int attack_point_definitively_found(int *n,float *buf,/*int*/double *attack_level,int *attack_point,
- int previous_total_samps_read,dataptr dz);
- static int level_is_too_high(float *buf,int abs_samppos,dataptr dz);
- static int level_is_too_high_in_thisbuf(float *buf, double *gain, double tail_gainstep,int chans,
- int n,int *too_high,dataptr dz);
- static int go_to_search_start(dataptr dz);
- static int go_to_max_sample(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
- static int find_local_maximum(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
- static int level_is_too_high_in_thisbuf2(float *buf, double *gain, double tail_gainstep,double maxgain,
- int chans,int n,int *sampcnt,int abs_onset_len,int *too_high,dataptr dz);
- static int level_is_too_high_in_onset(float *buf,int abs_samppos,double tail_gainstep,dataptr dz);
- static int restore_buffers_and_file_to_original_condition(float *buf,int abs_samppos,dataptr dz);
- static int level_is_too_high_in_tail(float *buf,int abs_samppos,double tail_gainstep,dataptr dz);
- static int create_tremol_sintable(dataptr dz);
- static void convert_tremol_frq_to_log10(dataptr dz);
- /***************************** ENVEL_PREPROCESS ******************************/
- int envel_preprocess(dataptr dz)
- {
- int exit_status;
- int filestsmplen;
- //TW UPDATES
- double *d;
- double maxsplen, minwidth;
- int n;
- double sec = (double)(ENV_FSECSIZE)/(double)(dz->infile->channels * dz->infile->srate);
- switch(dz->process) {
- case(ENV_WARPING):
- case(ENV_RESHAPING):
- case(ENV_REPLOTTING):
- switch(dz->mode) {
- case(ENV_NORMALISE): case(ENV_REVERSE): case(ENV_CEILING):
- case(ENV_EXAGGERATING): case(ENV_ATTENUATING): case(ENV_FLATTENING):
- case(ENV_TSTRETCHING): case(ENV_CORRUGATING): case(ENV_PEAKCNT):
- case(ENV_LIFTING): case(ENV_GATING):
- case(ENV_DUCKED): case(ENV_TRIGGERING):
- break;
- case(ENV_LIMITING):
- if(!first_param_not_less_than_second(ENV_LIMIT,ENV_THRESHOLD,dz))
- return(DATA_ERROR);
- break;
- case(ENV_INVERTING):
- if(!first_param_greater_than_second(ENV_MIRROR,ENV_GATE,dz))
- return(DATA_ERROR);
- break;
- case(ENV_EXPANDING):
- if(!first_param_not_less_than_second(ENV_THRESHOLD,ENV_GATE,dz))
- return(DATA_ERROR);
- break;
- default:
- sprintf(errstr,"Unknown case: envwarp,reshape or replot: envelope_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- break;
- case(ENV_CURTAILING):
- switch(dz->mode) {
- case(ENV_START_AND_END):
- case(ENV_START_AND_DUR):
- switch(dz->iparam[ENV_TIMETYPE]) {
- case(ENV_TIMETYPE_SMPS):
- dz->param[ENV_STARTTIME] = (double)(round(dz->param[ENV_STARTTIME])/dz->infile->channels);
- dz->param[ENV_ENDTIME] = (double)(round(dz->param[ENV_ENDTIME])/dz->infile->channels);
- /* fall thro */
- case(ENV_TIMETYPE_STSMPS):
- dz->param[ENV_STARTTIME] = dz->param[ENV_STARTTIME]/(double)dz->infile->srate;
- dz->param[ENV_ENDTIME] = dz->param[ENV_ENDTIME]/(double)dz->infile->srate;
- break;
- case(ENV_TIMETYPE_SECS):
- break;
- default:
- sprintf(errstr,"Unknown case: ENV_CURTAILING: envelope_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- if(dz->param[ENV_STARTTIME] < 0.0 || dz->param[ENV_STARTTIME] >= dz->duration) {
- sprintf(errstr,"Start of fade time : out of range.\n");
- return(USER_ERROR);
- }
- if(dz->mode==ENV_START_AND_DUR) { /* "ENDTIME" is actually FADE DURATION */
- if(dz->param[ENV_ENDTIME] < FLTERR) {
- sprintf(errstr,"Negative or zero fade duration : impossible.\n");
- return(USER_ERROR);
- }
- dz->param[ENV_ENDTIME] = dz->param[ENV_STARTTIME] + dz->param[ENV_ENDTIME];
- if(dz->param[ENV_ENDTIME] > dz->duration + FLTERR) {
- fprintf(stdout,"WARNING: Fade duration goes beyond file end: curtailing to file end.\n");
- fflush(stdout);
- }
- if(dz->param[ENV_ENDTIME] > dz->duration-FLTERR) {
- dz->param[ENV_ENDTIME] = dz->duration;
- }
- } else {
- if(dz->param[ENV_STARTTIME] + sec >= dz->param[ENV_ENDTIME]) {
- sprintf(errstr,"Fade times too close or reversed.\n");
- return(USER_ERROR);
- }
- if(dz->param[ENV_ENDTIME] < 0.0) {
- sprintf(errstr,"End-of-fade time : out of range.\n");
- return(USER_ERROR);
- } else if(dz->param[ENV_ENDTIME] > dz->duration) {
- dz->param[ENV_ENDTIME] = dz->duration;
- fprintf(stdout,"WARNING: End-of-fade beyond file end: defaulting to end of file.\n");
- fflush(stdout);
- }
- }
- break;
- case(ENV_START_ONLY):
- switch(dz->iparam[ENV_TIMETYPE]) {
- case(ENV_TIMETYPE_SMPS):
- dz->param[ENV_STARTTIME] = (double)(round(dz->param[ENV_STARTTIME])/dz->infile->channels);
- /* fall thro */
- case(ENV_TIMETYPE_STSMPS):
- dz->param[ENV_STARTTIME] = dz->param[ENV_STARTTIME]/(double)dz->infile->srate;
- break;
- case(ENV_TIMETYPE_SECS):
- break;
- default:
- sprintf(errstr,"Unknown case: ENV_CURTAILING: envelope_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- dz->param[ENV_ENDTIME] = dz->duration;
- }
- dz->itemcnt = 3;
- if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
- return(exit_status);
- if((exit_status = establish_additional_brktable(dz))<0)
- return(exit_status);
- break;
- case(ENV_DOVETAILING):
- filestsmplen = dz->insams[0]/dz->infile->channels;
- switch(dz->iparam[ENV_TIMETYPE]) {
- case(ENV_TIMETYPE_SMPS):
- dz->param[ENV_STARTTRIM] =
- (double)round(dz->param[ENV_STARTTRIM])/(double)(dz->infile->channels * dz->infile->srate);
- dz->param[ENV_ENDTRIM] =
- (double)round(dz->param[ENV_ENDTRIM])/(double)(dz->infile->channels * dz->infile->srate);
- dz->param[ENV_ENDTRIM] = dz->duration - dz->param[ENV_ENDTRIM];
- break;
- case(ENV_TIMETYPE_STSMPS):
- dz->param[ENV_STARTTRIM] = (double)round(dz->param[ENV_STARTTRIM])/(double)dz->infile->srate;
- dz->iparam[ENV_ENDTRIM] = (int)round(dz->param[ENV_ENDTRIM]);
- dz->iparam[ENV_ENDTRIM] = (int)(filestsmplen - dz->iparam[ENV_ENDTRIM]);
- dz->param[ENV_ENDTRIM] = (double)dz->iparam[ENV_ENDTRIM]/(double)dz->infile->srate;
- break;
- case(ENV_TIMETYPE_SECS):
- dz->param[ENV_ENDTRIM] = dz->duration - dz->param[ENV_ENDTRIM];
- break;
- default:
- sprintf(errstr,"Unknown case: ENV_DOVETAILING: envelope_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- if(dz->param[ENV_ENDTRIM] < 0.0) {
- sprintf(errstr,"End Trim is too large.\n");
- return(USER_ERROR);
- }
- if(dz->param[ENV_STARTTRIM] > dz->duration) {
- sprintf(errstr,"Start Trim is too large.\n");
- return(USER_ERROR);
- }
- if(dz->param[ENV_ENDTRIM] < dz->param[ENV_STARTTRIM]) {
- sprintf(errstr,"Start and End Trims overlap: cannot proceed.\n");
- return(USER_ERROR);
- }
- if(flteq(dz->param[ENV_ENDTRIM],dz->duration) && flteq(dz->param[ENV_STARTTRIM],0.0)) {
- sprintf(errstr,"Start and End Trims are zero: no change in file.\n");
- return(USER_ERROR);
- }
- if(flteq(dz->param[ENV_ENDTRIM],dz->duration) || flteq(dz->param[ENV_STARTTRIM],0.0))
- dz->itemcnt = 3;
- else
- dz->itemcnt = 4;
- if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
- return(exit_status);
- if((exit_status = establish_additional_brktable(dz))<0)
- return(exit_status);
- break;
- case(ENV_SWELL):
- dz->itemcnt = 3;
- if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
- return(exit_status);
- if((exit_status = establish_additional_brktable(dz))<0)
- return(exit_status);
- break;
- case(ENV_ATTACK):
- dz->param[ENV_ATK_GATE] *= (double)F_MAXSAMP; /* RWD actually redundant, but do it anyway */
- if((exit_status = find_and_test_attack_peak(dz))<0)
- return(exit_status);
- dz->param[ENV_ATK_ONSET] *= MS_TO_SECS;
- dz->param[ENV_ATK_TAIL] *= MS_TO_SECS;
- if(dz->iparam[ENV_ATK_ENVTYPE] == ENVTYPE_EXP)
- dz->iparam[ENV_ATK_ENVTYPE] = ENVTYPE_STEEP;
- dz->itemcnt = 5;
- if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
- return(exit_status);
- if((exit_status = establish_additional_brktable(dz))<0)
- return(exit_status);
- break;
- case(ENV_CREATE):
- if(dz->mode==ENV_ENVFILE_OUT) {
- if(dz->extrabrkno>=0) { /* If a brktable passed in from framework */
- if(dz->brk == NULL || dz->brk[dz->extrabrkno] == NULL) { /* clear it */
- sprintf(errstr,"Problem freeing inbrkfile-table: ENV_CREATE: envelope_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- free(dz->brk[dz->extrabrkno]);
- } /* allocate temporary brkpnt array */
- if((exit_status = establish_additional_brktable(dz))<0)
- return(exit_status);
- }
- break;
- case(ENV_EXTRACT): case(ENV_IMPOSE): case(ENV_REPLACE):
- case(ENV_ENVTOBRK): case(ENV_ENVTODBBRK): case(ENV_BRKTOENV):
- case(ENV_DBBRKTOENV):case(ENV_DBBRKTOBRK): case(ENV_BRKTODBBRK):
- //TW NEW CASE
- case(ENV_PROPOR):
- break;
- case(ENV_PLUCK):
- if(dz->infile->channels!=MONO) {
- sprintf(errstr,"This process only works with MONO files\n");
- return(USER_ERROR);
- }
- initrand48();
- break;
- case(ENV_TREMOL):
- if(dz->brksize[ENV_TREM_FRQ] && dz->mode==ENV_TREM_LOG)
- convert_tremol_frq_to_log10(dz);
- return create_tremol_sintable(dz);
- break;
- case(TIME_GRID):
- dz->tempsize = dz->insams[0] * dz->iparam[GRID_COUNT];
- if(dz->brksize[GRID_SPLEN] > 0) {
- d = dz->brk[GRID_SPLEN] + 1;
- for(n= 0;n < dz->brksize[GRID_SPLEN];n++) {
- *d *= MS_TO_SECS;
- d += 2;
- }
- } else
- dz->param[GRID_SPLEN] *= MS_TO_SECS;
- if(dz->brksize[GRID_WIDTH]) {
- if((exit_status = get_minvalue_in_brktable(&minwidth,GRID_WIDTH,dz))<0)
- return(exit_status);
- } else
- minwidth = dz->param[GRID_WIDTH];
- if((exit_status = get_maxvalue(GRID_SPLEN,&maxsplen,dz))<0)
- return(exit_status);
- if(maxsplen >= minwidth) {
- sprintf(errstr,"Maximum splicelen too large for minimum grid-width\n");
- return(DATA_ERROR);
- }
- break;
- default:
- sprintf(errstr,"Unknown case: envelope_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /***************************** CREATE_INITIAL_ENVELOPE_PARAMS ******************************/
- int create_initial_envelope_params(double infiledur,dataptr dz)
- {
- int exit_status, n, in_itemcnt;
- double attack_start, attack_end;
- if((exit_status = allocate_initial_envelope_params(dz))<0)
- return(exit_status);
- switch(dz->process) {
- case(ENV_CURTAILING):
- dz->parray[ENV_CREATE_INTIME][0] = 0.0;
- dz->parray[ENV_CREATE_INLEVEL][0] = 1.0;
- dz->iparray[ENV_SLOPETYPE][0] = ENVTYPE_LIN;
- dz->parray[ENV_CREATE_INTIME][1] = dz->param[ENV_STARTTIME];
- dz->parray[ENV_CREATE_INLEVEL][1] = 1.0;
- dz->iparray[ENV_SLOPETYPE][1] = ENVTYPE_LIN;
- dz->parray[ENV_CREATE_INTIME][2] = dz->param[ENV_ENDTIME];
- dz->parray[ENV_CREATE_INLEVEL][2] = 0.0;
- switch(dz->mode) {
- case(ENV_START_AND_END):
- case(ENV_START_AND_DUR):
- case(ENV_START_ONLY):
- dz->iparray[ENV_SLOPETYPE][2] = dz->iparam[ENV_ENVTYPE];
- break;
- default:
- dz->iparray[ENV_SLOPETYPE][2] = ENVTYPE_DBL;
- break;
- }
- break;
- case(ENV_DOVETAILING):
- n = 0;
- if(flteq(dz->param[ENV_STARTTRIM],0.0)) {
- dz->parray[ENV_CREATE_INTIME][n] = 0.0;
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- n++;
- } else {
- dz->parray[ENV_CREATE_INTIME][n] = 0.0;
- dz->parray[ENV_CREATE_INLEVEL][n] = 0.0;
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- n++;
- dz->parray[ENV_CREATE_INTIME][n] = dz->param[ENV_STARTTRIM];
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- if(dz->mode==DOVE)
- dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_STARTTYPE];
- else
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_DBL;
- n++;
- }
- if(flteq(dz->param[ENV_ENDTRIM],infiledur)) {
- dz->parray[ENV_CREATE_INTIME][n] = infiledur;
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- } else {
- dz->parray[ENV_CREATE_INTIME][n] = dz->param[ENV_ENDTRIM];
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- n++;
- dz->parray[ENV_CREATE_INTIME][n] = infiledur;
- dz->parray[ENV_CREATE_INLEVEL][n] = 0.0;
- if(dz->mode==DOVE)
- dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_ENDTYPE];
- else
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_DBL;
- }
- break;
- case(ENV_SWELL):
- dz->parray[ENV_CREATE_INTIME][0] = 0.0;
- dz->parray[ENV_CREATE_INLEVEL][0] = 0.0;
- dz->iparray[ENV_SLOPETYPE][0] = ENVTYPE_LIN;
- dz->parray[ENV_CREATE_INTIME][1] = dz->param[ENV_PEAKTIME];
- dz->parray[ENV_CREATE_INLEVEL][1] = 1.0;
- dz->iparray[ENV_SLOPETYPE][1] = dz->iparam[ENV_ENVTYPE];
- dz->parray[ENV_CREATE_INTIME][2] = infiledur;
- dz->parray[ENV_CREATE_INLEVEL][2] = 0.0;
- dz->iparray[ENV_SLOPETYPE][2] = dz->iparam[ENV_ENVTYPE];
- break;
- case(ENV_ATTACK):
- in_itemcnt = dz->itemcnt;
- n = 0;
- attack_start = max(0.0,dz->param[ENV_ATK_TIME] - dz->param[ENV_ATK_ONSET]);
- attack_end = min(infiledur,dz->param[ENV_ATK_TIME] + dz->param[ENV_ATK_TAIL]);
- if(dz->param[ENV_ATK_TIME] > 0.0) {
- dz->parray[ENV_CREATE_INTIME][n] = 0.0;
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- n++;
- if(attack_start > 0.0) {
- dz->parray[ENV_CREATE_INTIME][n] = attack_start;
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- n++;
- }
- dz->parray[ENV_CREATE_INTIME][n] = dz->param[ENV_ATK_TIME];
- dz->parray[ENV_CREATE_INLEVEL][n] = dz->param[ENV_ATK_GAIN];
- dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_ATK_ENVTYPE];
- n++;
- } else {
- dz->parray[ENV_CREATE_INTIME][n] = 0.0;
- dz->parray[ENV_CREATE_INLEVEL][n] = dz->param[ENV_ATK_GAIN];
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- n++;
- }
- if(attack_end < infiledur) {
- dz->parray[ENV_CREATE_INTIME][n] = attack_end;
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_ATK_ENVTYPE];
- n++;
- dz->parray[ENV_CREATE_INTIME][n] = infiledur;
- dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
- dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
- n++;
- } else {
- dz->parray[ENV_CREATE_INTIME][3] = infiledur;
- dz->parray[ENV_CREATE_INLEVEL][3] = 1.0;
- dz->iparray[ENV_SLOPETYPE][3] = dz->iparam[ENV_ATK_ENVTYPE];
- }
- dz->itemcnt = n;
- if((dz->itemcnt != in_itemcnt) && (exit_status = reallocate_initial_envelope_params(dz))<0)
- return(exit_status);
- break;
- default:
- sprintf(errstr,"Unknown case in create_initial_envelope_params()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /***************************** REALLOCATE_INITIAL_ENVELOPE_PARAMS ******************************/
- int reallocate_initial_envelope_params(dataptr dz)
- {
- if((dz->parray[ENV_CREATE_INLEVEL] = (double *)realloc
- (dz->parray[ENV_CREATE_INLEVEL],dz->itemcnt * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate input level array.\n");
- return(MEMORY_ERROR);
- }
- if((dz->parray[ENV_CREATE_INTIME] = (double *)realloc
- (dz->parray[ENV_CREATE_INTIME],dz->itemcnt * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate input time array.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ENV_SLOPETYPE] = (int *)realloc
- (dz->iparray[ENV_SLOPETYPE],dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate input slopetype array.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /***************************** ALLOCATE_INITIAL_ENVELOPE_PARAMS ******************************/
- int allocate_initial_envelope_params(dataptr dz)
- {
- if((dz->parray[ENV_CREATE_INLEVEL] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for input level array.\n");
- return(MEMORY_ERROR);
- }
- if((dz->parray[ENV_CREATE_INTIME] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for input time array.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ENV_SLOPETYPE] = (int *)malloc(dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for input slopetype array.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /****************************** FIND_AND_TEST_ATTACK_PEAK *******************************/
- int find_and_test_attack_peak(dataptr dz)
- {
- int exit_status;
- int chans = dz->infile->channels;
- int attack_point_found = FALSE;
- int attack_point=0, abs_samppos;
- float *buf = dz->sampbuf[0];
- if((exit_status = find_attack_point(buf,&attack_point_found,&attack_point,dz))<0)
- return(exit_status);
- if (!attack_point_found) {
- sprintf(errstr,"Gate amplitude not exceeded.\n");
- return(GOAL_FAILED);
- }
- if(dz->insams[0] - attack_point <
- round((ENV_MIN_ATK_ONSET * MS_TO_SECS) * (double)(dz->infile->srate * chans))) {
- sprintf(errstr,"Attack time too late in file to create a new attack.\n");
- return(GOAL_FAILED);
- }
- abs_samppos = (attack_point/chans) * chans;
- if((exit_status = restore_buffers_and_file_to_original_condition(buf,abs_samppos,dz))<0)
- return(exit_status);
- if(level_is_too_high(buf,abs_samppos,dz)) {
- sprintf(errstr,"The attack may distort with this gain level.\n");
- return(GOAL_FAILED);
- }
- if(dz->mode==ENV_ATK_XTIME)
- dz->param[ENV_ATK_TIME] = dz->param[ENV_ATK_ATTIME];
- else
- dz->param[ENV_ATK_TIME] = (double)(attack_point/chans)/(double)(dz->infile->srate);
- reset_filedata_counters(dz);
- if(sndseekEx(dz->ifd[0],0,0)<0) {
- sprintf(errstr,"sndseekEx failed: find_and_test_attack_peak()\n");
- return(SYSTEM_ERROR);
- }
- return(FINISHED);
- }
- /****************************** FIND_ATTACK_POINT *******************************/
- int find_attack_point(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
- {
- int exit_status;
- // int definitely_found = FALSE;
- switch(dz->mode) {
- case(ENV_ATK_GATED):
- return find_attack_point_using_gate(buf,attack_point_found,attack_point,dz);
- case(ENV_ATK_TIMED):
- if((exit_status = go_to_search_start(dz))<0)
- return(exit_status);
- if((exit_status = find_local_maximum(buf,attack_point_found,attack_point,dz))<0)
- return(exit_status);
- break;
- case(ENV_ATK_XTIME):
- *attack_point = round(dz->param[ENV_ATK_ATTIME] * (double)dz->infile->srate) * dz->infile->channels;
- *attack_point_found = TRUE;
- break;
- case(ENV_ATK_ATMAX):
- return go_to_max_sample(buf,attack_point_found,attack_point,dz);
- default:
- sprintf(errstr,"Unknown case in find_attack_point()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /****************************** FIND_ATTACK_POINT_USING_GATE *******************************/
- int find_attack_point_using_gate(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
- {
- int exit_status;
- int definitely_found = FALSE;
- /*int*/double attack_level=0.0;
- int previous_total_samps_read, n;
- while(!definitely_found && (dz->samps_left > 0)) {
- previous_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(buf,dz))<0)
- return(exit_status);
- n = 0;
- while(n<dz->ssampsread) {
- if(!(*attack_point_found)) {
- /*RWD be a little efficient here... */
- double fabsamp = fabs(buf[n]);
- if(/*abs(buf[n])*/fabsamp > dz->param[ENV_ATK_GATE]) {
- attack_level = /* abs(buf[n])*/fabsamp;
- *attack_point = previous_total_samps_read + n;
- *attack_point_found = TRUE;
- }
- }
- if(*attack_point_found) {
- if((definitely_found =
- attack_point_definitively_found(&n,buf,&attack_level,attack_point,previous_total_samps_read,dz))==TRUE)
- break;
- } else
- n++;
- }
- }
- return(FINISHED);
- }
- /****************************** ATTACK_POINT_DEFINITIVELY_FOUND *******************************/
- int attack_point_definitively_found
- (int *n,float *buf,/*int*/double *attack_level,int *attack_point,int previous_total_samps_read,dataptr dz)
- {
- /*int*/double thislevel;
- while(*n < dz->ssampsread) {
- thislevel = fabs(buf[*n]);
- if(thislevel < *attack_level)
- return TRUE;
- else if(thislevel > *attack_level) {
- *attack_level = thislevel;
- *attack_point = previous_total_samps_read + *n;
- }
- (*n)++;
- }
- return(FALSE);
- }
- /****************************** LEVEL_IS_TOO_HIGH *******************************
- *
- * This is an overestimate of risk!!
- */
- int level_is_too_high(float *buf,int abs_samppos,dataptr dz)
- {
- int exit_status;
- // int chans = dz->infile->channels;
- int too_high = FALSE;
- double tail_gainstep = dz->param[ENV_ATK_GAIN] - 1.0;
- switch(dz->mode) {
- case(ENV_ATK_ATMAX):
- break;
- case(ENV_ATK_TIMED):
- case(ENV_ATK_XTIME):
- if((exit_status = level_is_too_high_in_onset(buf,abs_samppos,tail_gainstep,dz))<0)
- return(exit_status);
- if((too_high = exit_status)==TRUE)
- break;
- /* fall thro */
- case(ENV_ATK_GATED):
- if((exit_status = level_is_too_high_in_tail(buf,abs_samppos,tail_gainstep,dz))<0)
- return(exit_status);
- too_high = exit_status;
- break;
- default:
- sprintf(errstr,"Unknown case in level_is_too_high()\n");
- return(PROGRAM_ERROR);
- }
- return(too_high);
- }
- /****************************** LEVEL_IS_TOO_HIGH_IN_THISBUF *******************************/
- int level_is_too_high_in_thisbuf
- (float *buf, double *gain, double tail_gainstep,int chans,int n,int *too_high,dataptr dz)
- {
- int m;
- double thislevel;
- while(n < dz->ssampsread) {
- for(m=0;m<chans;m++) {
- if((thislevel = (double) fabs(buf[n+m]) * (*gain)) > F_MAXSAMP) {
- *too_high = TRUE;
- return(FINISHED);
- }
- }
- if((*gain -= tail_gainstep)<=1.0)
- return(FINISHED);
- n += chans;
- }
- return(CONTINUE);
- }
- /****************************** GO_TO_SEARCH_START *******************************/
- int go_to_search_start(dataptr dz)
- {
- int seccnt;
- int shsecsize = ENV_FSECSIZE;
- double starttime = max(0.0,dz->param[ENV_ATK_ATTIME] - (ENV_ATK_SRCH * MS_TO_SECS));
- int startsamp = round(starttime * (double)dz->infile->srate) * dz->infile->channels;
- if(startsamp >= dz->insams[0]) {
- sprintf(errstr,"Error in sample arithmetic: go_to_search_start()\n");
- return(PROGRAM_ERROR);
- }
- seccnt = startsamp/shsecsize; /* TRUNCATE */
- startsamp = seccnt * shsecsize;
- if(sndseekEx(dz->ifd[0],startsamp,0)<0) {
- sprintf(errstr,"sndseekEx failed: go_to_search_start()\n");
- return(SYSTEM_ERROR);
- }
- /*dz->total_bytes_read = startbyte;*/
- dz->total_samps_read = startsamp;
- dz->samps_left = dz->insams[0] - startsamp;
- return(FINISHED);
- }
- /****************************** GO_TO_MAX_SAMPLE *******************************/
- int go_to_max_sample(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
- {
- int exit_status;
- int previous_total_samps_read = 0, n;
- /*int*/double thislevel;
- /*int*/double attack_level = -1.0;
- *attack_point_found = TRUE;
- while(dz->samps_left > 0) {
- previous_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
- n = 0;
- while(n<dz->ssampsread) {
- if((thislevel = fabs(buf[n])) > attack_level) {
- attack_level = thislevel;
- *attack_point = previous_total_samps_read + n;
- }
- n++;
- }
- }
- return(FINISHED);
- }
- /****************************** FIND_LOCAL_MAXIMUM *******************************/
- int find_local_maximum(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
- {
- int exit_status;
- /*int*/double thislevel;
- int n, m = 0;
- /*int*/double attack_level = -1.0;
- int finished = FALSE;
- int previous_total_samps_read;
- int search_limit = round((ENV_ATK_SRCH * 2.0) * MS_TO_SECS * (double)dz->infile->srate);
- search_limit *= dz->infile->channels;
- if(dz->samps_left <=0) {
- sprintf(errstr,"Error in buffer arithmetic: find_local_maximum()\n");
- return(PROGRAM_ERROR);
- }
- while(!finished && (dz->samps_left > 0)) {
- previous_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
- n = 0;
- while(n<dz->ssampsread) {
- if((thislevel = fabs(buf[n])) > attack_level) {
- attack_level = thislevel;
- *attack_point = previous_total_samps_read + n;
- }
- n++;
- if(++m >= search_limit) {
- finished = TRUE;
- break;
- }
- }
- }
- *attack_point_found = TRUE;
- return(FINISHED);
- }
- /****************************** LEVEL_IS_TOO_HIGH_IN_THISBUF2 *******************************/
- int level_is_too_high_in_thisbuf2(float *buf, double *gain, double tail_gainstep,
- double maxgain,int chans,int n,int *sampcnt,int abs_onset_len,int *too_high,dataptr dz)
- {
- int m;
- double thislevel;
- while(!(*too_high) && (n < dz->ssampsread)) {
- for(m=0;m<chans;m++) {
- if((thislevel = (double) fabs(buf[n+m]) * (*gain)) > F_MAXSAMP) {
- *too_high = TRUE;
- break;
- }
- }
- if((*gain += tail_gainstep)>=maxgain)
- *gain = maxgain;
- if((*sampcnt += chans) >= abs_onset_len)
- return(FINISHED);
- n += chans;
-
- }
- return(CONTINUE);
- }
- /****************************** LEVEL_IS_TOO_HIGH_IN_ONSET *******************************/
- int level_is_too_high_in_onset(float *buf,int abs_samppos,double tail_gainstep,dataptr dz)
- {
- int exit_status;
- int too_high = FALSE;
- int chans = dz->infile->channels;
- double gain = 1.0;
- int this_bufpos;
- int sampcnt = 0;
- int go_back = round(dz->param[ENV_ATK_ONSET] * MS_TO_SECS * (double)dz->infile->srate) * chans;
- int bakpos = max(0,abs_samppos - go_back);
- int abs_onset_len = abs_samppos - bakpos;
- int onset_len = abs_onset_len/chans;
- int bakset = (bakpos/dz->buflen) * dz->buflen;
- if(sndseekEx(dz->ifd[0],bakset,0)<0) {
- sprintf(errstr,"sndseek failed in level_is_too_high_in_onset()\n");
- return(SYSTEM_ERROR);
- }
- this_bufpos = bakpos%dz->buflen;
- dz->total_samps_read = bakset;
- dz->samps_left = dz->insams[0] - dz->total_samps_read;
- tail_gainstep /= (double)onset_len;
- while(!too_high && (dz->samps_left > 0)) {
- if((exit_status = read_samps(buf,dz))<0)
- return(exit_status);
- if(dz->ssampsread <= 0) {
- sprintf(errstr,"read anomaly: level_is_too_high_in_onset()\n");
- return(PROGRAM_ERROR);
- }
- if((exit_status = level_is_too_high_in_thisbuf2(buf,&gain,tail_gainstep,
- dz->param[ENV_ATK_GAIN],chans,this_bufpos,&sampcnt,abs_onset_len,&too_high,dz))==FINISHED)
- break;
- this_bufpos = 0;
- }
- if((exit_status = restore_buffers_and_file_to_original_condition(buf,abs_samppos,dz))<0)
- return(exit_status);
- return(too_high);
- }
- /****************************** RESTORE_BUFFERS_AND_FILE_TO_ORIGINAL_CONDITION *******************************/
- int restore_buffers_and_file_to_original_condition(float *buf,int abs_samppos,dataptr dz)
- {
- int exit_status;
- int reset = (abs_samppos/dz->buflen) * dz->buflen;
- if(sndseekEx(dz->ifd[0],reset,0)<0) {
- sprintf(errstr,"sndseek failed in restore_buffers_and_file_to_original_condition()\n");
- return(SYSTEM_ERROR);
- }
- if((exit_status = read_samps(buf,dz))<0)
- return(exit_status);
- if(dz->ssampsread <= 0) {
- sprintf(errstr,"read anomaly: restore_buffers_and_file_to_original_condition()\n");
- return(PROGRAM_ERROR);
- }
- dz->total_samps_read = reset + dz->ssampsread;
- dz->samps_left = dz->insams[0] - dz->total_samps_read;
- return(FINISHED);
- }
- /****************************** LEVEL_IS_TOO_HIGH_IN_TAIL *******************************/
- int level_is_too_high_in_tail(float *buf,int abs_samppos,double tail_gainstep,dataptr dz)
- {
- int exit_status;
- int too_high = FALSE;
- int chans = dz->infile->channels;
- double gain = dz->param[ENV_ATK_GAIN];
- int tail_len = round((dz->param[ENV_ATK_TAIL] * MS_TO_SECS) * (double)dz->infile->srate);
- int buf_samppos = abs_samppos % dz->buflen;
- tail_gainstep /= (double)tail_len;
- if((exit_status = level_is_too_high_in_thisbuf
- (buf,&gain,tail_gainstep,chans,buf_samppos,&too_high,dz))==FINISHED)
- return(too_high);
- while(dz->samps_left > 0) {
- if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
- return(exit_status);
- buf_samppos = 0;
- if((exit_status = level_is_too_high_in_thisbuf
- (buf,&gain,tail_gainstep,chans,buf_samppos,&too_high,dz))==FINISHED)
- break;
- }
- return(too_high);
- }
- /************************** CREATE_TREMOL_SINTABLE ******************/
- int create_tremol_sintable(dataptr dz)
- {
- int n;
- if((dz->parray[ENV_SINETAB] = (double *)malloc((ENV_TREM_TABSIZE + 1) * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for sine table.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<ENV_TREM_TABSIZE;n++) {
- dz->parray[ENV_SINETAB][n] = sin(PI * 2.0 * ((double)n/(double)ENV_TREM_TABSIZE));
- dz->parray[ENV_SINETAB][n] += 1.0;
- dz->parray[ENV_SINETAB][n] /= 2.0;
- }
- dz->parray[ENV_SINETAB][n] = 0.5; /* wrap around point */
- return(FINISHED);
- }
- /************************** CONVERT_TREMOL_FRQ_TO_LOG10 ******************/
- void convert_tremol_frq_to_log10(dataptr dz)
- {
- double *p, *pend;
- double infiledur = (double)dz->insams[0]/(double)dz->infile->srate;
- double effectively_zero = 1.0/infiledur;
- p = dz->brk[ENV_TREM_FRQ];
- pend = p + (dz->brksize[ENV_TREM_FRQ] * 2);
- p++;
- while(p < pend) {
- if(*p <= effectively_zero)
- *p = effectively_zero;
- *p = log10(*p);
- p += 2;
- }
- }
-
|