| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593 |
- /*
- * 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 TW */
- #include <stdio.h>
- #include <stdlib.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <pnames.h>
- #include <globcon.h>
- #include <processno.h>
- #include <modeno.h>
- #include <arrays.h>
- #include <flags.h>
- #include <highlight.h>
- #include <cdpmain.h>
- #include <formants.h>
- #include <speccon.h>
- #include <sfsys.h>
- #include <osbind.h>
- #include <highlight.h>
- //TW UPDATE
- #include <vowels.h>
- #if defined unix || defined __GNUC__
- #define round(x) lround((x))
- #endif
- static int do_filtering(double frq_limit,double hifrq_limit,dataptr dz);
- static int below_limitfrq_and_zeroed(int vc,double loskirt,dataptr dz);
- static int below_limitfrq_and_filtered(int vc,double limitfrq,double loskirt,double loskirt_bwidth,dataptr dz);
- static int above_limitfrq_and_zeroed(int vc,double hiskirt,dataptr dz);
- static int filter_above_limitfrq(int vc,double limitfrq,double hiskirt,double hiskirt_bwidth,dataptr dz);
- static int filtered_in_lower_skirt(int vc,double skirttop,double loskirt,double loskirt_bwidth,dataptr dz);
- static int filtered_in_upper_skirt(int vc,double skirt_bottom,double hiskirt,double hiskirt_bwidth,dataptr dz);
- static int do_greq_filter(dataptr dz);
- static int invert_greq_filter_envelope(dataptr dz);
- static int process_specsplit_channel(int cc,bandptr bb,dataptr dz);
- static int do_on(double bandhilimit,double bandlolimit,dataptr dz);
- static int do_below(double bandmid,dataptr dz);
- static int do_above(double bandmid,dataptr dz);
- static int do_boost(double bandhilimit,double bandlolimit,dataptr dz);
- static int do_above_boost(double bandhilimit,double bandlolimit,int *in_start_portion, dataptr dz);
- static int do_below_boost(double bandhilimit,double bandlolimit,int *in_start_portion,dataptr dz);
- static int do_once_below(double bandlolimit,int *in_start_portion,dataptr dz);
- static int do_once_above(double bandhilimit,int *in_start_portion,dataptr dz);
- static int initiate_new_arpeg_note(int cc,int vc,dataptr dz);
- static int initiate_new_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz);
- static int temporarily_sustain_arpeg_note(int cc,double thisamp,dataptr dz);
- static int temporarily_sustain_arpeg_note_with_fixed_pitch(int cc,int vc,double thisamp,dataptr dz);
- static int get_non_linear_decimation(double *nonlin_dec,int cc,dataptr dz);
- static int get_decimation(double *dec,int cc,dataptr dz);
- static int sustain_arpeg_note(int cc,int vc,dataptr dz);
- static int sustain_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz);
- static int nonlin_sustain_arpeg_note(int cc,int vc, dataptr dz);
- static int nonlin_sustain_arpeg_note_with_fixed_pitch(int cc, int vc, dataptr dz);
- static int set_bit_to_zero(int bflagno,int mask,dataptr dz);
- static int set_bit_to_one(int bflagno,int mask,dataptr dz);
- static int outside_skirts(int vc,double loskirt,double hiskirt,dataptr dz);
- static int reset_timechanging_arpe_variables(double *frqrange,double *lofrq, double *hifrq,dataptr dz);
- static int locate_current_wavetable_position(dataptr dz);
- //TW UPDATE
- static int do_vowel_filter(double *vamp,double formant1,double formant2,double formant3,double f2atten,double f3atten,
- double *sensitivity,int senslen,dataptr dz);
- static int get_formant_frqs
- (int vowel,double *formant1, double *formant2, double *formant3, double *f2atten, double *f3atten);
- static int define_sensitivity_curve(double **sensitivity,int *senslen);
- static int adjust_for_sensitivity(double *amp,double frq,double *sensitivity,int senslen);
- /**************************** SPECFILT ***************************/
- int specfilt(dataptr dz)
- {
- int exit_status;
- int vc;
- double frq_limit, hifrq_limit = 0.0, pre_amptotal, post_amptotal;
- if(dz->brksize[FILT_QQ])
- dz->param[FILT_QQ] = exp(dz->param[FILT_QQ]);
- if(dz->brksize[FILT_FRQ1])
- frq_limit = exp(dz->param[FILT_FRQ1]);
- else
- frq_limit = dz->param[FILT_FRQ1];
- switch(dz->mode) {
- case(F_BND):
- case(F_BND_NORM):
- case(F_NOTCH):
- case(F_NOTCH_NORM):
- case(F_BAND_GAIN):
- case(F_NOTCH_GAIN):
- if(dz->brksize[FILT_FRQ2])
- hifrq_limit = exp(dz->param[FILT_FRQ2]);
- else
- hifrq_limit = dz->param[FILT_FRQ2];
- if(frq_limit > hifrq_limit)
- swap(&frq_limit,&hifrq_limit);
- break;
- }
- if((exit_status = get_totalamp(&pre_amptotal,dz->flbufptr[0],dz->wanted))<0)
- return(exit_status);
- if((exit_status = do_filtering(frq_limit,hifrq_limit,dz))<0)
- return(exit_status);
- if((exit_status = get_totalamp(&post_amptotal,dz->flbufptr[0],dz->wanted))<0)
- return(exit_status);
- switch(dz->mode) {
- case(F_HI_NORM):
- case(F_LO_NORM):
- case(F_BND_NORM):
- case(F_NOTCH_NORM): /* normalised output */
- if((exit_status = normalise(pre_amptotal,post_amptotal,dz))<0)
- return(exit_status);
- break;
- case(F_HI_GAIN):
- case(F_LO_GAIN):
- case(F_BAND_GAIN):
- case(F_NOTCH_GAIN): /* post-gain */
- for(vc = 0; vc < dz->wanted; vc += 2)
- dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * dz->param[FILT_PG]);
- break;
- }
- return(FINISHED);
- }
- /**************************** DO_FILTERING ***************************/
- int do_filtering(double frq_limit,double hifrq_limit,dataptr dz)
- {
- int exit_status;
- int vc;
- double loskirt, loskirt_bwidth, hiskirt, hiskirt_bwidth;
- switch(dz->mode) {
- case(F_HI):
- case(F_HI_NORM):
- case(F_HI_GAIN):
- loskirt = max(0.0,(frq_limit - dz->param[FILT_QQ]));
- loskirt_bwidth = frq_limit - loskirt;
- for(vc = 0; vc < dz->wanted; vc += 2) {
- if((exit_status = below_limitfrq_and_zeroed(vc,loskirt,dz))<0)
- return(exit_status);
- if(exit_status==TRUE)
- continue;
- if((exit_status = below_limitfrq_and_filtered(vc,frq_limit,loskirt,loskirt_bwidth,dz))<0)
- return(exit_status);
- }
- break;
- case(F_LO):
- case(F_LO_NORM):
- case(F_LO_GAIN):
- hiskirt = min(dz->nyquist,(frq_limit + dz->param[FILT_QQ]));
- hiskirt_bwidth = hiskirt - frq_limit;
- for(vc = 0; vc < dz->wanted; vc += 2) {
- if((exit_status = above_limitfrq_and_zeroed(vc,hiskirt,dz))<0)
- return(exit_status);
- if(exit_status==TRUE)
- continue;
- if((exit_status = filter_above_limitfrq(vc,frq_limit,hiskirt,hiskirt_bwidth,dz))<0)
- return(exit_status);
- }
- break;
- case(F_BND):
- case(F_BND_NORM):
- case(F_BAND_GAIN):
- loskirt = max(0.0,(frq_limit - dz->param[FILT_QQ]));
- loskirt_bwidth = frq_limit - loskirt;
- hiskirt = min(dz->nyquist,(hifrq_limit + dz->param[FILT_QQ]));
- hiskirt_bwidth = hiskirt - hifrq_limit;
- for(vc = 0; vc < dz->wanted; vc += 2) {
- if((exit_status = below_limitfrq_and_zeroed(vc,loskirt,dz))<0)
- return(exit_status);
- if(exit_status==TRUE)
- continue;
- if((exit_status = below_limitfrq_and_filtered(vc,frq_limit,loskirt,loskirt_bwidth,dz))<0)
- return(exit_status);
- if(exit_status == TRUE)
- continue;
- if((exit_status = above_limitfrq_and_zeroed(vc,hiskirt,dz))<0)
- return(exit_status);
- if(exit_status == TRUE)
- continue;
- if((exit_status = filter_above_limitfrq(vc,hifrq_limit,hiskirt,hiskirt_bwidth,dz))<0)
- return(exit_status);
- }
- break;
- case(F_NOTCH):
- case(F_NOTCH_NORM):
- case(F_NOTCH_GAIN):
- loskirt = max(0.0,(frq_limit - dz->param[FILT_QQ]));
- loskirt_bwidth = frq_limit - loskirt;
- hiskirt = min(dz->nyquist,(hifrq_limit + dz->param[FILT_QQ]));
- hiskirt_bwidth = hiskirt - hifrq_limit;
- for(vc = 0; vc < dz->wanted; vc += 2) {
- if(outside_skirts(vc,loskirt,hiskirt,dz))
- continue;
- if((exit_status = filtered_in_lower_skirt(vc,frq_limit,loskirt,loskirt_bwidth,dz))<0)
- return(exit_status);
- if(exit_status==TRUE)
- continue;
- if((exit_status = filtered_in_upper_skirt(vc,hifrq_limit,hiskirt,hiskirt_bwidth,dz))<0)
- return(exit_status);
- if(exit_status==TRUE)
- continue;
- dz->flbufptr[0][AMPP] = 0.0F;
- }
- break;
- default:
- sprintf(errstr,"unknown mode in do_filtering()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /**************************** BELOW_LIMITFRQ_AND_ZEROED ***************************/
- int below_limitfrq_and_zeroed(int vc,double loskirt,dataptr dz)
- {
- if(dz->flbufptr[0][FREQ] < loskirt) {
- dz->flbufptr[0][AMPP] = 0.0F;
- return(TRUE);
- }
- return(FALSE);
- }
- /**************************** BELOW_LIMITFRQ_AND_FILTERED ***************************/
- int below_limitfrq_and_filtered(int vc,double limitfrq,double loskirt,double loskirt_bwidth,dataptr dz)
- {
- if(dz->flbufptr[0][FREQ] < limitfrq) {
- dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * ((dz->flbufptr[0][FREQ] - loskirt)/loskirt_bwidth));
- return(TRUE);
- }
- return(FALSE);
- }
- /**************************** FILTER_ABOVE_LIMITFRQ ***************************/
- int filter_above_limitfrq(int vc,double limitfrq,double hiskirt,double hiskirt_bwidth,dataptr dz)
- {
- if(dz->flbufptr[0][FREQ] > limitfrq) {
- dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * ((hiskirt - dz->flbufptr[0][FREQ])/hiskirt_bwidth));
- return(TRUE);
- }
- return(FALSE);
- }
- /**************************** ABOVE_LIMITFRQ_AND_ZEROED ***************************/
- int above_limitfrq_and_zeroed(int vc,double hiskirt,dataptr dz)
- {
- if(dz->flbufptr[0][FREQ] > hiskirt) {
- dz->flbufptr[0][AMPP] = 0.0F;
- return(TRUE);
- }
- return(FALSE);
- }
- /**************************** FILTER_IN_LOWER_SKIRT ***************************/
- int filtered_in_lower_skirt(int vc,double skirttop,double loskirt,double loskirt_bwidth,dataptr dz)
- {
- if(dz->flbufptr[0][FREQ] < skirttop) {
- dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * (1.0 - ((dz->flbufptr[0][FREQ] - loskirt)/loskirt_bwidth)));
- return(TRUE);
- }
- return(FALSE);
- }
- /**************************** FILTER_IN_UPPER_SKIRT ***************************/
- int filtered_in_upper_skirt(int vc,double skirt_bottom,double hiskirt,double hiskirt_bwidth,dataptr dz)
- {
- if(dz->flbufptr[0][FREQ] > skirt_bottom) {
- dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * (1.0 - ((hiskirt - dz->flbufptr[0][FREQ])/hiskirt_bwidth)));
- return(TRUE);
- }
- return(FALSE);
- }
- /*********************** SPECGREQ **********************/
- int specgreq(dataptr dz)
- {
- int exit_status;
- if((exit_status = construct_filter_envelope((int)dz->itemcnt,dz->flbufptr[0],dz))<0)
- return(exit_status);
- if(dz->vflag[GREQ_NOTCH]) {
- if((exit_status = invert_greq_filter_envelope(dz))<0)
- return(exit_status);
- }
- if((exit_status = do_greq_filter(dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /****************************** DO_GREQ_FILTER ***************************/
- int do_greq_filter(dataptr dz)
- {
- int cc, vc;
- for(cc=0, vc=0; cc < dz->clength; cc++, vc += 2)
- dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * dz->fsampbuf[cc]);
- return(FINISHED);
- }
- /****************************** INVERT_GREQ_FILTER_ENVELOPE ***************************/
- int invert_greq_filter_envelope(dataptr dz)
- {
- int cc;
- for(cc=0; cc<dz->clength; cc++)
- dz->fsampbuf[cc] = (float)(1.0 - dz->fsampbuf[cc]);
- return(FINISHED);
- }
- /******************************** SPECSPLIT ******************************/
- int specsplit(dataptr dz)
- {
- int exit_status;
- int cc, bno = 0, bottom, top, done = 0, k;
- bandptr bb;
- double bandbot, bandtop;
- rectify_window(dz->flbufptr[0],dz);
- if((exit_status = get_amp_and_frq(dz->flbufptr[0],dz))<0)
- return(exit_status);
- cc = 0; /* channel counter */
- while(bno<dz->itemcnt) { /* For all bands */
- bb = dz->band[bno];
- bandbot = bb->bfrqlo;
- bandtop = bb->bfrqhi;
- while(dz->freq[cc]<bandbot) { /* while chan-frq<bandbot: do nothing */
- if(++cc>=dz->clength) {
- done = 1;
- break; /* if all channels<bandbot, we.ve finished pass */
- }
- }
- if(done)
- break;
- bottom = cc; /* set bottom channel for inner loop */
- while(dz->freq[cc]<bandtop) {
- if(++cc>=dz->clength) {
- done = 1; /* find channels up to top of band */
- break;
- }
- }
- top = min(cc,(dz->clength)-1); /* set top channel for inner loop */
- if((bb->bdoflag & DO_TRANSPOSITION) && bb->btrans>1.0) {
- for( k = top; k>= bottom; k--) {
- if((exit_status = process_specsplit_channel(k,bb,dz))<0)
- return(exit_status);
- }
- } else {
- for( k = bottom; k <= top; k++) {
- if((exit_status = process_specsplit_channel(k,bb,dz))<0)
- return(exit_status);
- }
- }
- if(done)
- break;
- bno++;
- }
- if((exit_status = put_amp_and_frq(dz->flbufptr[0],dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /************************ PROCESS_SPECSPLIT_CHANNEL *****************************/
- int process_specsplit_channel(int cc,bandptr bb,dataptr dz)
- {
- int exit_status;
- double thismult;
- double newamp = dz->amp[cc]; /* DEFAULT */
- double newfrq = dz->freq[cc]; /* DEFAULT */
- int newchan;
- if(bb->bdoflag & DO_AMPLITUDE_CHANGE) {
- if(bb->bdoflag & DO_RAMPED_AMPLITUDE) {
- thismult = (dz->freq[cc] - bb->bfrqlo)/(bb->bfrqdif);
- thismult *= bb->bampdif;
- thismult += bb->bamp;
- newamp = dz->amp[cc] * thismult;
- } else
- newamp = dz->amp[cc] * bb->bamp;
- }
- if(bb->bdoflag & DO_TRANSPOSITION) {
- if(bb->badditive) {
- if((newfrq = dz->freq[cc] + bb->btrans)<dz->nyquist) {
- if((exit_status = get_channel_corresponding_to_frq(&newchan,newfrq,dz))<0)
- return(exit_status);
- if(newchan!=cc) {
- dz->freq[newchan] = (float)newfrq;
- dz->amp[newchan] = (float)newamp;
- }
- }
- } else {
- if((newfrq = dz->freq[cc] * bb->btrans)<dz->nyquist) {
- if((exit_status = get_channel_corresponding_to_frq(&newchan,newfrq,dz))<0)
- return(exit_status);
- if(newchan!=cc) {
- dz->freq[newchan] = (float)newfrq;
- dz->amp[newchan] = (float)newamp;
- }
- }
- }
- if(!(bb->bdoflag & DO_ADD_TO_SPECTRUM)) {
- newamp = /* set interpolated value on old amp */
- (dz->amp[max(cc-1,0)] + dz->amp[min(cc+1,(dz->clength-1))])/2.0;
- }
- }
- dz->freq[cc] = (float)newfrq;
- dz->amp[cc] = (float)newamp;
- return(FINISHED);
- }
- /********************************** SPECARPE **********************************/
- int specarpe(int *in_start_portion,dataptr dz)
- {
- int exit_status;
- double lofrq, hifrq, frqrang;
- double bandmid, bandhilimit, bandlolimit;
- int tabindex;
- if((exit_status = reset_timechanging_arpe_variables(&frqrang,&lofrq,&hifrq,dz))<0)
- return(exit_status);
- if((exit_status = locate_current_wavetable_position(dz))<0)
- return(exit_status);
- tabindex = round(dz->param[ARPE_WAVETABPOS]);
- /* LOCATE CURRENT FREQUENCY BAND */
- bandmid = (dz->parray[ARPE_TAB][tabindex] * frqrang) + lofrq;
- bandhilimit = min(bandmid + dz->param[ARPE_HBAND],dz->nyquist);
- bandlolimit = max(bandmid - dz->param[ARPE_HBAND],0.0);
-
- if((exit_status = get_amp_and_frq(dz->flbufptr[0],dz))<0) /* SEPARATE THE AMP AND FREQ DATA */
- return(exit_status);
- switch(dz->mode) { /* ELIMINATE OR MODIFY FREQUENCIES, AS NECESSARY */
- case(ON): exit_status = do_on(bandhilimit,bandlolimit,dz); break;
- case(BELOW): exit_status = do_below(bandmid,dz); break;
- case(ABOVE): exit_status = do_above(bandmid,dz); break;
- case(BOOST): exit_status = do_boost(bandhilimit,bandlolimit,dz); break;
- case(ABOVE_BOOST): exit_status = do_above_boost(bandhilimit,bandlolimit,in_start_portion,dz); break;
- case(BELOW_BOOST): exit_status = do_below_boost(bandhilimit,bandlolimit,in_start_portion,dz); break;
- case(ONCE_ABOVE): exit_status = do_once_above(bandhilimit,in_start_portion,dz); break;
- case(ONCE_BELOW): exit_status = do_once_below(bandlolimit,in_start_portion,dz); break;
- default:
- sprintf(errstr,"unknown mode in specarpe()\n");
- return(PROGRAM_ERROR);
- }
- if(exit_status<0)
- return(exit_status);
- if((exit_status = put_amp_and_frq(dz->flbufptr[0],dz))<0) /* WRITE MODIFIED AMP & FREQ BUFF TO SAMP BUFF */
- return(exit_status);
- return(FINISHED);
- }
- /*************************** DO_ON ****************************/
- int do_on(double bandhilimit,double bandlolimit,dataptr dz)
- {
- int exit_status;
- int cc, vc = 0;
- double dec, nonlin_dec = 0.0, thisamp;
- switch(dz->iparam[ARPE_SUSFLAG]) {
- case(AP_NORMAL):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- } else {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- case(AP_SUSTAIN_PITCH):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- case(AP_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = get_decimation(&dec,cc,dz))<0)
- return(exit_status);
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- case(AP_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = get_decimation(&dec,cc,dz))<0)
- return(exit_status);
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- case(AP_NONLIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = nonlin_sustain_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- } else {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- case(AP_NONLIN_AND_SUSTAIN_PITCH):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- case(AP_NONLIN_AND_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
- return(exit_status);
- }
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = nonlin_sustain_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- case(AP_NONLIN_AND_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
- return(exit_status);
- }
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else
- dz->amp[cc] = 0.0f;
- }
- }
- break;
- }
- return(FINISHED);
- }
- /******************************* DO_BELOW **************************/
- int do_below(double bandmid,dataptr dz)
- {
- int cc;
- for(cc=0;cc<dz->clength;cc++) {
- if(dz->freq[cc]>bandmid)
- dz->amp[cc] = 0.0f;
- //TW JULY 2006
- else
- dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
- }
- return(FINISHED);
- }
- /******************************** DO_ABOVE ***********************/
- int do_above(double bandmid,dataptr dz)
- {
- int cc;
- for(cc=0;cc<dz->clength;cc++) {
- if(dz->freq[cc]<bandmid)
- dz->amp[cc] = 0.0f;
- //TW JULY 2006
- else
- dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
- }
- return(FINISHED);
- }
- /**************************** DO_BOOST ****************************/
- int do_boost(double bandhilimit,double bandlolimit,dataptr dz)
- {
- int exit_status;
- int cc, vc;
- double dec, nonlin_dec = 0.0,thisamp;
- switch(dz->iparam[ARPE_SUSFLAG]) {
- case(AP_NORMAL):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- break;
- case(AP_SUSTAIN_PITCH):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- break;
- case(AP_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = get_decimation(&dec,cc,dz))<0)
- return(exit_status);
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- }
- break;
- case(AP_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = get_decimation(&dec,cc,dz))<0)
- return(exit_status);
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- }
- break;
- case(AP_NONLIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
- return(exit_status);
- if(dz->iparray[ARPE_KEEP][cc]) {
- dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * nonlin_dec);
- dz->iparray[ARPE_KEEP][cc]--;
- } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- break;
- case(AP_NONLIN_AND_SUSTAIN_PITCH):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- break;
- case(AP_NONLIN_AND_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
- return(exit_status);
- }
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = nonlin_sustain_arpeg_note(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- }
- break;
- case(AP_NONLIN_AND_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
- return(exit_status);
- }
- if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
- if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- } else {
- if(dz->iparray[ARPE_KEEP][cc]) {
- if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
- return(exit_status);
- }
- }
- }
- break;
- }
- return(FINISHED);
- }
- /************************* DO_ABOVE_BOOST ****************************/
- int do_above_boost(double bandhilimit,double bandlolimit,int *in_start_portion, dataptr dz)
- {
- int cc;
- if(*in_start_portion) {
- if((dz->iparam[ARPE_WTYPE]==SIN || dz->iparam[ARPE_WTYPE]==SAW)) {
- if(dz->param[ARPE_WAVETABPOS]>=ARPE_TABSIZE/2)
- *in_start_portion = FALSE;
- } else {
- if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
- *in_start_portion = FALSE;
- }
- }
- if(*in_start_portion) {
- for(cc=0;cc<dz->clength;cc++) {
- if(dz->freq[cc]>bandlolimit)
- dz->amp[cc] = 0.0f;
- //TW JULY 2006
- else
- dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL] * dz->iparam[ARPE_SUST]);
- }
- } else
- return do_boost(bandhilimit,bandlolimit,dz);
- return(FINISHED);
- }
- /**************************** DO_BELOW_BOOST ************************/
- int do_below_boost(double bandhilimit,double bandlolimit,int *in_start_portion,dataptr dz)
- {
- int cc;
- if(*in_start_portion) {
- if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
- *in_start_portion = FALSE;
- }
- if(*in_start_portion) {
- for(cc=0;cc<dz->clength;cc++) {
- if(dz->freq[cc]<bandhilimit)
- dz->amp[cc] = 0.0f;
- //TW JULY 2006
- else
- dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL] * dz->iparam[ARPE_SUST]);
- }
- } else
- return do_boost(bandhilimit,bandlolimit,dz);
- return(FINISHED);
- }
- /************************** DO_ONCE_BELOW ***************************/
- int do_once_below(double bandlolimit,int *in_start_portion,dataptr dz)
- {
- int cc;
- if(*in_start_portion) {
- if((dz->iparam[ARPE_WTYPE]==SIN || dz->iparam[ARPE_WTYPE]==SAW)) {
- if(dz->param[ARPE_WAVETABPOS] >= ARPE_TABSIZE/2)
- *in_start_portion = FALSE;
- } else {
- if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
- *in_start_portion = FALSE;
- }
- }
- if(*in_start_portion) {
- for(cc=0;cc<dz->clength;cc++) {
- if(dz->freq[cc]>bandlolimit)
- dz->amp[cc] = 0.0f;
- //TW JULY 2006
- else
- dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
- }
- }
- return(FINISHED);
- }
- /***************************** DO_ONCE_ABOVE **************************/
- int do_once_above(double bandhilimit,int *in_start_portion,dataptr dz)
- {
- int cc;
- if(*in_start_portion) {
- if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
- *in_start_portion = FALSE;
- }
- if(*in_start_portion) {
- for(cc=0;cc<dz->clength;cc++) {
- if(dz->freq[cc]<bandhilimit)
- dz->amp[cc] = 0.0f;
- //TW JULY 2006
- else
- dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
- }
- }
- return(FINISHED);
- }
- /******************** INITIATE_NEW_ARPEG_NOTE ********************/
- int initiate_new_arpeg_note(int cc,int vc,dataptr dz)
- {
- dz->iparray[ARPE_KEEP][cc] = dz->iparam[ARPE_SUST];
- dz->amp[cc] *= (float)(dz->param[ARPE_AMPL] * dz->iparray[ARPE_KEEP][cc]);
- dz->windowbuf[0][AMPP] = dz->amp[cc];
- (dz->iparray[ARPE_KEEP][cc])--;
- return(FINISHED);
- }
- /******************** INITIATE_NEW_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
- int initiate_new_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz)
- {
- dz->iparray[ARPE_KEEP][cc] = dz->iparam[ARPE_SUST];
- dz->amp[cc] *= (float)(dz->param[ARPE_AMPL] * dz->iparray[ARPE_KEEP][cc]);
- dz->windowbuf[0][AMPP] = dz->amp[cc];
- dz->windowbuf[0][FREQ] = dz->freq[cc];
- dz->iparray[ARPE_KEEP][cc]--;
- return(FINISHED);
- }
- /******************** TEMPORARILY_SUSTAIN_ARPEG_NOTE ********************/
- int temporarily_sustain_arpeg_note(int cc,double thisamp,dataptr dz)
- {
- dz->amp[cc] = (float)thisamp;
- dz->iparray[ARPE_KEEP][cc]--;
- return(FINISHED);
- }
- /******************** TEMPORARILY_SUSTAIN_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
- int temporarily_sustain_arpeg_note_with_fixed_pitch(int cc,int vc,double thisamp,dataptr dz)
- {
- dz->amp[cc] = (float)thisamp;
- dz->freq[cc] = dz->windowbuf[0][FREQ];
- dz->iparray[ARPE_KEEP][cc]--;
- return(FINISHED);
- }
- /******************** GET_NON_LINEAR_DECIMATION ********************/
- int get_non_linear_decimation(double *nonlin_dec,int cc,dataptr dz)
- {
- *nonlin_dec = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
- *nonlin_dec = pow(*nonlin_dec,dz->param[ARPE_NONLIN]);
- return(FINISHED);
- }
- /******************** GET_DECIMATION ********************/
- int get_decimation(double *dec,int cc,dataptr dz)
- {
- *dec = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
- return(FINISHED);
- }
- /******************** SUSTAIN_ARPEG_NOTE ********************/
- int sustain_arpeg_note(int cc,int vc,dataptr dz)
- {
- double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
- dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
- dz->iparray[ARPE_KEEP][cc]--;
- return(FINISHED);
- }
- /******************** SUSTAIN_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
- int sustain_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz)
- {
- double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
- dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
- dz->freq[cc] = dz->windowbuf[0][FREQ];
- dz->iparray[ARPE_KEEP][cc]--;
- return(FINISHED);
- }
- /******************** NONLIN_SUSTAIN_ARPEG_NOTE ********************/
- int nonlin_sustain_arpeg_note(int cc,int vc, dataptr dz)
- {
- double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
- z = pow(z,dz->param[ARPE_NONLIN]);
- dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
- dz->iparray[ARPE_KEEP][cc]--;
- return(FINISHED);
- }
- /******************** NONLIN_SUSTAIN_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
- int nonlin_sustain_arpeg_note_with_fixed_pitch(int cc, int vc, dataptr dz)
- {
- double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
- z = pow(z,dz->param[ARPE_NONLIN]);
- dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
- dz->freq[cc] = dz->windowbuf[0][FREQ];
- dz->iparray[ARPE_KEEP][cc]--;
- return(FINISHED);
- }
- /****************************** SPECPLUCK ****************************/
- int specpluck(dataptr dz)
- {
- int exit_status;
- int mask = 1;
- int cc, vc, bflagno, is_set;
- if(dz->total_windows==1) { /* Set up BITFLAGS for current state of chans */
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2){
- if((exit_status = choose_bflagno_and_reset_mask_if_ness
- (&bflagno,cc,&mask,dz->iparam[PLUK_LONGPOW2],dz->iparam[PLUK_DIVMASK]))<0)
- return(exit_status);
- if(!flteq((double)dz->flbufptr[0][AMPP],0.0))
- dz->lparray[PLUK_BFLG][bflagno] |= mask;
- mask <<= 1;
- }
- } else { /* Check change of state of channels */
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2){
- if((exit_status = choose_bflagno_and_reset_mask_if_ness
- (&bflagno,cc,&mask,dz->iparam[PLUK_LONGPOW2],dz->iparam[PLUK_DIVMASK]))<0)
- return(exit_status);
- is_set = dz->lparray[PLUK_BFLG][bflagno] & mask;
- if(!flteq((double)dz->flbufptr[0][vc],0.0)) { /* If chan amp NOT zero */
- if(!is_set) { /* if bit previously 0 (for zero amp) */
- dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] * dz->param[PLUK_GAIN]);
- exit_status = set_bit_to_one(bflagno,mask,dz); /* Give boost to chan amp */
- }
- } else { /* channel amp IS zero */
- if(is_set) /* if bit previously 1 for nonzero amp */
- exit_status = set_bit_to_zero(bflagno,mask,dz);
- }
- mask <<= 1; /* move bitmask upwards */
- }
- }
- return(FINISHED);
- }
- /****************************** SET_BIT_TO_ZERO ****************************/
- int set_bit_to_zero(int bflagno,int mask,dataptr dz)
- {
- mask = ~mask; /* bit-invert mask */
- dz->lparray[PLUK_BFLG][bflagno] &= mask; /* Set bit to 0 */
- return(FINISHED);
- }
- /****************************** SET_BIT_TO_ONE ****************************/
- int set_bit_to_one(int bflagno,int mask,dataptr dz)
- {
- dz->lparray[PLUK_BFLG][bflagno] |= mask;
- return(FINISHED);
- }
- /********************************** SPECTRACE **********************************/
- int spectrace(dataptr dz)
- {
- int exit_status;
- int invtrindex, cc, vc;
- int chans_outside_fltband_to_keep = 0, chans_in_filtband;
- double hifrq_limit = 0.0, lofrq_limit = 0.0;
- chvptr quietest, loudest;
- if((dz->mode == TRC_ALL || dz->vflag[TRACE_RETAIN]) && dz->iparam[TRAC_INDX] >= dz->clength)
- return(FINISHED);
- if(dz->mode != TRC_ALL) {
- hifrq_limit = dz->param[TRAC_HIFRQ];
- lofrq_limit = dz->param[TRAC_LOFRQ];
- if(hifrq_limit < lofrq_limit)
- swap(&hifrq_limit,&lofrq_limit);
- if(dz->vflag[TRACE_RETAIN] ) {
- chans_in_filtband = dz->clength;
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
- chans_in_filtband--;
- }
- if((chans_outside_fltband_to_keep = dz->iparam[TRAC_INDX] - chans_in_filtband) <= 0) {
- chans_outside_fltband_to_keep = 0;
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
- dz->flbufptr[0][AMPP] = 0.0f;
- }
- }
- } else {
- for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
- if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
- dz->flbufptr[0][AMPP] = 0.0f;
- }
- }
- }
- if(chans_outside_fltband_to_keep>0) {
- if((exit_status = initialise_ring_vals(chans_outside_fltband_to_keep,-BIGAMP,dz))<0)
- return(exit_status);
- for(vc = 0; vc < dz->wanted; vc += 2) {
- if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit) {
- if((exit_status = if_one_of_loudest_chans_store_in_ring(vc,dz))<0)
- return(exit_status);
- dz->flbufptr[0][AMPP] = 0.0F;
- }
- }
- /* RESTORE TRUE AMPLITUDE (STORED IN RING) IN LOUDEST OUTSIDER CHANNELS ONLY */
- loudest = dz->ringhead;
- do {
- dz->flbufptr[0][loudest->loc] = loudest->val;
- } while((loudest = loudest->next)!=dz->ringhead);
- } else {
- if(dz->iparam[TRAC_INDX]>(dz->clength/2)) { /* IF MORE CHANS TO KEEP THAN TO REJECT */
- invtrindex = dz->clength - dz->iparam[TRAC_INDX]; /* COUNT CHANS TO REJECT */
- if((exit_status = initialise_ring_vals(invtrindex,BIGAMP,dz))<0)/* MAXIMISE ALL QUIETEST STORES IN RING */
- return(exit_status);
- for(vc = 0; vc < dz->wanted; vc += 2) { /* STORE INDICES OF QUIETEST CHANS */
- if((exit_status = if_one_of_quietest_chans_store_in_ring(vc,dz))<0)
- return(exit_status);
- }
- quietest = dz->ringhead;
- do { /* ZERO ALL QUIETEST CHANS */
- dz->flbufptr[0][quietest->loc] = 0.0F;
- } while((quietest = quietest->next)!=dz->ringhead);
- } else { /* IF MORE CHANS TO REJECT THAN TO KEEP */
- if((exit_status = initialise_ring_vals(dz->iparam[TRAC_INDX],-BIGAMP,dz))<0)
- return(exit_status); /* MINIMISE ALL LOUDEST STORES IN RING */
- 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); /* STORE INDICES OF LOUDEST CHANS */
- dz->flbufptr[0][AMPP] = 0.0F; /* INITIALISE EVERY CHANNEL TO ZERO AMP */
- }
- loudest = dz->ringhead;
- do { /* RESTORE AMPLITUDE IN LOUDEST CHANS ONLY */
- dz->flbufptr[0][loudest->loc] = loudest->val;
- } while((loudest = loudest->next)!=dz->ringhead);
- }
- }
- return(FINISHED);
- }
- /**************************** OUTSIDE_SKIRTS ***************************/
- int outside_skirts(int vc,double loskirt,double hiskirt,dataptr dz)
- {
- if(dz->flbufptr[0][FREQ] < loskirt || dz->flbufptr[0][FREQ] > hiskirt)
- return(TRUE);
- return(FALSE);
- }
- /***************************** RESET_TIMECHANGING_ARPE_VARIABLES **************************/
- int reset_timechanging_arpe_variables(double *frqrange,double *lofrq, double *hifrq,dataptr dz)
- {
- double this_arpfrq;
- if(dz->brksize[ARPE_ARPFRQ]) { /* RESET ARPFREQ, if ness */
- this_arpfrq = (dz->param[ARPE_LASTARPFRQ] + dz->param[ARPE_ARPFRQ])/2.0;
- dz->param[ARPE_LASTARPFRQ] = dz->param[ARPE_ARPFRQ];
- dz->param[ARPE_ARPFRQ] = this_arpfrq;
- }
- /* RESET arp amplification, if ness */
- //TW JULY 2006
- if(dz->mode < BELOW) {
- if(dz->brksize[ARPE_AMPL] || dz->brksize[ARPE_SUST])
- dz->param[ARPE_AMPL] /= (double)dz->iparam[ARPE_SUST];
- }
- *lofrq = dz->param[ARPE_LOFRQ]; /* RESET arp hi and lo limits */
- *hifrq = dz->param[ARPE_HIFRQ];
- if((dz->brksize[ARPE_LOFRQ] || dz->brksize[ARPE_HIFRQ])
- && (*hifrq < *lofrq))
- swap(hifrq,lofrq);
- *frqrange = *hifrq - *lofrq;
- return(FINISHED);
- }
- /******************** LOCATE_CURRENT_WAVETABLE_POSITION ********************/
- int locate_current_wavetable_position(dataptr dz)
- {
- double tabincr;
- tabincr = dz->frametime * dz->param[ARPE_ARPFRQ] * ARPE_TABSIZE;
- dz->param[ARPE_LAST_TABPOS] = dz->param[ARPE_WAVETABPOS];
- dz->param[ARPE_WAVETABPOS] = fmod(dz->param[ARPE_WAVETABPOS] + tabincr,(double)ARPE_TABSIZE);
- return(FINISHED);
- }
- //TW UPDATE: NEW FUNCTIONS (adjusted for float)
- /************************************ VOWEL_FILTER ************************************/
- #define NOISEBASE (0.2)
- int vowel_filter(dataptr dz)
- {
- int *vowels = dz->iparray[0];
- double *times = dz->parray[0];
- double startformant1, startformant2, startformant3, endformant1, endformant2, endformant3;
- double formant1, formant2, formant3;
- double form1step, form2step, form3step;
- double starttime, endtime, time, timefrac, timestep, *sensitivity;
- double f3startatten, f3endatten, f3attenstep, f3atten;
- double f2startatten, f2endatten, f2attenstep, f2atten;
- int exit_status, senslen;
- int n = 0, t = 0;
- double *amp;
- int total_windows_got, windows_in_buf;
- if((amp = (double *)malloc(dz->clength * sizeof(double)))==NULL) {
- sprintf(errstr,"Insufficient memory to store vowel envelope\n");
- return(MEMORY_ERROR);
- }
- if((exit_status = define_sensitivity_curve(&sensitivity,&senslen))<0)
- return(exit_status);
- dz->flbufptr[0] = dz->bigfbuf;
- if((exit_status = get_formant_frqs
- (vowels[t],&startformant1,&startformant2,&startformant3,&f2startatten,&f3startatten))<0)
- return(exit_status);
- starttime = times[t++];
- if((exit_status = get_formant_frqs(vowels[t],&endformant1,&endformant2,&endformant3,&f2endatten,&f3endatten))<0)
- return(exit_status);
- endtime = times[t++];
- form1step = endformant1 - startformant1;
- form2step = endformant2 - startformant2;
- form3step = endformant3 - startformant3;
- f2attenstep = f2endatten - f2startatten;
- f3attenstep = f3endatten - f3startatten;
- timestep = endtime-starttime;
- formant1 = startformant1; /* works if only one vowel is entered (for time zero) */
- formant2 = startformant2;
- formant3 = startformant3;
- f2atten = f2startatten;
- f3atten = f3startatten;
- total_windows_got = 0;
- while(n < dz->wlength) {
- if(n >= total_windows_got) {
- if((exit_status = read_samps(dz->bigfbuf, dz)) < 0) {
- sprintf(errstr,"Problem reading source analysis data.\n");
- return(SYSTEM_ERROR);
- }
- dz->flbufptr[0] = dz->bigfbuf;
- windows_in_buf = dz->ssampsread/dz->wanted;
- total_windows_got += windows_in_buf;
- }
- if(dz->itemcnt) {
- time = n * dz->frametime;
- while(time >= endtime) { /* advance along vowels */
- startformant1 = endformant1;
- startformant2 = endformant2;
- startformant3 = endformant3;
- f2startatten = f2endatten;
- f3startatten = f3endatten;
- starttime = endtime;
- if(t < dz->itemcnt) {
- if((exit_status = get_formant_frqs(vowels[t],&endformant1,&endformant2,&endformant3,&f2endatten,&f3endatten))<0)
- return(exit_status);
- endtime = times[t++];
- } else
- break;
- form1step = endformant1 - startformant1;
- form2step = endformant2 - startformant2;
- form3step = endformant3 - startformant3;
- f2attenstep = f2endatten - f2startatten;
- f3attenstep = f3endatten - f3startatten;
- timestep = endtime-starttime;
- }
- if(!flteq(starttime,endtime)) { /* interpolate between vowels : or retain last vowel */
- timefrac = (time - starttime)/timestep;
- formant1 = startformant1 + (form1step * timefrac);
- formant2 = startformant2 + (form2step * timefrac);
- formant3 = startformant3 + (form3step * timefrac);
- f2atten = f2startatten + (f2attenstep * timefrac);
- f3atten = f3startatten + (f3attenstep * timefrac);
- }
- }
- if((exit_status = do_vowel_filter
- (amp,formant1,formant2,formant3,f2atten,f3atten,sensitivity,senslen,dz)) <0)
- return(exit_status);
- if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[1]) {
- if((exit_status = write_samps(dz->bigfbuf,dz->buflen,dz))<0)
- return(exit_status);
- dz->flbufptr[0] = dz->bigfbuf;
- }
- n++;
- }
- if(dz->flbufptr[0] != dz->bigfbuf) {
- if((exit_status = write_samps(dz->bigfbuf,dz->flbufptr[0] - dz->bigfbuf,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
-
- /************************************ DO_VOWEL_FILTER ************************************
- *
- * "sensitivity" compensates for frq sensitivity of ear at low end, and attenuates
- * formant bands above c3500.
- */
- int do_vowel_filter(double *vamp,double formant1,double formant2,double formant3,double f2atten,double f3atten,
- double *sensitivity,int senslen,dataptr dz)
- {
- double hfwidth1, hfwidth2, hfwidth3 = 0.0, lolim1, lolim2, lolim3 = 0.0, hilim1, hilim2, hilim3 = 0.0;
- // double thisfrq, amp, amp2, amp3 = 0.0, totamp = 0.0;
- double thisfrq, amp, amp2 = 0.0, amp3 = 0.0;
- int exit_status, cc, vc;
- int overlapped_formants12 = 0, overlapped_formants23 = 0, overlapped_formants13 = 0;
- int is_overlap12, is_overlap23, is_overlap13;
- double toplim, pre_totamp, post_totamp, maxamp, maxvamp, ampscale;
- int is_third_formant = 0;
- double signal_base = 1.0 - dz->param[PV_PKRANG];
- if(formant3 > 0.0)
- is_third_formant = 1;
- hfwidth1 = formant1 * dz->param[PV_HWIDTH]; /* set limits of formant bands */
- lolim1 = formant1 - hfwidth1;
- hilim1 = formant1 + hfwidth1;
- hfwidth2 = formant2 * dz->param[PV_HWIDTH];
- lolim2 = formant2 - hfwidth2;
- hilim2 = formant2 + hfwidth2;
- if(is_third_formant) {
- hfwidth3 = formant3 * dz->param[PV_HWIDTH];
- lolim3 = formant3 - hfwidth3;
- hilim3 = formant3 + hfwidth3;
- }
- if(hilim1 > lolim2) /* deal with overlapping formants */
- overlapped_formants12 = 1;
- if(is_third_formant) {
- if(hilim2 > lolim3)
- overlapped_formants23 = 1;
- if(hilim1 > lolim3)
- overlapped_formants13 = 1;
- }
- if(is_third_formant)
- toplim = hilim3;
- else
- toplim = hilim2;
- maxamp = 0.0;
- pre_totamp = 0.0;
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
- pre_totamp += dz->flbufptr[0][AMPP];
- maxamp = max(dz->flbufptr[0][AMPP],maxamp);
- }
- maxvamp = 0.0;
- /* find the formant envelope amplitude at frequency of every window */
- if(!is_third_formant)
- hilim3 = hilim2;
- for(cc = 0, vc = 0;cc <dz->clength; cc++, vc += 2) {
- thisfrq = dz->flbufptr[0][FREQ];
- amp = 0.0;
- is_overlap12 = 0;
- is_overlap23 = 0;
- is_overlap13 = 0;
- if(thisfrq < lolim1 || thisfrq > hilim3)
- ;
- else if((thisfrq > lolim1) && (thisfrq < hilim1)) {
- if(overlapped_formants12 && (thisfrq > lolim2)) {
- is_overlap12 = 1;
- if(thisfrq >= formant2)
- amp2 = (hilim2 - thisfrq)/hfwidth2;
- else
- amp2 = (thisfrq - lolim2)/hfwidth2;
- amp2 *= f2atten;
- }
- if(is_third_formant) {
- if(overlapped_formants13 && (thisfrq > lolim3)) {
- is_overlap13 = 1;
- if(thisfrq >= formant3)
- amp3 = (hilim3 - thisfrq)/hfwidth3;
- else
- amp3 = (thisfrq - lolim3)/hfwidth3;
- amp3 *= f3atten;
- }
- }
- if(thisfrq >= formant1)
- amp = (hilim1 - thisfrq)/hfwidth1;
- else
- amp = (thisfrq - lolim1)/hfwidth1;
- if(is_overlap12)
- amp = max(amp,amp2);
- if(is_third_formant && is_overlap13)
- amp = max(amp,amp3);
- } else if((thisfrq > lolim2) && (thisfrq < hilim2)) {
- if(is_third_formant && overlapped_formants23 && (thisfrq > lolim3)) {
- is_overlap23 = 1;
- if(thisfrq >= formant3)
- amp3 = (hilim3 - thisfrq)/hfwidth3;
- else
- amp3 = (thisfrq - lolim3)/hfwidth3;
- amp3 *= f3atten;
- }
- if(thisfrq >= formant2)
- amp = (hilim2 - thisfrq)/hfwidth2;
- else
- amp = (thisfrq - lolim2)/hfwidth2;
- amp *= f2atten;
- if(is_third_formant && is_overlap23)
- amp = max(amp,amp3);
- } else if(is_third_formant && (thisfrq > lolim3)) {
- if(thisfrq >= formant3)
- amp = (hilim3 - thisfrq)/hfwidth3;
- else
- amp = (thisfrq - lolim3)/hfwidth3;
- amp *= f3atten;
- }
- amp = pow(amp,dz->param[PV_CURVIT]);
- amp *= dz->param[PV_PKRANG];
- amp += signal_base;
- if((exit_status = adjust_for_sensitivity(&,(double)thisfrq,sensitivity,senslen))<0)
- return(exit_status);
- vamp[cc] = amp;
- maxvamp = max(maxvamp,vamp[cc]);
- }
- /* set scaling factor to allow for max level of input window */
- if(flteq(maxvamp,0.0))
- ampscale = 0.0;
- else
- ampscale = (maxamp/maxvamp);
- post_totamp = 0.0;
- for(cc = 0,vc = 0;cc <dz->clength; cc++,vc += 2) {
- vamp[cc] *= ampscale;
- /* force window to formant level ONLY if existing val > a given proportion of formant level */
- if((double)dz->flbufptr[0][AMPP] > vamp[cc] * dz->param[VF_THRESH])
- dz->flbufptr[0][AMPP] = (float)vamp[cc];
- post_totamp += dz->flbufptr[0][AMPP];
- }
- /* normalise to overall level of original window */
- if((exit_status = normalise(pre_totamp,post_totamp,dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /************************************ DEFINE_SENSITIVITY_CURVE ************************************
- *
- * approximate compensation for aural sensitivity
- */
- #define LOFRQ_BOOST (2.511) /* 8dB */
- #define HIFRQ_LOSS (0.4) /* -8dB */
- #define LOFRQ_FOOT (250.0)
- #define MIDFRQSHELF_BOT (2000.0)
- #define MIDFRQSHELF_TOP (3000.0)
- #define HIFRQ_FOOT (4000.0)
- #define TOP_OF_SPECTRUM (96000.0) /* double maximum nyquist (i.e. >nyquist: for safety margin) */
- int define_sensitivity_curve(double **sensitivity,int *senslen)
- {
- int arraysize = BIGARRAY;
- double *p;
- int n = 0;
- if((*sensitivity = (double *)malloc(arraysize * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for time data.\n");
- return(MEMORY_ERROR);
- }
- p = *sensitivity;
- *p++ = 0.0; *p++ = 1.0; n+= 2; /* everything must be in 0-1 range */
- *p++ = LOFRQ_FOOT; *p++ = 1.0; n+= 2; /* for pow() calculations to work, later */
- *p++ = MIDFRQSHELF_BOT; *p++ = 1.0/LOFRQ_BOOST; n+= 2;
- *p++ = MIDFRQSHELF_TOP; *p++ = 1.0/LOFRQ_BOOST; n+= 2;
- *p++ = HIFRQ_FOOT; *p++ = HIFRQ_LOSS/LOFRQ_BOOST; n+= 2;
- *p++ = TOP_OF_SPECTRUM; *p++ = HIFRQ_LOSS/LOFRQ_BOOST; n+= 2;
- if((*sensitivity = (double *)realloc((char *)(*sensitivity),n * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for sensitivity curve.\n");
- return(MEMORY_ERROR);
- }
- *senslen = n;
- return(FINISHED);
- }
- /************************************ GET_FORMANT_FRQS ************************************/
- int get_formant_frqs
- (int vowel,double *formant1, double *formant2, double *formant3, double *f2atten, double *f3atten)
- {
- switch(vowel) {
- case(VOWEL_EE): *formant1= EE_FORMANT1; *formant2= EE_FORMANT2; *formant3= EE_FORMANT3;
- /* heed */ *f2atten = EE_F2ATTEN; *f3atten = EE_F3ATTEN;
- break;
- case(VOWEL_I): *formant1= I_FORMANT1; *formant2= I_FORMANT2; *formant3= I_FORMANT3;
- /* hid */ *f2atten = I_F2ATTEN; *f3atten = I_F3ATTEN;
- break;
- case(VOWEL_AI): *formant1= AI_FORMANT1; *formant2= AI_FORMANT2; *formant3= AI_FORMANT3;
- /* maid */ *f2atten = AI_F2ATTEN; *f3atten = AI_F3ATTEN;
- break;
- case(VOWEL_AII): *formant1= AII_FORMANT1; *formant2= AII_FORMANT2; *formant3= AII_FORMANT3;
- /* scottish educAted */ *f2atten = AII_F2ATTEN; *f3atten = AII_F3ATTEN;
- break;
- case(VOWEL_E): *formant1= E_FORMANT1; *formant2= E_FORMANT2; *formant3= E_FORMANT3;
- /* head */ *f2atten = E_F2ATTEN; *f3atten = E_F3ATTEN;
- break;
- case(VOWEL_A): *formant1= A_FORMANT1; *formant2= A_FORMANT2; *formant3= A_FORMANT3;
- /* had */ *f2atten = A_F2ATTEN; *f3atten = A_F3ATTEN;
- break;
- case(VOWEL_AR): *formant1= AR_FORMANT1; *formant2= AR_FORMANT2; *formant3= AR_FORMANT3;
- /* hard */ *f2atten = AR_F2ATTEN; *f3atten = AR_F3ATTEN;
- break;
- case(VOWEL_O): *formant1= O_FORMANT1; *formant2= O_FORMANT2; *formant3= O_FORMANT3;
- /* hod */ *f2atten = O_F2ATTEN; *f3atten = O_F3ATTEN;
- break;
- case(VOWEL_OR): *formant1= OR_FORMANT1; *formant2= OR_FORMANT2; *formant3= OR_FORMANT3;
- /* hoard */ *f2atten = OR_F2ATTEN; *f3atten = OR_F3ATTEN;
- break;
- case(VOWEL_OA): *formant1= OA_FORMANT1; *formant2= OA_FORMANT2; *formant3= OA_FORMANT3;
- /* load (North of England) */ *f2atten = OA_F2ATTEN; *f3atten = OA_F3ATTEN;
- break;
- case(VOWEL_U): *formant1= U_FORMANT1; *formant2= U_FORMANT2; *formant3= U_FORMANT3;
- /* hood, mud (North of England) */ *f2atten = U_F2ATTEN; *f3atten = U_F3ATTEN;
- break;
- case(VOWEL_UU): *formant1= UU_FORMANT1; *formant2= UU_FORMANT2; *formant3= UU_FORMANT3;
- /* Scottish edUcated */ *f2atten = UU_F2ATTEN; *f3atten = UU_F3ATTEN;
- break;
- case(VOWEL_UI): *formant1= UI_FORMANT1; *formant2= UI_FORMANT2; *formant3= UI_FORMANT3;
- /* Scottish 'could' */ *f2atten = UI_F2ATTEN; *f3atten = UI_F3ATTEN;
- break;
- case(VOWEL_OO): *formant1= OO_FORMANT1; *formant2= OO_FORMANT2; *formant3= OO_FORMANT3;
- /* mood */ *f2atten = OO_F2ATTEN; *f3atten = OO_F3ATTEN;
- break;
- case(VOWEL_XX): *formant1= XX_FORMANT1; *formant2= XX_FORMANT2; *formant3= XX_FORMANT3;
- /* mud (South of England) */ *f2atten = XX_F2ATTEN; *f3atten = XX_F3ATTEN;
- break;
- case(VOWEL_X): *formant1= X_FORMANT1; *formant2= X_FORMANT2; *formant3 = X_FORMANT3;
- /* the, herd */ *f2atten = X_F2ATTEN; *f3atten = X_F3ATTEN;
- break;
- case(VOWEL_N): *formant1= N_FORMANT1; *formant2= N_FORMANT2; *formant3 = N_FORMANT3;
- /* 'n' */ *f2atten = N_F2ATTEN; *f3atten = N_F3ATTEN;
- break;
- case(VOWEL_M): *formant1= M_FORMANT1; *formant2= M_FORMANT2; *formant3 = M_FORMANT3;
- /* 'm' */ *f2atten = M_F2ATTEN; *f3atten = M_F3ATTEN;
- break;
- case(VOWEL_R): *formant1= R_FORMANT1; *formant2= R_FORMANT2; *formant3 = R_FORMANT3;
- /* dRaws */ *f2atten = R_F2ATTEN; *f3atten = R_F3ATTEN;
- break;
- case(VOWEL_TH): *formant1= TH_FORMANT1; *formant2= TH_FORMANT2; *formant3 = TH_FORMANT3;
- /* 'THe' */ *f2atten = TH_F2ATTEN; *f3atten = TH_F3ATTEN;
- break;
- default:
- sprintf(errstr,"Unknown vowel\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /************************************ ADJUST_FOR_SENSITIVITY ************************************/
- int adjust_for_sensitivity(double *amp,double frq,double *sensitivity,int senslen)
- {
- int n = 0;
- double multiplier, losensfrq, hisensfrq, losens, hisens, frqfrac, sensstep;
- while(frq > sensitivity[n]) {
- n += 2;
- if(n > senslen) {
- sprintf(errstr,"Failed to find sensitivity value (1)\n");
- return(PROGRAM_ERROR);
- }
- }
- hisensfrq = sensitivity[n];
- n -= 2;
- if(n < 0) {
- *amp *= sensitivity[1];
- return(FINISHED);
- }
- losensfrq = sensitivity[n];
- frqfrac = (frq - losensfrq)/(hisensfrq - losensfrq);
- n++;
- losens = sensitivity[n];
- n += 2;
- if(n >= senslen) {
- sprintf(errstr,"Failed to find sensitivity value (3)\n");
- return(PROGRAM_ERROR);
- }
- hisens = sensitivity[n];
- sensstep = hisens - losens;
- multiplier = losens + (sensstep * frqfrac);
- *amp *= multiplier;
- return(FINISHED);
- }
|