synthesis.c 191 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157
  1. /*
  2. * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. // TO DO !!!
  22. // need to bakup standalone.h, newsynth.exe and this file
  23. // NEED TO do SLOOM interface
  24. // Try putting signal in at each fractal level , as it's a bit THIN at present (FLAG - but different process)
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <structures.h>
  28. #include <tkglobals.h>
  29. #include <pnames.h>
  30. #include <filetype.h>
  31. #include <processno.h>
  32. #include <modeno.h>
  33. #include <logic.h>
  34. #include <globcon.h>
  35. #include <cdpmain.h>
  36. #include <math.h>
  37. #include <mixxcon.h>
  38. #include <osbind.h>
  39. #include <standalone.h>
  40. #include <ctype.h>
  41. #include <sfsys.h>
  42. #include <string.h>
  43. #include <srates.h>
  44. #ifdef unix
  45. #include <aaio.h>
  46. #endif
  47. #define S_OFF 0
  48. #define S_ON 1
  49. #define SIGNAL_TO_LEFT (0)
  50. #define SIGNAL_TO_RIGHT (1)
  51. #define ROOT2 (1.4142136)
  52. #define SYN_FROMROOT 0
  53. #define SYN_TOROOT 1
  54. #define SYN_SPACED 2
  55. #define SYN_X 3
  56. #define SYN_JUMP 4
  57. #define SYNDUFF_MIN
  58. #ifdef unix
  59. #define round(x) lround((x))
  60. #endif
  61. #ifndef HUGE
  62. #define HUGE 3.40282347e+38F
  63. #endif
  64. #define spikelen ringsize
  65. #define SPIKEMAX 0.95
  66. #define MAXFRAC 27 // at maxsamprate 96000, and min frq .001 = 96000000 samples =?= 2^27
  67. #define AT_END 0
  68. char errstr[2400];
  69. int anal_infiles = 1;
  70. int sloom = 0;
  71. int sloombatch = 0;
  72. const char* cdp_version = "7.0.0";
  73. //CDP LIB REPLACEMENTS
  74. static int setup_synthesizer_application(dataptr dz);
  75. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  76. static int setup_synthesis_param_ranges_and_defaults(dataptr dz);
  77. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  78. static int open_the_outfile(dataptr dz);
  79. static int handle_the_special_data(char *str,dataptr dz);
  80. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  81. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  82. static int establish_application(dataptr dz);
  83. static int initialise_vflags(dataptr dz);
  84. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  85. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  86. static int mark_parameter_types(dataptr dz,aplptr ap);
  87. static int assign_file_data_storage(int infilecnt,dataptr dz);
  88. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  89. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  90. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  91. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  92. static int synthesis_param_preprocess(int **perm,int **permon,int **permoff,int **superperm,double *minrate,int *maxsteps,dataptr dz);
  93. static int synthesis(int *perm,int *permon,int *permoff,int *superperm,double minrate,int maxsteps,dataptr dz);
  94. static void incr_sinptr(int n,double time,double onehzincr,dataptr dz);
  95. static double read_level(int n,double time,dataptr dz);
  96. static int create_synthesizer_sndbufs(dataptr dz);
  97. static int generate_packet_envelope (dataptr dz);
  98. static double read_packet_envelope(int kk,double incr,dataptr dz);
  99. static int modify_packet_envelope(dataptr dz);
  100. static void rndintperm(int *perm,int cnt);
  101. static void get_current_partial_vals(double time,double *pvals,int totalpartials,dataptr dz);
  102. static void pancalc(double position,double *leftgain,double *rightgain);
  103. static void sort_partials_into_ascending_frq_order(int total_partialcnt,double *pvals,double *sinptr,
  104. double **llev,double **rlev,int **onoff,int **lmost,int **origspl,int *splordr,dataptr dz);
  105. static void resort_partials_into_original_frq_order(int total_partialcnt,double *pvals,double *sinptr,
  106. double **llev,double **rlev,int **onoff,int **lmost,int **origspl,int *splordr,dataptr dz);
  107. static void xclusive(int *perm,int *permon,int *permoff,int max_partials_cnt,int partials_in_play, int **onoff,int stepcnt);
  108. static double emergepos(int emergchan,int chans,double time,double timespan);
  109. static double convergepos(int converchan,int chans,double time,double convergetime,double dur);
  110. static void spacebox_apply(double pos, double lev,int chans,int *lmost, int *rmost,double *rlev,double *llev,int spacetyp);
  111. static void output_special_spatialisation_sample(float *obuf,int sampcnt,int switchpos,int chans,double val,double valr,int lmost,int rmost,int spacetyp);
  112. static void spacebox(double *pos, int *switchpos, double posstep, int chans, int spacetyp, int configno, int configcnt,int *superperm);
  113. static double sinread(double *tabpos,double frq,dataptr dz);
  114. static void duffing_osc(double *val,double *vel, double delta_t,double *tabpos,dataptr dz);
  115. static int duffing(dataptr dz);
  116. static int check_synth_param_validity_and_consistency(dataptr dz);
  117. static int fractal(dataptr dz);
  118. /**************************************** MAIN *********************************************/
  119. int main(int argc,char *argv[])
  120. {
  121. int exit_status;
  122. dataptr dz = NULL;
  123. char **cmdline, sfnam[400];
  124. int cmdlinecnt;
  125. aplptr ap;
  126. int is_launched = FALSE;
  127. int *perm, *permon, *permoff, *superperm;
  128. int maxsteps = 0;
  129. double minrate = 0.0;
  130. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  131. fprintf(stdout,"%s\n",cdp_version);
  132. fflush(stdout);
  133. return 0;
  134. }
  135. /* CHECK FOR SOUNDLOOM */
  136. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  137. sloom = 0;
  138. sloombatch = 1;
  139. }
  140. if(sflinit("cdp")){
  141. sfperror("cdp: initialisation\n");
  142. return(FAILED);
  143. }
  144. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  145. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  146. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  147. return(FAILED);
  148. }
  149. if(!sloom) {
  150. if(argc == 1) {
  151. usage1();
  152. return(FAILED);
  153. } else if(argc == 2) {
  154. usage2(argv[1]);
  155. return(FAILED);
  156. }
  157. }
  158. if(!sloom) {
  159. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  160. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  161. return(FAILED);
  162. }
  163. cmdline = argv;
  164. cmdlinecnt = argc;
  165. if((get_the_process_no(argv[0],dz))<0)
  166. return(FAILED);
  167. cmdline++;
  168. cmdlinecnt--;
  169. dz->maxmode = 5;
  170. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  171. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  172. return(exit_status);
  173. }
  174. cmdline++;
  175. cmdlinecnt--;
  176. // setup_particular_application =
  177. if(dz->mode == 2 && cmdlinecnt < 8) {
  178. usage2("synthesis");
  179. return(FAILED);
  180. } else if(dz->mode == 3 && cmdlinecnt < 9) {
  181. usage2("synthesis");
  182. return(FAILED);
  183. }
  184. if((exit_status = setup_synthesizer_application(dz))<0) {
  185. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  186. return(FAILED);
  187. }
  188. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  189. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  190. return(FAILED);
  191. }
  192. } else {
  193. //parse_TK_data() =
  194. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  195. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  196. return(exit_status);
  197. }
  198. }
  199. ap = dz->application;
  200. dz->infile->channels = 1;
  201. // parse_infile_and_hone_type() =
  202. // setup_param_ranges_and_defaults() =
  203. if((exit_status = setup_synthesis_param_ranges_and_defaults(dz))<0) {
  204. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  205. return(FAILED);
  206. }
  207. // open_first_infile() : redundant
  208. // handle_extra_infiles() : redundant
  209. // handle_outfile() =
  210. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  211. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  212. return(FAILED);
  213. }
  214. // handle_formants() redundant
  215. // handle_formant_quiksearch() redundant
  216. if(dz->mode != 3 && dz->mode != 4) {
  217. strcpy(sfnam,cmdline[0]);
  218. cmdlinecnt--;
  219. cmdline++;
  220. }
  221. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  222. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  223. return(FAILED);
  224. }
  225. // check_param_validity_and_consistency()
  226. if(dz->mode == 3) {
  227. if((exit_status = check_synth_param_validity_and_consistency(dz)) < 0) {
  228. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  229. return(FAILED);
  230. }
  231. }
  232. if(dz->mode == 4) {
  233. if((dz->parray = (double **)malloc(sizeof(double *)))==NULL) {
  234. sprintf(errstr,"INSUFFICIENT MEMORY to create sinetable array.\n");
  235. return(MEMORY_ERROR);
  236. }
  237. } else if(dz->mode != 3) {
  238. if((exit_status = handle_the_special_data(sfnam,dz))<0) {
  239. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  240. return(FAILED);
  241. }
  242. }
  243. is_launched = TRUE;
  244. if((exit_status = create_synthesizer_sndbufs(dz))<0) { // CDP LIB
  245. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  246. return(FAILED);
  247. }
  248. if((exit_status = synthesis_param_preprocess(&perm,&permon,&permoff,&superperm,&minrate,&maxsteps,dz))<0) {
  249. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  250. return(FAILED);
  251. }
  252. if(dz->mode == 2 && dz->iparam[SYNTH_CHANS] > 1)
  253. dz->infile->channels = dz->iparam[SYNTH_CHANS];
  254. if((exit_status = open_the_outfile(dz))<0) {
  255. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  256. return(FAILED);
  257. }
  258. //spec_process_file =
  259. if(dz->mode == 3) {
  260. if((exit_status = fractal(dz))<0) {
  261. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  262. return(FAILED);
  263. }
  264. } else if(dz->mode == 4) {
  265. // NB sintable is in dz->parray[0]
  266. // dz->rampbrksize = sample-length of final splice
  267. if((exit_status = duffing(dz))<0) {
  268. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  269. return(FAILED);
  270. }
  271. } else {
  272. if((exit_status = synthesis(perm,permon,permoff,superperm,minrate,maxsteps,dz))<0) {
  273. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  274. return(FAILED);
  275. }
  276. }
  277. if((exit_status = complete_output(dz))<0) { // CDP LIB
  278. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  279. return(FAILED);
  280. }
  281. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  282. free(dz);
  283. return(SUCCEEDED);
  284. }
  285. /**********************************************
  286. REPLACED CDP LIB FUNCTIONS
  287. **********************************************/
  288. /****************************** SET_PARAM_DATA *********************************/
  289. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  290. {
  291. ap->special_data = (char)special_data;
  292. ap->param_cnt = (char)paramcnt;
  293. ap->max_param_cnt = (char)maxparamcnt;
  294. if(ap->max_param_cnt>0) {
  295. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  296. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  297. return(MEMORY_ERROR);
  298. }
  299. strcpy(ap->param_list,paramlist);
  300. }
  301. return(FINISHED);
  302. }
  303. /****************************** SET_VFLGS *********************************/
  304. int set_vflgs
  305. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  306. {
  307. ap->option_cnt = (char) optcnt; /*RWD added cast */
  308. if(optcnt) {
  309. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  310. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  311. return(MEMORY_ERROR);
  312. }
  313. strcpy(ap->option_list,optlist);
  314. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  315. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  316. return(MEMORY_ERROR);
  317. }
  318. strcpy(ap->option_flags,optflags);
  319. }
  320. ap->vflag_cnt = (char) vflagcnt;
  321. ap->variant_param_cnt = (char) vparamcnt;
  322. if(vflagcnt) {
  323. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  324. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  325. return(MEMORY_ERROR);
  326. }
  327. strcpy(ap->variant_list,varlist);
  328. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  329. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  330. return(MEMORY_ERROR);
  331. }
  332. strcpy(ap->variant_flags,varflags);
  333. }
  334. return(FINISHED);
  335. }
  336. /***************************** APPLICATION_INIT **************************/
  337. int application_init(dataptr dz)
  338. {
  339. int exit_status;
  340. int storage_cnt;
  341. int tipc, brkcnt;
  342. aplptr ap = dz->application;
  343. if(ap->vflag_cnt>0)
  344. initialise_vflags(dz);
  345. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  346. ap->total_input_param_cnt = (char)tipc;
  347. if(tipc>0) {
  348. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  349. return(exit_status);
  350. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  351. return(exit_status);
  352. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  353. return(exit_status);
  354. }
  355. brkcnt = tipc;
  356. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  357. if(brkcnt>0) {
  358. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  359. return(exit_status);
  360. }
  361. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  362. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  363. return(exit_status);
  364. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  365. return(exit_status);
  366. }
  367. if((exit_status = mark_parameter_types(dz,ap))<0)
  368. return(exit_status);
  369. // establish_infile_constants() replaced by
  370. dz->infilecnt = 1;
  371. //establish_bufptrs_and_extra_buffers():
  372. return(FINISHED);
  373. }
  374. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  375. /* RWD mallo changed to calloc; helps debug verison run as release! */
  376. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  377. {
  378. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  379. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  380. return(MEMORY_ERROR);
  381. }
  382. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  383. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  384. return(MEMORY_ERROR);
  385. }
  386. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  387. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  388. return(MEMORY_ERROR);
  389. }
  390. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  391. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  392. return(MEMORY_ERROR);
  393. }
  394. return(FINISHED);
  395. }
  396. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  397. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  398. {
  399. int n;
  400. for(n=0;n<storage_cnt;n++) {
  401. dz->is_int[n] = (char)0;
  402. dz->no_brk[n] = (char)0;
  403. }
  404. return(FINISHED);
  405. }
  406. /***************************** MARK_PARAMETER_TYPES **************************/
  407. int mark_parameter_types(dataptr dz,aplptr ap)
  408. {
  409. int n, m; /* PARAMS */
  410. for(n=0;n<ap->max_param_cnt;n++) {
  411. switch(ap->param_list[n]) {
  412. case('0'): break; /* dz->is_active[n] = 0 is default */
  413. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  414. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  415. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  416. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  417. default:
  418. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  419. return(PROGRAM_ERROR);
  420. }
  421. } /* OPTIONS */
  422. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  423. switch(ap->option_list[n]) {
  424. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  425. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  426. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  427. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  428. default:
  429. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  430. return(PROGRAM_ERROR);
  431. }
  432. } /* VARIANTS */
  433. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  434. switch(ap->variant_list[n]) {
  435. case('0'): break;
  436. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  437. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  438. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  439. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  440. default:
  441. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  442. return(PROGRAM_ERROR);
  443. }
  444. } /* INTERNAL */
  445. for(n=0,
  446. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  447. switch(ap->internal_param_list[n]) {
  448. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  449. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  450. case('d'): dz->no_brk[m] = (char)1; break;
  451. default:
  452. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  453. return(PROGRAM_ERROR);
  454. }
  455. }
  456. return(FINISHED);
  457. }
  458. /************************ HANDLE_THE_OUTFILE *********************/
  459. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  460. {
  461. char *filename = (*cmdline)[0], *p;
  462. if(filename[0]=='-' && filename[1]=='f') {
  463. dz->floatsam_output = 1;
  464. dz->true_outfile_stype = SAMP_FLOAT;
  465. filename+= 2;
  466. }
  467. if(!sloom) {
  468. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  469. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  470. return(DATA_ERROR);
  471. }
  472. }
  473. p = filename; // Drop file extension
  474. while(*p != ENDOFSTR) {
  475. if(*p == '.') {
  476. *p = ENDOFSTR;
  477. break;
  478. }
  479. p++;
  480. }
  481. strcpy(dz->outfilename,filename);
  482. (*cmdline)++;
  483. (*cmdlinecnt)--;
  484. return(FINISHED);
  485. }
  486. /************************ OPEN_THE_OUTFILE *********************/
  487. int open_the_outfile(dataptr dz)
  488. {
  489. int exit_status;
  490. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  491. return(exit_status);
  492. return(FINISHED);
  493. }
  494. /***************************** ESTABLISH_APPLICATION **************************/
  495. int establish_application(dataptr dz)
  496. {
  497. aplptr ap;
  498. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  499. sprintf(errstr,"establish_application()\n");
  500. return(MEMORY_ERROR);
  501. }
  502. ap = dz->application;
  503. memset((char *)ap,0,sizeof(struct applic));
  504. return(FINISHED);
  505. }
  506. /************************* INITIALISE_VFLAGS *************************/
  507. int initialise_vflags(dataptr dz)
  508. {
  509. int n;
  510. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  511. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  512. return(MEMORY_ERROR);
  513. }
  514. for(n=0;n<dz->application->vflag_cnt;n++)
  515. dz->vflag[n] = FALSE;
  516. return FINISHED;
  517. }
  518. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  519. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  520. {
  521. int n;
  522. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  523. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  524. return(MEMORY_ERROR);
  525. }
  526. for(n=0;n<tipc;n++)
  527. ap->default_val[n] = 0.0;
  528. return(FINISHED);
  529. }
  530. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  531. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  532. {
  533. int n;
  534. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  535. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  536. return(MEMORY_ERROR);
  537. }
  538. for(n=0;n<tipc;n++)
  539. dz->is_active[n] = (char)0;
  540. return(FINISHED);
  541. }
  542. /************************* SETUP_SYNTHESIZER_APPLICATION *******************/
  543. int setup_synthesizer_application(dataptr dz)
  544. {
  545. int exit_status;
  546. aplptr ap;
  547. if((exit_status = establish_application(dz))<0) // GLOBAL
  548. return(FAILED);
  549. ap = dz->application;
  550. // SEE parstruct FOR EXPLANATION of next 2 functions
  551. switch(dz->mode) {
  552. case(0):
  553. if((exit_status = set_param_data(ap,SYN_PARTIALS,3,3,"idD"))<0)
  554. return(FAILED);
  555. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  556. return(exit_status);
  557. break;
  558. case(1):
  559. if((exit_status = set_param_data(ap,SYN_PARTIALS,3,3,"idD"))<0)
  560. return(FAILED);
  561. if((exit_status = set_vflgs(ap,"nc",2,"DD","f",1,0,"0"))<0)
  562. return(exit_status);
  563. break;
  564. case(2):
  565. if((exit_status = set_param_data(ap,SYN_PARTIALS,6,6,"idDiiD"))<0)
  566. return(FAILED);
  567. if((exit_status = set_vflgs(ap,"udfsneEcCtr",11,"ddddiididid","azmxj",5,0,"00000"))<0)
  568. return(exit_status);
  569. break;
  570. case(3):
  571. if((exit_status = set_param_data(ap,0,9,9,"idDididDD"))<0)
  572. return(FAILED);
  573. if((exit_status = set_vflgs(ap,"rf",2,"Di","e",1,0,"0"))<0)
  574. return(exit_status);
  575. break;
  576. case(4):
  577. if((exit_status = set_param_data(ap,0,6,6,"idDDdd"))<0)
  578. return(FAILED);
  579. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  580. return(exit_status);
  581. break;
  582. }
  583. // set_legal_infile_structure -->
  584. dz->has_otherfile = FALSE;
  585. // assign_process_logic -->
  586. dz->input_data_type = NO_FILE_AT_ALL;
  587. dz->process_type = UNEQUAL_SNDFILE;
  588. dz->outfiletype = SNDFILE_OUT;
  589. return application_init(dz); //GLOBAL
  590. }
  591. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  592. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  593. {
  594. int exit_status;
  595. infileptr infile_info;
  596. if(!sloom) {
  597. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  598. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  599. return(MEMORY_ERROR);
  600. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  601. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  602. return(PROGRAM_ERROR);
  603. } else if(infile_info->filetype != SNDFILE) {
  604. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  605. return(DATA_ERROR);
  606. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  607. sprintf(errstr,"Failed to copy file parsing information\n");
  608. return(PROGRAM_ERROR);
  609. }
  610. free(infile_info);
  611. }
  612. return(FINISHED);
  613. }
  614. /************************* SETUP_SYNTHESIS_PARAM_RANGES_AND_DEFAULTS *******************/
  615. int setup_synthesis_param_ranges_and_defaults(dataptr dz)
  616. {
  617. int exit_status;
  618. aplptr ap = dz->application;
  619. // set_param_ranges()
  620. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  621. // NB total_input_param_cnt is > 0 !!!
  622. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  623. return(FAILED);
  624. // get_param_ranges()
  625. ap->lo[SYNTHSRAT] = 16000;
  626. ap->hi[SYNTHSRAT] = 96000;
  627. ap->default_val[SYNTHSRAT] = 44100.0;
  628. ap->lo[SYNTH_DUR] = 0.0;
  629. ap->hi[SYNTH_DUR] = 32767.0;
  630. ap->default_val[SYNTH_DUR] = 1.0;
  631. ap->lo[SYNTH_FRQ] = .001;
  632. ap->hi[SYNTH_FRQ] = 10000;
  633. ap->default_val[SYNTH_FRQ] = 440;
  634. if(dz->mode == 1) {
  635. ap->lo[SYNTH_SQZ] = 0.0;
  636. ap->hi[SYNTH_SQZ] = 1000.0;
  637. ap->default_val[SYNTH_SQZ] = 1.0;
  638. ap->lo[SYNTH_CTR] = -1.0;
  639. ap->hi[SYNTH_CTR] = 1.0;
  640. ap->default_val[SYNTH_CTR] = 0.0;
  641. } else if(dz->mode == 2) {
  642. ap->lo[SYNTH_CHANS] = 1;
  643. ap->hi[SYNTH_CHANS] = 16.0;
  644. ap->default_val[SYNTH_CHANS] = 1.0;
  645. ap->lo[SYNTH_MAX] = 1.0;
  646. ap->hi[SYNTH_MAX] = 8.0;
  647. ap->default_val[SYNTH_MAX] = 3.0;
  648. ap->lo[SYNTH_RATE] = 0.004;
  649. ap->hi[SYNTH_RATE] = 100;
  650. ap->default_val[SYNTH_RATE] = 0.1;
  651. ap->lo[SYNTH_RISE] = 0.0;
  652. ap->hi[SYNTH_RISE] = 100;
  653. ap->default_val[SYNTH_RISE] = 0;
  654. ap->lo[SYNTH_FALL] = 0.0;
  655. ap->hi[SYNTH_FALL] = 100;
  656. ap->default_val[SYNTH_FALL] = 0;
  657. ap->lo[SYNTH_STDY] = 0.0;
  658. ap->hi[SYNTH_STDY] = 3600;
  659. ap->default_val[SYNTH_STDY] = 0;
  660. ap->lo[SYNTH_SPLEN] = 2;
  661. ap->hi[SYNTH_SPLEN] = 50;
  662. ap->default_val[SYNTH_SPLEN] = 5;
  663. ap->lo[SYNTH_NUM] = 0;
  664. ap->hi[SYNTH_NUM] = 1000;
  665. ap->default_val[SYNTH_NUM] = 0;
  666. ap->lo[SYNTH_EFROM] = 0;
  667. ap->hi[SYNTH_EFROM] = 16.0;
  668. ap->default_val[SYNTH_EFROM] = 0;
  669. ap->lo[SYNTH_ETIME] = 0;
  670. ap->hi[SYNTH_ETIME] = 32767.0;
  671. ap->default_val[SYNTH_ETIME] = 0;
  672. ap->lo[SYNTH_CTO] = 0;
  673. ap->hi[SYNTH_CTO] = 16.0;
  674. ap->default_val[SYNTH_CTO] = 0;
  675. ap->lo[SYNTH_CTIME] = 0;
  676. ap->hi[SYNTH_CTIME] = 32767.0;
  677. ap->default_val[SYNTH_CTIME] = 0;
  678. ap->lo[SYNTH_STYPE] = 0;
  679. ap->hi[SYNTH_STYPE] = 14;
  680. ap->default_val[SYNTH_STYPE] = 0;
  681. ap->lo[SYNTH_RSPEED] = -20;
  682. ap->hi[SYNTH_RSPEED] = 20;
  683. ap->default_val[SYNTH_RSPEED] = 0;
  684. } else if(dz->mode == 3) {
  685. ap->lo[SYNTH_ATK] = 0;
  686. ap->hi[SYNTH_ATK] = 16;
  687. ap->default_val[SYNTH_ATK] = 2;
  688. ap->lo[SYNTH_EATK] = 0.25;
  689. ap->hi[SYNTH_EATK] = 4;
  690. ap->default_val[SYNTH_EATK] = 2;
  691. ap->lo[SYNTH_DEC] = 0;
  692. ap->hi[SYNTH_DEC] = 64;
  693. ap->default_val[SYNTH_DEC] = 2;
  694. ap->lo[SYNTH_EDEC] = 0.25;
  695. ap->hi[SYNTH_EDEC] = 4;
  696. ap->default_val[SYNTH_EDEC] = 2;
  697. ap->lo[SYNTH_ATOH] = .1;
  698. ap->hi[SYNTH_ATOH] = 1;
  699. ap->default_val[SYNTH_ATOH] = .5;
  700. ap->lo[SYNTH_GTOW] = .1;
  701. ap->hi[SYNTH_GTOW] = 1;
  702. ap->default_val[SYNTH_GTOW] = 1;
  703. ap->lo[SYNTH_RAND] = 0;
  704. ap->hi[SYNTH_RAND] = 1;
  705. ap->default_val[SYNTH_RAND] = 0;
  706. ap->lo[SYNTH_FLEVEL] = 0;
  707. ap->hi[SYNTH_FLEVEL] = 256;
  708. ap->default_val[SYNTH_FLEVEL] = 0;
  709. } else if(dz->mode == 4) {
  710. ap->lo[SYNTH_FRQ] = .1;
  711. ap->hi[SYNTH_FRQ] = 200;
  712. ap->default_val[SYNTH_FRQ] = 70;
  713. ap->lo[SYNTH_DAMP] = .15;
  714. ap->hi[SYNTH_DAMP] = 2;
  715. ap->default_val[SYNTH_DAMP] = .5;
  716. ap->lo[SYNTH_K] = -10;
  717. ap->hi[SYNTH_K] = 10;
  718. ap->default_val[SYNTH_K] = 1;
  719. ap->lo[SYNTH_B] = 20;
  720. ap->hi[SYNTH_B] = 50;
  721. ap->default_val[SYNTH_B] = 30;
  722. }
  723. dz->maxmode = 5;
  724. if(!sloom)
  725. put_default_vals_in_all_params(dz);
  726. return(FINISHED);
  727. }
  728. /********************************* PARSE_SLOOM_DATA *********************************/
  729. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  730. {
  731. int exit_status;
  732. int cnt = 1, infilecnt;
  733. int filesize, insams, inbrksize;
  734. double dummy;
  735. int true_cnt = 0;
  736. aplptr ap;
  737. while(cnt<=PRE_CMDLINE_DATACNT) {
  738. if(cnt > argc) {
  739. sprintf(errstr,"Insufficient data sent from TK\n");
  740. return(DATA_ERROR);
  741. }
  742. switch(cnt) {
  743. case(1):
  744. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  745. sprintf(errstr,"Cannot read process no. sent from TK\n");
  746. return(DATA_ERROR);
  747. }
  748. break;
  749. case(2):
  750. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  751. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  752. return(DATA_ERROR);
  753. }
  754. if(dz->mode > 0)
  755. dz->mode--;
  756. //setup_particular_application() =
  757. if((exit_status = setup_synthesizer_application(dz))<0)
  758. return(exit_status);
  759. ap = dz->application;
  760. break;
  761. case(3):
  762. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  763. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  764. return(DATA_ERROR);
  765. }
  766. if(infilecnt < 1) {
  767. true_cnt = cnt + 1;
  768. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  769. }
  770. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  771. return(exit_status);
  772. break;
  773. case(INPUT_FILETYPE+4):
  774. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  775. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  776. return(DATA_ERROR);
  777. }
  778. break;
  779. case(INPUT_FILESIZE+4):
  780. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  781. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  782. return(DATA_ERROR);
  783. }
  784. dz->insams[0] = filesize;
  785. break;
  786. case(INPUT_INSAMS+4):
  787. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  788. sprintf(errstr,"Cannot read insams sent from TK\n");
  789. return(DATA_ERROR);
  790. }
  791. dz->insams[0] = insams;
  792. break;
  793. case(INPUT_SRATE+4):
  794. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  795. sprintf(errstr,"Cannot read srate sent from TK\n");
  796. return(DATA_ERROR);
  797. }
  798. break;
  799. case(INPUT_CHANNELS+4):
  800. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  801. sprintf(errstr,"Cannot read channels sent from TK\n");
  802. return(DATA_ERROR);
  803. }
  804. break;
  805. case(INPUT_STYPE+4):
  806. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  807. sprintf(errstr,"Cannot read stype sent from TK\n");
  808. return(DATA_ERROR);
  809. }
  810. break;
  811. case(INPUT_ORIGSTYPE+4):
  812. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  813. sprintf(errstr,"Cannot read origstype sent from TK\n");
  814. return(DATA_ERROR);
  815. }
  816. break;
  817. case(INPUT_ORIGRATE+4):
  818. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  819. sprintf(errstr,"Cannot read origrate sent from TK\n");
  820. return(DATA_ERROR);
  821. }
  822. break;
  823. case(INPUT_MLEN+4):
  824. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  825. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  826. return(DATA_ERROR);
  827. }
  828. break;
  829. case(INPUT_DFAC+4):
  830. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  831. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  832. return(DATA_ERROR);
  833. }
  834. break;
  835. case(INPUT_ORIGCHANS+4):
  836. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  837. sprintf(errstr,"Cannot read origchans sent from TK\n");
  838. return(DATA_ERROR);
  839. }
  840. break;
  841. case(INPUT_SPECENVCNT+4):
  842. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  843. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  844. return(DATA_ERROR);
  845. }
  846. dz->specenvcnt = dz->infile->specenvcnt;
  847. break;
  848. case(INPUT_WANTED+4):
  849. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  850. sprintf(errstr,"Cannot read wanted sent from TK\n");
  851. return(DATA_ERROR);
  852. }
  853. break;
  854. case(INPUT_WLENGTH+4):
  855. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  856. sprintf(errstr,"Cannot read wlength sent from TK\n");
  857. return(DATA_ERROR);
  858. }
  859. break;
  860. case(INPUT_OUT_CHANS+4):
  861. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  862. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  863. return(DATA_ERROR);
  864. }
  865. break;
  866. /* RWD these chanegs to samps - tk will have to deal with that! */
  867. case(INPUT_DESCRIPTOR_BYTES+4):
  868. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  869. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  870. return(DATA_ERROR);
  871. }
  872. break;
  873. case(INPUT_IS_TRANSPOS+4):
  874. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  875. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  876. return(DATA_ERROR);
  877. }
  878. break;
  879. case(INPUT_COULD_BE_TRANSPOS+4):
  880. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  881. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  882. return(DATA_ERROR);
  883. }
  884. break;
  885. case(INPUT_COULD_BE_PITCH+4):
  886. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  887. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  888. return(DATA_ERROR);
  889. }
  890. break;
  891. case(INPUT_DIFFERENT_SRATES+4):
  892. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  893. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  894. return(DATA_ERROR);
  895. }
  896. break;
  897. case(INPUT_DUPLICATE_SNDS+4):
  898. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  899. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  900. return(DATA_ERROR);
  901. }
  902. break;
  903. case(INPUT_BRKSIZE+4):
  904. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  905. sprintf(errstr,"Cannot read brksize sent from TK\n");
  906. return(DATA_ERROR);
  907. }
  908. if(inbrksize > 0) {
  909. switch(dz->input_data_type) {
  910. case(WORDLIST_ONLY):
  911. break;
  912. case(PITCH_AND_PITCH):
  913. case(PITCH_AND_TRANSPOS):
  914. case(TRANSPOS_AND_TRANSPOS):
  915. dz->tempsize = inbrksize;
  916. break;
  917. case(BRKFILES_ONLY):
  918. case(UNRANGED_BRKFILE_ONLY):
  919. case(DB_BRKFILES_ONLY):
  920. case(ALL_FILES):
  921. case(ANY_NUMBER_OF_ANY_FILES):
  922. if(dz->extrabrkno < 0) {
  923. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  924. return(DATA_ERROR);
  925. }
  926. if(dz->brksize == NULL) {
  927. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  928. return(PROGRAM_ERROR);
  929. }
  930. dz->brksize[dz->extrabrkno] = inbrksize;
  931. break;
  932. default:
  933. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  934. dz->input_data_type);
  935. return(PROGRAM_ERROR);
  936. }
  937. break;
  938. }
  939. break;
  940. case(INPUT_NUMSIZE+4):
  941. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  942. sprintf(errstr,"Cannot read numsize sent from TK\n");
  943. return(DATA_ERROR);
  944. }
  945. break;
  946. case(INPUT_LINECNT+4):
  947. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  948. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  949. return(DATA_ERROR);
  950. }
  951. break;
  952. case(INPUT_ALL_WORDS+4):
  953. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  954. sprintf(errstr,"Cannot read all_words sent from TK\n");
  955. return(DATA_ERROR);
  956. }
  957. break;
  958. case(INPUT_ARATE+4):
  959. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  960. sprintf(errstr,"Cannot read arate sent from TK\n");
  961. return(DATA_ERROR);
  962. }
  963. break;
  964. case(INPUT_FRAMETIME+4):
  965. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  966. sprintf(errstr,"Cannot read frametime sent from TK\n");
  967. return(DATA_ERROR);
  968. }
  969. dz->frametime = (float)dummy;
  970. break;
  971. case(INPUT_WINDOW_SIZE+4):
  972. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  973. sprintf(errstr,"Cannot read window_size sent from TK\n");
  974. return(DATA_ERROR);
  975. }
  976. break;
  977. case(INPUT_NYQUIST+4):
  978. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  979. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  980. return(DATA_ERROR);
  981. }
  982. break;
  983. case(INPUT_DURATION+4):
  984. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  985. sprintf(errstr,"Cannot read duration sent from TK\n");
  986. return(DATA_ERROR);
  987. }
  988. break;
  989. case(INPUT_MINBRK+4):
  990. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  991. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  992. return(DATA_ERROR);
  993. }
  994. break;
  995. case(INPUT_MAXBRK+4):
  996. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  997. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  998. return(DATA_ERROR);
  999. }
  1000. break;
  1001. case(INPUT_MINNUM+4):
  1002. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  1003. sprintf(errstr,"Cannot read minnum sent from TK\n");
  1004. return(DATA_ERROR);
  1005. }
  1006. break;
  1007. case(INPUT_MAXNUM+4):
  1008. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  1009. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  1010. return(DATA_ERROR);
  1011. }
  1012. break;
  1013. default:
  1014. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  1015. return(PROGRAM_ERROR);
  1016. }
  1017. cnt++;
  1018. }
  1019. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  1020. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  1021. return(DATA_ERROR);
  1022. }
  1023. if(true_cnt)
  1024. cnt = true_cnt;
  1025. *cmdlinecnt = 0;
  1026. while(cnt < argc) {
  1027. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  1028. return(exit_status);
  1029. cnt++;
  1030. }
  1031. return(FINISHED);
  1032. }
  1033. /********************************* GET_TK_CMDLINE_WORD *********************************/
  1034. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  1035. {
  1036. if(*cmdlinecnt==0) {
  1037. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  1038. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1039. return(MEMORY_ERROR);
  1040. }
  1041. } else {
  1042. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  1043. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  1044. return(MEMORY_ERROR);
  1045. }
  1046. }
  1047. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1048. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  1049. return(MEMORY_ERROR);
  1050. }
  1051. strcpy((*cmdline)[*cmdlinecnt],q);
  1052. (*cmdlinecnt)++;
  1053. return(FINISHED);
  1054. }
  1055. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  1056. int assign_file_data_storage(int infilecnt,dataptr dz)
  1057. {
  1058. int exit_status;
  1059. int no_sndfile_system_files = FALSE;
  1060. dz->infilecnt = infilecnt;
  1061. if((exit_status = allocate_filespace(dz))<0)
  1062. return(exit_status);
  1063. if(no_sndfile_system_files)
  1064. dz->infilecnt = 0;
  1065. return(FINISHED);
  1066. }
  1067. /************************* redundant functions: to ensure libs compile OK *******************/
  1068. int assign_process_logic(dataptr dz)
  1069. {
  1070. return(FINISHED);
  1071. }
  1072. void set_legal_infile_structure(dataptr dz)
  1073. {}
  1074. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1075. {
  1076. return(FINISHED);
  1077. }
  1078. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1079. {
  1080. return(FINISHED);
  1081. }
  1082. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1083. {
  1084. return(FINISHED);
  1085. }
  1086. int read_special_data(char *str,dataptr dz)
  1087. {
  1088. return(FINISHED);
  1089. }
  1090. int inner_loop
  1091. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1092. {
  1093. return(FINISHED);
  1094. }
  1095. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1096. {
  1097. return(FINISHED);
  1098. }
  1099. /******************************** USAGE1 ********************************/
  1100. int usage1(void)
  1101. {
  1102. usage2("synthesis");
  1103. return(USAGE_ONLY);
  1104. }
  1105. /********************************************************************************************/
  1106. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1107. {
  1108. if(!strcmp(prog_identifier_from_cmdline,"synthesis")) dz->process = SYNTHESIZER;
  1109. else {
  1110. fprintf(stderr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1111. return(USAGE_ONLY);
  1112. }
  1113. return(FINISHED);
  1114. }
  1115. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1116. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1117. {
  1118. int n;
  1119. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1120. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1121. return(MEMORY_ERROR);
  1122. }
  1123. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1124. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1125. return(MEMORY_ERROR);
  1126. }
  1127. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1128. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1129. return(MEMORY_ERROR);
  1130. }
  1131. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1132. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1133. return(MEMORY_ERROR);
  1134. }
  1135. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1136. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1137. return(MEMORY_ERROR);
  1138. }
  1139. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1140. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1141. return(MEMORY_ERROR);
  1142. }
  1143. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1144. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1145. return(MEMORY_ERROR);
  1146. }
  1147. for(n=0;n<brkcnt;n++) {
  1148. dz->brk[n] = NULL;
  1149. dz->brkptr[n] = NULL;
  1150. dz->brkinit[n] = 0;
  1151. dz->brksize[n] = 0;
  1152. }
  1153. return(FINISHED);
  1154. }
  1155. /******************************** USAGE2 ********************************/
  1156. int usage2(char *str)
  1157. {
  1158. int k;
  1159. if(!strcmp(str,"synthesis")) {
  1160. fprintf(stderr,
  1161. "USAGE:\n"
  1162. "newsynth synthesis 1 outf spectrum srate dur frq\n"
  1163. "newsynth synthesis 2 outf spectrum srate dur frq [-nnarrowing] [-ccentring]\n"
  1164. "newsynth synthesis 3 outf spectrum srate dur frq chans maxrange rate\n"
  1165. " [-urise] [-dfall] [-fsteady] [-ssplice] [-nN] [-a] [-z] [-x]\n"
  1166. " [-tspacetype] [-rrotspeed]\n"
  1167. " [[-m] [-j] [efrom -Etime] [cto -Ctime]]\n"
  1168. "newsynth synthesis 4 outf srate dur frq atk ea dec ed atoh gtow [-fflv] [-rrnd|-e]\n"
  1169. "newsynth synthesis 5 outf srate dur frq damping k b\n"
  1170. "\n"
  1171. "Synthesize complex spectra.\n"
  1172. "\n"
  1173. "MODE 1 Generates tones with any number of (possibly varying) partials.\n"
  1174. "MODE 2 Generates wave-packet streams with any number of (possibly varying) partials.\n"
  1175. "MODE 3 Multichan Mode1 where partials (spread over N octaves) fade in-out randomly.\n"
  1176. "MODE 4 Fractally arrayed spikes.\n"
  1177. "MODE 5 Duffing damped oscillator (frq, amplitude and damping can vary through time).\n"
  1178. "\n"
  1179. "Hit key '1' '2 '3' '4' or '5 to see more on individual modes, or 'e' to exit.\n"
  1180. "\n");
  1181. while((k = getch())!='1' && k != '2' && k != '3' && k != '4' && k != '5' && k != 'e')
  1182. ;
  1183. if(k == '1') {
  1184. fprintf(stderr,
  1185. "newsynth synthesis 1 outf spectrum srate dur frq\n"
  1186. "\n"
  1187. "SPECTRUM Listing of partial ratios and relative levels, against time.\n"
  1188. " Data: text file of data lines. Every line has same number of entries.\n"
  1189. " 1ST ENTRY on each line is time. Times must start at zero and increase.\n"
  1190. " ALL EVEN NUMBERED ENTRIES are partial numbers.\n"
  1191. " For tone-generation, the first partial number on each line must be 1.\n"
  1192. " Partial numbers must increase from entry to entry.\n"
  1193. " ALL OTHER ODD NUMBERED ENTRIES are partial levels, and may have any value.\n"
  1194. " -ve values invert the phase of the partial.\n"
  1195. "SRATE Sample rate of synthesized sound.\n"
  1196. "DUR Duration of synthesized sound.\n"
  1197. "FRQ Possibly time-varying Fundamental frq of output (0.001 to 10000Hz) OR\n");
  1198. } else if(k == '2') {
  1199. fprintf(stderr,
  1200. "newsynth synthesis 2 outf spectrum srate dur frq [-nnarrowing] [-ccentring]\n"
  1201. "\n"
  1202. "SPECTRUM Listing of partial ratios and relative levels, against time.\n"
  1203. " Data: text file of data lines. Every line has same number of entries.\n"
  1204. " 1ST ENTRY on each line is time. Times must start at zero and increase.\n"
  1205. " ALL EVEN NUMBERED ENTRIES are partial numbers.\n"
  1206. " For tone-generation, the first partial number on each line must be 1.\n"
  1207. " Partial numbers must increase from entry to entry.\n"
  1208. " ALL OTHER ODD NUMBERED ENTRIES are partial levels, and may have any value.\n"
  1209. " -ve values invert the phase of the partial.\n"
  1210. "SRATE Sample rate of synthesized sound.\n"
  1211. "DUR Duration of synthesized sound.\n"
  1212. "FRQ Possibly time-varying Fundamental frq of output (0.001 to 10000Hz) OR\n"
  1213. "NARROWING Narrowing of packet envelope (0 - 1000).\n"
  1214. " Values below 1.0 broaden the packet.\n"
  1215. " Values very close to zero may produce clicks (square-wave envelope).\n"
  1216. " Very high vals with very high frqs may produce click-impulses or silence.\n"
  1217. "CENTRING Centring of peak of packet envelope.\n"
  1218. " 0 peak at centre: -1 peak at start: 1 peak at end.\n");
  1219. } else if(k == '3') {
  1220. fprintf(stderr,
  1221. "newsynth synthesis 3 outf spectrum srate dur frq chans maxrange step\n"
  1222. " [-urise] [-dfall] [-fsteady] [-ssplice] [-nN] [-a] [-z] [-x]\n"
  1223. " [-tspacetype] [-rrotspeed] [[-m] [-j] [efrom -Etime] [cto -Ctime]]\n"
  1224. "\n"
  1225. "SPECTRUM Listing of partial ratios and relative levels, against time.\n"
  1226. " Data: text file of data lines. Every line has same number of entries.\n"
  1227. " 1ST ENTRY on each line is time. Times must start at zero and increase.\n"
  1228. " ALL EVEN NUMBERED ENTRIES are partial numbers.\n"
  1229. " For tone-generation, the first partial number on each line must be 1.\n"
  1230. " Partial numbers must increase from entry to entry.\n"
  1231. " ALL OTHER ODD NUMBERED ENTRIES are partial levels, and may have any value.\n"
  1232. " -ve values invert the phase of the partial.\n"
  1233. "SRATE Sample rate of synthesized sound.\n"
  1234. "DUR Duration of synthesized sound.\n"
  1235. "FRQ Possibly time-varying Fundamental frq of output (0.001 to 10000Hz) OR\n"
  1236. "CHANS Number of output channels.\n"
  1237. "MAXRANGE Max range of transposition of spectral components (in whole 8vas).\n"
  1238. "STEP Average time between changes to partial-content of output.\n"
  1239. "RISE Time to expand to maximum range.\n"
  1240. "FALL Time to return to initial range, before end.\n"
  1241. "STEADY Duration of steady state at sound end.\n"
  1242. "SPLICE Splices for partial entry and exit, in mS.\n"
  1243. "-nN (Number) Same fixed number (N) of partials chosen for each event.\n"
  1244. "-a Initial rise in number of partials from only-the-fundamental.\n"
  1245. "-z Fall in number of partials , during \"steady state\" to fundamental.\n"
  1246. "-x (Xclusive) change all partials (as far as poss) from event to event.\n"
  1247. "-m (Move) Distribute partials in space.\n"
  1248. "-j (Jump) All partials assigned to same location for any one event.\n"
  1249. "SPACETYPE Type of output spatialisation.\n"
  1250. "ROTSPEED rotation speed (for certain spatialisation types).\n"
  1251. "-e -E (Emerge) sound emerges from channel \"from\" over time \"time\" at start.\n"
  1252. "-c -C (Converge) Sound converges to channel \"to\" over time \"time\" at end.\n"
  1253. "NB: Flags -j,-e,-E,-c,-C only operational if -m set.\n"
  1254. "NB: Flags with NO params must be placed AFTER any flags WITH params, on the cmdline.\n"
  1255. "\n"
  1256. "Hit key 's' to continue to \"SPACETYPE\" info , or 'e' to exit.\n"
  1257. "\n");
  1258. while((k = getch())!='s' && k != 'e')
  1259. ;
  1260. if(k == 's') {
  1261. fprintf(stderr,
  1262. "\n"
  1263. "SPACETYPE options : For 8-channel output only.\n"
  1264. "\n"
  1265. "1 Positions alternate between Left and Right sides, but are otherwise random.\n"
  1266. "2 Positions alternate between Front and Back, but are otherwise random.\n"
  1267. "3 Rotating clockwise or anticlockwise.\n"
  1268. "4 Random permutations of all 8 channels.\n"
  1269. "5 ... plus all possible pairs of channels.\n"
  1270. "6 ... plus all possible meaningful small and large triangles.\n"
  1271. "7 ... plus square, diamond and all-at-once.\n"
  1272. " In types 4 to 7, all members of perm used before next perm starts.\n"
  1273. "8 Alternate between all-left and all-right.\n"
  1274. "9 Alternate between all-front and all-back.\n"
  1275. "10 Alternate between all-square and all-diamond.\n"
  1276. "11 Rotate triangle formed by lspkrs 2-apart clockwise.\n"
  1277. "12 Rotate triangle formed by lspkrs 3-apart clockwise.\n"
  1278. "13 Rotate triangle formed by lspkrs 2-apart anticlockwise.\n"
  1279. "14 Rotate triangle formed by lspkrs 3-apart anticlockwise.\n");
  1280. }
  1281. } else if(k == '4') {
  1282. fprintf(stderr,
  1283. "\n"
  1284. "MODE 4 parameters: .\n"
  1285. "\n"
  1286. "newsynth synthesis 4 outf srate dur frq atk ea dec ed atoh gtow [-fflv] [-rrnd|-e]\n"
  1287. "\n"
  1288. "SRATE Sample rate of synthesized sound.\n"
  1289. "DUR Duration of synthesized sound.\n"
  1290. "FRQ Possibly time-varying Fundamental frq of output (0.001 to 10000Hz) OR\n"
  1291. "\n"
  1292. "Waveform consists of spikes distributed fractally over wavelen.\n"
  1293. "\n"
  1294. "ATK Length of spike attack in samples.\n"
  1295. "EA Rise curve of attack: > 1 rise slow-then-fast : >1 fast-then-slow.\n"
  1296. "DEC Length of spike decay in samples.\n"
  1297. "ED Fall curve of decay: > 1 fall fast-then-slow : >1 slow-then-fast.\n"
  1298. "\n"
  1299. "Spike placement frame\n"
  1300. " _________wavelen__________\n"
  1301. "| |\n"
  1302. " ___grouplen____\n"
  1303. "| |\n"
  1304. " 1/2 grouplen\n"
  1305. " _______\n"
  1306. "| |\n"
  1307. " _a_ _a_ |\n"
  1308. "| | | | |\n"
  1309. "| |_b_| |_b_|__________\n"
  1310. " trailing\n"
  1311. " | silence |\n"
  1312. "ATOH Ratio of on-time (a) to 1/2-grouplen (see diagram) in grouplen.\n"
  1313. " (which determines relative length of \"a\" (ON) and \"b\" (OFF).\n"
  1314. "GTOW Ratio of grouplen to total-wavelength.\n"
  1315. " (which determines length of trailing silence (see diagram).\n"
  1316. "Blocks \"a\" then subdivided in same proportions again, etc. iteratively.\n"
  1317. "Spikes then placed at start of each \"a\" block in each subdivision.\n"
  1318. "FLV Alternate \"a\" blocks in waveforn assigned +ve and -ve values.\n"
  1319. " \"FLV\" determines at which fractal level this +- switch takes place.\n"
  1320. " Level 0 uses the large blocks in the uppermost (slowest) level.\n"
  1321. " NB Maximum level of \"flv\" will depend on various other parameters.\n"
  1322. " If \"flv\" is set too high it will be reset to the max fractal level\n"
  1323. " achievable with the current parameters.\n"
  1324. "RND Subdivision places 2nd \"a\" seg randomly between true pos & grouplen-end.\n"
  1325. "-e Subdivision places 2nd \"a\" at END of grouplen.\n"
  1326. " (-e and RAND cannot be used together).\n"
  1327. "\n"
  1328. "FRQ,ATOH,GTOW and RND can vary in time.\n");
  1329. } else if(k == '5') {
  1330. fprintf(stderr,
  1331. "newsynth synthesis 5 outf srate dur frq damping k b\n"
  1332. "\n"
  1333. "SRATE Sample rate of synthesized sound.\n"
  1334. "DUR Duration of synthesized sound.\n"
  1335. "FRQ Possibly time-varying Fundamental frq of forcing oscillation (1-200Hz).\n"
  1336. "DAMPING Possibly time-varying damping of forced oscillation (0.15 to 2).\n"
  1337. "K, B Coefficients determe nature of damping. (k -10 to 10 : b 20 to 50)\n"
  1338. "\n");
  1339. }
  1340. } else
  1341. fprintf(stdout,"Unknown option '%s'\n",str);
  1342. return(USAGE_ONLY);
  1343. }
  1344. int usage3(char *str1,char *str2)
  1345. {
  1346. fprintf(stderr,"Insufficient parameters on command line.\n");
  1347. return(USAGE_ONLY);
  1348. }
  1349. /**************************** SYNTHESIS_PARAM_PREPROCESS *************************/
  1350. int synthesis_param_preprocess (int **perm,int **permon,int **permoff,int **superperm,double *minrate,int *maxsteps,dataptr dz)
  1351. {
  1352. int exit_status, sinarray, pntarray = 0, chans, configno;
  1353. int n, m;
  1354. double *sintab, *thispartials, srate, nyquist, endsplice, time, top, maxrate, val;
  1355. int partialscnt = dz->itemcnt, entrycnt = dz->ringsize;
  1356. float *spikebuf = dz->sampbuf[2];
  1357. if(BAD_SR(dz->param[SYNTHSRAT])) {
  1358. sprintf(errstr,"Invalid sample rate (%lf) entered.\n",dz->param[SYNTHSRAT]);
  1359. return(MEMORY_ERROR);
  1360. }
  1361. dz->infile->srate = dz->iparam[SYNTHSRAT];
  1362. srate = (double)dz->iparam[SYNTHSRAT];
  1363. nyquist = srate/2.0;
  1364. chans = dz->iparam[SYNTH_CHANS];
  1365. // Establish end splice length
  1366. dz->iparam[SYNTH_DUR] = (int)round(dz->param[SYNTH_DUR] * srate);
  1367. if(dz->mode == 2) {
  1368. if(dz->brksize[SYNTH_RATE]) {
  1369. if((exit_status = get_maxvalue(SYNTH_RATE,&maxrate,dz))<0)
  1370. return PROGRAM_ERROR;
  1371. if((exit_status = get_minvalue_in_brktable(minrate,SYNTH_RATE,dz))<0)
  1372. return PROGRAM_ERROR;
  1373. } else {
  1374. maxrate = dz->param[SYNTH_RATE];
  1375. *minrate = dz->param[SYNTH_RATE];
  1376. }
  1377. if(maxrate >= dz->param[SYNTH_DUR]/2.0) {
  1378. sprintf(errstr,"(max) Rate (%lf) must be less than half duration (%lf).\n",maxrate,dz->param[SYNTH_DUR]);
  1379. return(DATA_ERROR);
  1380. }
  1381. if(dz->iparam[SYNTH_STYPE] > 0) {
  1382. if(*minrate <= dz->param[SYNTH_SPLEN] * MS_TO_SECS * 2.0) {
  1383. sprintf(errstr,"(min) Rate (%lf) must be greater than 2 * splice (%lf) For special spatialisation types\n",*minrate,dz->param[SYNTH_SPLEN] * MS_TO_SECS * 2.0);
  1384. return(DATA_ERROR);
  1385. }
  1386. } else {
  1387. if(*minrate <= dz->param[SYNTH_SPLEN] * MS_TO_SECS) {
  1388. sprintf(errstr,"(min) Rate (%lf) must be greater than splicelength (%lf).\n",*minrate,dz->param[SYNTH_SPLEN] * MS_TO_SECS);
  1389. return(DATA_ERROR);
  1390. }
  1391. }
  1392. if(dz->vflag[SYN_SPACED] && dz->iparam[SYNTH_CHANS] < 2) { // Can't spatialise to mono output!!
  1393. fprintf(stdout,"WARNING: Mono output: Can't spatialise the output.\n");
  1394. fflush(stdout);;
  1395. dz->vflag[SYN_SPACED] = 0;
  1396. }
  1397. endsplice = 50.0 * MS_TO_SECS;
  1398. dz->rampbrksize = (int)floor(endsplice * srate);
  1399. } else {
  1400. endsplice = 50.0 * MS_TO_SECS; // Go for big splice
  1401. if(dz->param[SYNTH_DUR] <= endsplice * 2)
  1402. endsplice = min(dz->param[SYNTH_DUR]/4.0,5.0 * MS_TO_SECS); // Else go for small splice
  1403. dz->rampbrksize = (int)floor(endsplice * srate); // Establish size of final splice
  1404. }
  1405. if(dz->mode == 3) {
  1406. n = 0;
  1407. if(dz->iparam[SYNTH_ATK] > 0) {
  1408. for(m = 0;m < dz->iparam[SYNTH_ATK];m++) {
  1409. val = (double)(m+1)/(double)(dz->iparam[SYNTH_ATK] + 1);
  1410. val = pow(val,dz->param[SYNTH_EATK]);
  1411. spikebuf[n++] = (float)(val * SPIKEMAX);
  1412. }
  1413. }
  1414. spikebuf[n++] = (float)SPIKEMAX;
  1415. if(dz->iparam[SYNTH_DEC] > 0) {
  1416. for(m = dz->iparam[SYNTH_DEC];m > 0;m--) {
  1417. val = (double)m/(double)(dz->iparam[SYNTH_DEC] + 1);
  1418. val = pow(val,dz->param[SYNTH_EDEC]);
  1419. spikebuf[n++] = (float)(val * SPIKEMAX);
  1420. }
  1421. }
  1422. return FINISHED;
  1423. }
  1424. // Check no partials go over nyquist
  1425. if(dz->mode != 4) {
  1426. for(n=0;n < partialscnt;n++) {
  1427. thispartials = dz->parray[n];
  1428. for(m=0;m<entrycnt;m+=2) {
  1429. if(dz->brksize[SYNTH_FRQ]) {
  1430. time = thispartials[m];
  1431. if((exit_status = read_value_from_brktable(time,SYNTH_FRQ,dz))<0)
  1432. return(exit_status);
  1433. }
  1434. top = thispartials[m+1] * dz->param[SYNTH_FRQ];
  1435. if(top >= nyquist) {
  1436. sprintf(errstr,"Partial %lf at time %lf (frq %lf) is above the nyquist (%lf)\n",thispartials[m+1],thispartials[m],dz->param[SYNTH_FRQ],nyquist);
  1437. return(DATA_ERROR);
  1438. }
  1439. }
  1440. }
  1441. }
  1442. // Establish sine-table
  1443. if(dz->mode == 4)
  1444. sinarray = 0;
  1445. else {
  1446. sinarray = partialscnt * 2;
  1447. pntarray = sinarray + 1;
  1448. }
  1449. if((dz->parray[sinarray] = (double *)malloc((SYNTH_TABSIZE + 1) * sizeof(double)))==NULL) {
  1450. sprintf(errstr,"INSUFFICIENT MEMORY for sine table.\n");
  1451. return(MEMORY_ERROR);
  1452. }
  1453. sintab = dz->parray[sinarray];
  1454. for(n=0;n<SYNTH_TABSIZE;n++)
  1455. sintab[n] = sin(PI * 2.0 * ((double)n/(double)SYNTH_TABSIZE));
  1456. sintab[n] = sintab[0]; /* wrap around point */
  1457. // Pointers into sintable for all partials
  1458. if(dz->mode == 4)
  1459. return FINISHED;
  1460. else if(dz->mode == 2) {
  1461. /*
  1462. * | |
  1463. * MODE 2 arrays |positions
  1464. * pcnt = partialcnt mpcnt = maxpartial cnt (partials + all transpositions) | | |
  1465. * | current
  1466. * | frqs|
  1467. * parray |----------|----------|-|-|-----------------|-----------------|-|-|-|
  1468. * | tvarying pno+plevel |s|s| left_level | right-level step| |
  1469. * | (Mpcnt*2) |i|i| mpcnt | mpcnt times |
  1470. * | |n|n| | | | | |
  1471. * address 0 mpcnt*2| |p|(mpcnt*2)+2 |(mpcnt*3)+2 | (mpcnt*4)+3
  1472. * | | |t| | (mpcnt*4)+2
  1473. * | | |r| | | | (mpcnt*4)+4
  1474. * lengths | linelen of srcdata | | | maxsteps | maxsteps | |m| |
  1475. * |s|t| |t|p|t|
  1476. * (slen = sintablen) |l|o| |o|c|o|
  1477. * (totl = estimate of no |e|t| |t|n|t|
  1478. * of timesteps used) |n|l| |l|t|l|
  1479. *
  1480. *
  1481. * iparray |-----------------|-----------------|-----------------|-| switchpos
  1482. * | on-off flags | leftmost chan | spo |s|porder
  1483. * | (mpcnt) | (mpcnt) | (mpcnt) |p| | (mpcnt*3)+2
  1484. * | | | |l| (mpcnt*3)+1
  1485. * address 0 mpcnt mpcnt*2 (mpcnt*3)
  1486. * | | | |c| |
  1487. * lengths | maxsteps | maxsteps | maxsteps |nmpcnt
  1488. * |t| mpcnt
  1489. * |r| |
  1490. * (splcntrs = splice counters) |s| |
  1491. * (spo = orig values of splice counters)
  1492. */
  1493. // A sine-table pointer for every partial and every partial transposition
  1494. if((dz->parray[pntarray] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  1495. sprintf(errstr,"INSUFFICIENT MEMORY for sine table pointers.\n");
  1496. return(MEMORY_ERROR);
  1497. }
  1498. // An array for every partials on-off markers, every leftmost-chan, every splice-counter-orig-vals, plus actual splice-cntrs + porder
  1499. if((dz->iparray = (int **)malloc(((partialscnt * 3) + 3) * sizeof(int *)))==NULL) {
  1500. sprintf(errstr,"INSUFFICIENT MEMORY for integer array fpr partial on-off markers.\n");
  1501. return(MEMORY_ERROR);
  1502. }
  1503. *maxsteps = (int)ceil(dz->param[SYNTH_DUR]/(*minrate)) + 100; // SAFETY
  1504. for(n=0,m=dz->temp_sampsize;n<partialscnt;n++,m++) {
  1505. // An array of on-off switching vals at steptimes, for every partial and partial-transposition
  1506. if((dz->iparray[n] = (int *)malloc((*maxsteps) * sizeof(int)))==NULL) {
  1507. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off marker array %d.\n",n); // base address = 0
  1508. return(MEMORY_ERROR);
  1509. }
  1510. // An array of leftmost output channel at steptimes, for every partial and partial-transposition
  1511. if((dz->iparray[n+partialscnt] = (int *)malloc((*maxsteps) * sizeof(int)))==NULL) {
  1512. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off marker array %d.\n",n); // base address = partialscnt
  1513. return(MEMORY_ERROR);
  1514. }
  1515. // An array of original_vals of splice_counters, at steptimes for every partial and partial-transposition
  1516. if((dz->iparray[n+(partialscnt*2)] = (int *)malloc((*maxsteps) * sizeof(int)))==NULL) {
  1517. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off marker array %d.\n",n); // base address = partialscnt
  1518. return(MEMORY_ERROR);
  1519. }
  1520. // An array levels (or of left levels), at every steptime, for each partial and partial-transposition // base address = dz->temp_sampsize
  1521. if((dz->parray[m] = (double *)malloc((*maxsteps) * sizeof(double)))==NULL) {
  1522. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off gain and step times vals, array %d.\n",n);
  1523. return(MEMORY_ERROR);
  1524. }
  1525. // An array of right levels, at every steptime, for each partial and partial-transposition // base address = dz->temp_sampsize + partialscnt
  1526. if((dz->parray[m+partialscnt] = (double *)malloc((*maxsteps) * sizeof(double)))==NULL) {
  1527. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off gain and step times vals, array %d.\n",n);
  1528. return(MEMORY_ERROR);
  1529. }
  1530. }
  1531. // An array of steptimes
  1532. if((dz->parray[m+partialscnt] = (double *)malloc((*maxsteps) * sizeof(double)))==NULL) { // address = dz->temp_sampsize + (partialscnt * 2)
  1533. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off gain and step times vals, array %d.\n",n);
  1534. return(MEMORY_ERROR);
  1535. }
  1536. // An array of current frqs of partials
  1537. if((dz->parray[m+partialscnt+1] = (double *)malloc(partialscnt * sizeof(double)))==NULL) { // address = dz->temp_sampsize + (partialscnt * 2) + 1
  1538. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off gain and step times vals, array %d.\n",n);
  1539. return(MEMORY_ERROR);
  1540. }
  1541. // An array of current spatial positions
  1542. if((dz->parray[m+partialscnt+2] = (double *)malloc((*maxsteps) * sizeof(double)))==NULL) { // address = dz->temp_sampsize + (partialscnt * 2) + 2
  1543. sprintf(errstr,"INSUFFICIENT MEMORY for step positions.\n");
  1544. return(MEMORY_ERROR);
  1545. }
  1546. // An array of splice-counters for every partial
  1547. if((dz->iparray[partialscnt*3] = (int*)malloc(partialscnt * sizeof(int)))==NULL) { // address = (partialscnt * 3)
  1548. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off gain and step times vals, array %d.\n",n);
  1549. return(MEMORY_ERROR);
  1550. }
  1551. // An array of to remember the partials order, for 2nd run
  1552. if((dz->iparray[(partialscnt*3)+1] = (int*)malloc(partialscnt * sizeof(int)))==NULL) { // address = (partialscnt * 3)+1
  1553. sprintf(errstr,"INSUFFICIENT MEMORY for partial on-off gain and step times vals, array %d.\n",n);
  1554. return(MEMORY_ERROR);
  1555. }
  1556. for(n=0;n<partialscnt;n++) // Store original order
  1557. dz->iparray[(partialscnt*3)+1][n] = n;
  1558. // An array of to remember the switchpos
  1559. if((dz->iparray[(partialscnt*3)+2] = (int*)malloc((*maxsteps) * sizeof(int)))==NULL) { // address = (partialscnt * 3)+2
  1560. sprintf(errstr,"INSUFFICIENT MEMORY for switching between channels %d.\n",n);
  1561. return(MEMORY_ERROR);
  1562. }
  1563. // A permutation array for randomly permuting partials
  1564. if((*perm = (int *)malloc(partialscnt*sizeof(int)))==NULL) {
  1565. sprintf(errstr,"NO MEMORY FOR PARTIALS PERMUTATIONS\n");
  1566. return(DATA_ERROR);
  1567. }
  1568. if((*permon = (int *)malloc(partialscnt*sizeof(int)))==NULL) {
  1569. sprintf(errstr,"NO MEMORY FOR PARTIALS PERMUTATIONS\n");
  1570. return(DATA_ERROR);
  1571. }
  1572. if((*permoff = (int *)malloc(partialscnt*sizeof(int)))==NULL) {
  1573. sprintf(errstr,"NO MEMORY FOR PARTIALS PERMUTATIONS\n");
  1574. return(DATA_ERROR);
  1575. }
  1576. configno = chans;
  1577. configno += (chans * ((chans/2) - 1)) + chans/2;
  1578. configno += chans * 2;
  1579. configno += 3;
  1580. if((*superperm = (int *)malloc(configno*sizeof(int)))==NULL) {
  1581. sprintf(errstr,"NO MEMORY FOR PARTIALS PERMUTATIONS\n");
  1582. return(DATA_ERROR);
  1583. }
  1584. } else {
  1585. if((dz->parray[pntarray] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  1586. sprintf(errstr,"INSUFFICIENT MEMORY for sine table.\n");
  1587. return(MEMORY_ERROR);
  1588. }
  1589. }
  1590. for(n=0;n<dz->itemcnt;n++) // Zero sine-table pointers for all partials
  1591. dz->parray[pntarray][n] = 0.0;
  1592. if(dz->mode == 1) {
  1593. if((exit_status = generate_packet_envelope(dz))<0)
  1594. return(exit_status);
  1595. } else if(dz->mode == 2) {
  1596. if(dz->param[SYNTH_RISE] + dz->param[SYNTH_FALL] + dz->param[SYNTH_STDY] > dz->param[SYNTH_DUR]) {
  1597. sprintf(errstr,"Rise, Fall and Steady-state parameters not compatible with output duration.\n");
  1598. return(DATA_ERROR);
  1599. }
  1600. dz->param[SYNTH_STDY] = dz->param[SYNTH_DUR] - dz->param[SYNTH_STDY];
  1601. dz->param[SYNTH_FALL] = dz->param[SYNTH_STDY] - dz->param[SYNTH_FALL];
  1602. if(dz->param[SYNTH_ETIME] + dz->param[SYNTH_CTIME] >= dz->param[SYNTH_DUR]) {
  1603. sprintf(errstr,"Emerge and Converge times, combined, must be LESS than Output duration.\n");
  1604. return(DATA_ERROR);
  1605. }
  1606. if(dz->iparam[SYNTH_NUM] > partialscnt) {
  1607. sprintf(errstr,"Number of partials in play must be <= total number of partials and their transpositions (%d)\n",partialscnt);
  1608. return(DATA_ERROR);
  1609. }
  1610. if(dz->iparam[SYNTH_EFROM] > dz->iparam[SYNTH_CHANS] || dz->iparam[SYNTH_CTO] > dz->iparam[SYNTH_CHANS]) {
  1611. sprintf(errstr,"Channel to emerge from or converge to must be <= output channel count.\n");
  1612. return(DATA_ERROR);
  1613. }
  1614. if(dz->iparam[SYNTH_EFROM] > 0 && dz->param[SYNTH_ETIME] == 0.0) {
  1615. fprintf(stdout,"WARNING: Emergence time set to zero: Ignoring emergence channel.\n");
  1616. fflush(stdout);
  1617. dz->iparam[SYNTH_EFROM] = 0;
  1618. }
  1619. if(dz->iparam[SYNTH_EFROM] == 0 && dz->param[SYNTH_ETIME] > 0.0) {
  1620. fprintf(stdout,"WARNING: Emergence channel not set: Ignoring emergence duration.\n");
  1621. fflush(stdout);
  1622. dz->param[SYNTH_ETIME] = 0.0;
  1623. }
  1624. if(dz->iparam[SYNTH_CTO] > 0 && dz->param[SYNTH_CTIME] == 0.0) {
  1625. fprintf(stdout,"WARNING: Convergence time set to zero: Ignoring convergence channel.\n");
  1626. fflush(stdout);
  1627. dz->iparam[SYNTH_CTO] = 0;
  1628. }
  1629. if(dz->iparam[SYNTH_CTO] == 0 && dz->param[SYNTH_CTIME] > 0.0) {
  1630. fprintf(stdout,"WARNING: Convergence channel not set: Ignoring convergence duration.\n");
  1631. fflush(stdout);
  1632. dz->param[SYNTH_ETIME] = 0.0;
  1633. }
  1634. if(!dz->vflag[SYN_SPACED] && (dz->iparam[SYNTH_CTO] > 0 || dz->iparam[SYNTH_EFROM] > 0)) {
  1635. fprintf(stdout,"WARNING: Spatialisation flag not set: ignoring emerge/converge parameters.\n");
  1636. fflush(stdout);
  1637. dz->iparam[SYNTH_CTO] = 0;
  1638. dz->iparam[SYNTH_EFROM] = 0;
  1639. dz->param[SYNTH_ETIME] = 0.0;
  1640. dz->param[SYNTH_CTIME] = 0.0;
  1641. }
  1642. dz->param[SYNTH_CTIME] = dz->param[SYNTH_DUR] - dz->param[SYNTH_CTIME];
  1643. if(dz->vflag[SYN_JUMP] && !dz->vflag[SYN_SPACED]) {
  1644. fprintf(stdout,"WARNING: Spatialisation flag not set: ignoring Jump flag.\n");
  1645. fflush(stdout);
  1646. dz->vflag[SYN_JUMP] = 0;
  1647. }
  1648. if(dz->iparam[SYNTH_STYPE] < 0) {
  1649. if(chans != 8) {
  1650. sprintf(errstr,"Special Spatialisation types Only available for 8-channel output.\n");
  1651. return(DATA_ERROR);
  1652. }
  1653. if(dz->iparam[SYNTH_EFROM] || dz->iparam[SYNTH_CTO]) {
  1654. fprintf(stdout,"WARNING: Emergence/convergence not available with Special Spatialisation types.\n");
  1655. fflush(stdout);
  1656. dz->iparam[SYNTH_CTO] = 0;
  1657. dz->iparam[SYNTH_EFROM] = 0;
  1658. dz->param[SYNTH_ETIME] = 0.0;
  1659. dz->param[SYNTH_CTIME] = 0.0;
  1660. }
  1661. if(dz->vflag[SYN_JUMP]) {
  1662. sprintf(errstr,"Special Spatialisation types incompatible with Jump flag. Choose one or the other.\n");
  1663. return(DATA_ERROR);
  1664. }
  1665. if(dz->iparam[SYNTH_STYPE] == SB_ROTATE && dz->param[SYNTH_RSPEED] == 0.0) {
  1666. sprintf(errstr,"No rotation speed given for Special Spatialisation type %d, \"Rotation\".\n",SB_ROTATE);
  1667. return(DATA_ERROR);
  1668. }
  1669. if(dz->iparam[SYNTH_STYPE] != SB_ROTATE && dz->param[SYNTH_RSPEED] > 0.0) {
  1670. sprintf(errstr,"Special Spatialisation type %d, \"Rotation\" not set: Ignoring Rotation Speed.\n",SB_ROTATE);
  1671. fflush(stdout);
  1672. }
  1673. dz->vflag[SYN_SPACED] = 1;
  1674. }
  1675. }
  1676. return(FINISHED);
  1677. }
  1678. /******************************** SYNTHESIS ********************************
  1679. *
  1680. * MODE 2 arrays
  1681. * pcnt = partialcnt mpcnt = maxpartial cnt (partials + all transpositions) | | |
  1682. * | current
  1683. * | frqs|
  1684. * parray |----------|----------|-|-|-----------------|-----------------|-|-|-|
  1685. * | tvarying pno+plevel |s|s| left_level | right-level step|p|
  1686. * | (Mpcnt*2) |i|i| mpcnt | mpcnt timeso|
  1687. * | |n|n| | | | |s|
  1688. * address 0 mpcnt*2| |p|(mpcnt*2)+2 |(mpcnt*3)+2 | (mpcnt*4)+3
  1689. * | | |t| | (mpcnt*4)+2
  1690. * | | |r| | | | (mpcnt*4)+4
  1691. * lengths | linelen of srcdata | | | maxsteps | maxsteps | |m| |
  1692. * |s|t| |t|p|t|
  1693. * (slen = sintablen) |l|o| |o|c|o|
  1694. * (totl = estimate of no |e|t| |t|n|t|
  1695. * of timesteps used) |n|l| |l|t|l|
  1696. *
  1697. * iparray |-----------------|-----------------|-----------------|-| switchpos
  1698. * | on-off flags | leftmost chan | spo |s|porder
  1699. * | (mpcnt) | (mpcnt) | (mpcnt) |p| | (mpcnt*3)+2
  1700. * | | | |l| (mpcnt*3)+1
  1701. * address 0 mpcnt mpcnt*2 (mpcnt*3)
  1702. * | | | |c| |
  1703. * lengths | maxsteps | maxsteps | maxsteps |nmpcnt
  1704. * |t| mpcnt
  1705. * |r| |
  1706. * (splcntrs = splice counters) |s| |
  1707. * (spo = orig values of splice counters)
  1708. */
  1709. int synthesis(int *perm,int *permon,int *permoff,int *superperm, double minrate,int maxsteps,dataptr dz)
  1710. {
  1711. int exit_status, n, chans, rangxs = 0, max_partials_cnt, partials_in_play, rmost, k, terminate = 0, israngechange = 0;
  1712. int loindex, hiindex, packet_dur, kk, stepcnt = 0, totaloutsamps, base_sampcnt;
  1713. double loval, hival, valdiff, timefrac, val, valr = 0.0, vall = 0.0, level, maxval = 1.0, onehzincr, packet_incr, envv, pos = 0.0;
  1714. float *obuf = dz->sampbuf[0];
  1715. double srate = (double)dz->infile->srate, thisstep, xsrange_frac = 0.0, thisrangxs, rangetop, posstep = 0.0;
  1716. int partialcnt = dz->itemcnt, total_partialcnt = 0, sintable = partialcnt * 2, splen = 0, spacetyp = dz->iparam[SYNTH_STYPE];
  1717. double *sintab = dz->parray[sintable], *sinptr = dz->parray[sintable+1];
  1718. double **llev = NULL, **rlev = NULL;
  1719. double *steptimes = NULL, *pvals = NULL, *position = NULL;
  1720. int **onoff = NULL, **lmost = NULL, **origspl = NULL, *splcntr = NULL, *splordr = NULL, *swpos = NULL;
  1721. int inendsplice, instartsplice, total_samps_synthed = 0, jlmost = 0, switchpos = 0;
  1722. int configcnt = 0, configno = 0, l_most = 0, r_most = 0, special_onoff = 0, indownsplice = 0;
  1723. int sampcnt = 0, startspliceend = dz->rampbrksize, endsplicestart = dz->iparam[1] - dz->rampbrksize;
  1724. double time = 0.0, spliceincr, spliceval, localspliceval, normaliser, falldur = 0.0, enddur = 0.0, nexttime = -1.0, leftgain = 0.0, rightgain = 0.0;
  1725. int packet_phase = 1;
  1726. onehzincr = (double)SYNTH_TABSIZE/srate;
  1727. spliceincr = 1.0/(double)dz->rampbrksize;
  1728. spliceval = 0.0;
  1729. instartsplice = 1;
  1730. inendsplice = 0;
  1731. totaloutsamps = dz->iparam[1];
  1732. if(dz->mode == 2) {
  1733. chans = dz->iparam[SYNTH_CHANS];
  1734. if(spacetyp > 0) {
  1735. switch(spacetyp) {
  1736. case(SB_SUPERSPACE4): // Square, diamond and All-at-once
  1737. configno = 3; // For 8 chan = 3 + (8*2) + [((8*(4-1))+4] + 8 = 3 + 16 + 28 + 8 = 55
  1738. // fall thro
  1739. case(SB_SUPERSPACE3): // all possible meaningful small and large triangles
  1740. configno += chans * 2;
  1741. // fall thro
  1742. case(SB_SUPERSPACE2): // all possible pairs
  1743. configno += (chans * ((chans/2) - 1)) + chans/2;
  1744. // fall thro
  1745. case(SB_SUPERSPACE): // all single chans
  1746. configno += chans;
  1747. break;
  1748. }
  1749. }
  1750. totaloutsamps *= chans;
  1751. endsplicestart = dz->iparam[1] - (int)floor(50 * MS_TO_SECS * srate); // Force long splice at end
  1752. endsplicestart *= chans;
  1753. startspliceend = (int)floor(50 * MS_TO_SECS * srate); // Force long splice at start
  1754. startspliceend *= chans;
  1755. instartsplice = 1;
  1756. inendsplice = 0;
  1757. splen = (int)round(dz->param[SYNTH_SPLEN] * MS_TO_SECS * srate);
  1758. total_partialcnt = partialcnt;
  1759. llev = dz->parray + (partialcnt * 2) + 2;
  1760. rlev = dz->parray + (partialcnt * 3) + 2;
  1761. steptimes = dz->parray[(partialcnt * 4) + 2];
  1762. pvals = dz->parray[(partialcnt * 4) + 3];
  1763. position = dz->parray[(partialcnt * 4) + 4];
  1764. onoff = dz->iparray;
  1765. lmost = dz->iparray + partialcnt;
  1766. origspl = dz->iparray + (partialcnt * 2);
  1767. splcntr = dz->iparray[partialcnt * 3];
  1768. splordr = dz->iparray[(partialcnt * 3) + 1];
  1769. swpos = dz->iparray[(partialcnt * 3) + 2];
  1770. falldur = dz->param[SYNTH_STDY] - dz->param[SYNTH_FALL];
  1771. enddur = dz->param[SYNTH_DUR] - dz->param[SYNTH_STDY];
  1772. rangxs = dz->iparam[SYNTH_MAX] - 1; // Max no partial-transpositions (apart from orig vals)
  1773. for(n=0;n < partialcnt;n++) {
  1774. onoff[n][0] = S_OFF;// all partials initially flagged off
  1775. lmost[n][0] = 0; // all leftmost-outchan initially set to left - SAFETY
  1776. origspl[n][0] = 0; // all original-settings of splice-counters to zero
  1777. splcntr[n] = 0; // all splicecounters initially set to zero - SAFETY
  1778. llev[n][0] = 0.0; // all partial gains initially set to zero - SAFETY
  1779. rlev[n][0] = 0.0;
  1780. }
  1781. nexttime = 0.0; // initialise "nexttime" to trigger 1st setting of partials
  1782. steptimes[0] = nexttime;// initial steptime set to zero
  1783. stepcnt = 0;
  1784. } else {
  1785. chans = 1;
  1786. }
  1787. fprintf(stdout,"INFO: First pass: assessing level.\n");
  1788. fflush(stdout);
  1789. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1790. while(total_samps_synthed < totaloutsamps) {
  1791. time = (double)(total_samps_synthed/chans)/srate;
  1792. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  1793. return exit_status;
  1794. switch(dz->mode) {
  1795. case(0):
  1796. for(n=0;n<dz->itemcnt;n++) {
  1797. loindex = (int)floor(sinptr[n]); // Read from sintable, using partial-increment
  1798. hiindex = loindex + 1;
  1799. loval = sintab[loindex];
  1800. hival = sintab[hiindex];
  1801. valdiff = hival - loval;
  1802. timefrac = sinptr[n] - (double)loindex;
  1803. val = loval + (valdiff * timefrac);
  1804. level = read_level(n,time,dz); // Read corresponding level
  1805. val *= level;
  1806. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  1807. incr_sinptr(n,time,onehzincr,dz); // Track (modify if ness) the partial-incr value for this partial
  1808. }
  1809. if(instartsplice) {
  1810. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  1811. spliceval += spliceincr;
  1812. spliceval = min(spliceval,1.0);
  1813. } else if(inendsplice) {
  1814. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  1815. spliceval -= spliceincr;
  1816. spliceval = max(spliceval,0.0);
  1817. }
  1818. maxval = max(maxval,fabs(obuf[sampcnt]));
  1819. if(++sampcnt >= dz->buflen) {
  1820. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1821. sampcnt = 0;
  1822. }
  1823. total_samps_synthed++;
  1824. if(!inendsplice && (total_samps_synthed >= endsplicestart)) {
  1825. inendsplice = 1;
  1826. spliceval = 1.0;
  1827. }
  1828. if(instartsplice && (total_samps_synthed >= startspliceend))
  1829. instartsplice = 0;
  1830. break;
  1831. case(1):
  1832. if(dz->brksize[SYNTH_SQZ] || dz->brksize[SYNTH_CTR]) {
  1833. if(!(flteq(dz->param[SYNTH_SQZ],1.0)) || !(flteq(dz->param[SYNTH_CTR],0.0)))
  1834. modify_packet_envelope(dz);
  1835. }
  1836. packet_dur = (int)round((1.0/dz->param[SYNTH_FRQ]) * srate);
  1837. packet_incr = (double)TREMOLO_TABSIZE/(double)(packet_dur - 1); // Forces last read to be at end of packet envelope (zero)
  1838. for(n=0;n<dz->itemcnt;n++)
  1839. sinptr[n] = 0.0;
  1840. for(kk = 0; kk<packet_dur;kk++) {
  1841. for(n=0;n<dz->itemcnt;n++) {
  1842. if(!dz->vflag[0])
  1843. time = (double)(total_samps_synthed + n)/srate;
  1844. loindex = (int)floor(sinptr[n]);
  1845. hiindex = loindex + 1;
  1846. loval = sintab[loindex];
  1847. hival = sintab[hiindex];
  1848. valdiff = hival - loval;
  1849. timefrac = sinptr[n] - (double)loindex;
  1850. val = loval + (valdiff * timefrac);
  1851. level = read_level(n,time,dz);
  1852. val *= level;
  1853. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  1854. incr_sinptr(n,time,onehzincr,dz);
  1855. }
  1856. envv = read_packet_envelope(kk,packet_incr,dz);
  1857. obuf[sampcnt] = (float)(obuf[sampcnt] * envv * packet_phase);
  1858. maxval = max(maxval,fabs(obuf[sampcnt]));
  1859. if(++sampcnt >= dz->buflen) {
  1860. sampcnt = 0;
  1861. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1862. }
  1863. total_samps_synthed++;
  1864. }
  1865. packet_phase = -packet_phase;
  1866. break;
  1867. case(2):
  1868. if(time >= steptimes[stepcnt]) { // If we've reached the next partials-change time
  1869. if(sloom && ((stepcnt % 200) == 0)) {
  1870. fprintf(stdout,"INFO: at %.1lf secs\n",time);
  1871. fflush(stdout);
  1872. }
  1873. if(spacetyp > 0) {
  1874. if(configcnt == 0)
  1875. rndintperm(superperm,configno);
  1876. if(++configcnt >= configno)
  1877. configcnt = 0;
  1878. }
  1879. thisstep = (drand48() * 2.0) - 1.0; // -1 to 1
  1880. thisstep *= dz->param[SYNTH_RATE]/2.0; // -(1/2) rate to +(1/2) rate
  1881. thisstep += dz->param[SYNTH_RATE]; // (1/2) rate to 1+(1/2) rate
  1882. nexttime = time + thisstep;
  1883. stepcnt++;
  1884. if(spacetyp == SB_ROTATE)
  1885. posstep = thisstep * dz->param[SYNTH_RSPEED] * chans;
  1886. if(stepcnt >= maxsteps - 1) { // If we run out of memory (as steps have random length) despite safety margin
  1887. terminate = 1; // Force all partials to turn off, and terminate at end of fade
  1888. totaloutsamps = total_samps_synthed + (splen * chans);
  1889. }
  1890. steptimes[stepcnt] = nexttime;
  1891. // Find current value of all partials, + sort to ascending order
  1892. get_current_partial_vals(time,pvals,total_partialcnt,dz);
  1893. sort_partials_into_ascending_frq_order(total_partialcnt,pvals,sinptr,llev,rlev,onoff,lmost,origspl,splordr,dz);
  1894. // FIND THE RANGE OF PARTIALS WHICH CAN BE USED
  1895. if(terminate) { // TURN EVERYTHING OFF!!
  1896. for(n=0;n<total_partialcnt;n++) {
  1897. onoff[n][stepcnt] = S_OFF;
  1898. if(onoff[n][stepcnt-1] == S_ON) {
  1899. origspl[n][stepcnt] = splen; // Partial is switched off
  1900. splcntr[n] = splen; // Set up dnsplice, retaining previous level
  1901. llev[n][stepcnt] = llev[n][stepcnt-1];
  1902. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  1903. if(dz->vflag[SYN_SPACED]) // Retain previous level(s)
  1904. rlev[n][stepcnt] = rlev[n][stepcnt-1];
  1905. else
  1906. rlev[n][stepcnt] = 0.0;
  1907. } else if(onoff[n][stepcnt-1] == S_OFF) {
  1908. origspl[n][stepcnt] = 0; // Partial already OFF
  1909. splcntr[n] = 0; // SAFETY
  1910. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  1911. }
  1912. }
  1913. } else {
  1914. if(dz->iparam[SYNTH_MAX] > 1) { // Find which partials can be used at this time....
  1915. israngechange = 0;
  1916. if(time < dz->param[SYNTH_RISE]) { // If we're in the initial fade-up or final fade-down
  1917. xsrange_frac = (dz->param[SYNTH_RISE] - time)/dz->param[SYNTH_RISE]; // Frac Range 1-0
  1918. israngechange = 1;
  1919. } else if(time > dz->param[SYNTH_FALL] && time < dz->param[SYNTH_STDY]) { // Calc the active octave-range at this point
  1920. xsrange_frac = (time - dz->param[SYNTH_FALL])/falldur; // Frac Range 0-1
  1921. israngechange = 2;
  1922. } else if (time >= dz->param[SYNTH_STDY]) {
  1923. if(dz->vflag[SYN_TOROOT]) // If we're in final steady-state or final fade
  1924. xsrange_frac = (time - dz->param[SYNTH_STDY])/enddur; // Frac Range 0-1
  1925. else
  1926. xsrange_frac = 1.0; // Flat
  1927. israngechange = 3;
  1928. }
  1929. if(israngechange) {
  1930. xsrange_frac = 1.0 - xsrange_frac; // Frac Range 1-0
  1931. if((israngechange == 1) && dz->vflag[SYN_FROMROOT]) {
  1932. thisrangxs = dz->iparam[SYNTH_MAX] * xsrange_frac; // Expand from root to max-range
  1933. rangetop = thisrangxs * dz->scalefact;
  1934. } else if((israngechange == 3) && dz->vflag[SYN_TOROOT]) {
  1935. thisrangxs = xsrange_frac; // Contract from min-range to root
  1936. rangetop = thisrangxs * dz->scalefact;
  1937. } else {
  1938. thisrangxs = rangxs * xsrange_frac; // Contract xs-range
  1939. rangetop = (1.0 + thisrangxs) * dz->scalefact; // Find current top of range
  1940. } // Multiplying by original range of partials (scalefact)
  1941. for(n = 0;n<total_partialcnt;n++) {
  1942. if(pvals[n] >= rangetop) // Find max partial we can use
  1943. break;
  1944. }
  1945. max_partials_cnt = n+1; // Max range of partials-and-transpositions we might use
  1946. max_partials_cnt = min(max_partials_cnt,total_partialcnt); // FAILSAFE
  1947. } else // Otherwise, use maximum octave range
  1948. max_partials_cnt = total_partialcnt;
  1949. } else
  1950. max_partials_cnt = total_partialcnt;
  1951. // P-and-ts we'll actually use at this moment (random)
  1952. if(dz->iparam[SYNTH_NUM] > 0)
  1953. partials_in_play = min(dz->iparam[SYNTH_NUM],max_partials_cnt);
  1954. else
  1955. partials_in_play = (int)floor(drand48() * (double)max_partials_cnt) + 1;
  1956. // If Jump flag set, do spatialisation for ALL partials FIRST
  1957. special_onoff = 0;
  1958. if(dz->vflag[SYN_SPACED]) {
  1959. if(dz->vflag[SYN_JUMP]) {
  1960. if(dz->iparam[SYNTH_EFROM] && (time < dz->param[SYNTH_ETIME]))
  1961. pos = emergepos(dz->iparam[SYNTH_EFROM],chans,time,dz->param[SYNTH_ETIME]);
  1962. else if(dz->iparam[SYNTH_CTO] && (time > dz->param[SYNTH_CTIME]))
  1963. pos = convergepos(dz->iparam[SYNTH_CTO],chans,time,dz->param[SYNTH_CTIME],dz->param[SYNTH_DUR]);
  1964. else
  1965. pos = chans * drand48();
  1966. jlmost = (int)floor(pos);
  1967. pos -= (double)jlmost;
  1968. pos = (pos * 2.0) - 1.0;
  1969. pancalc(pos,&leftgain,&rightgain);
  1970. } else if(spacetyp > 0) {
  1971. spacebox(&pos,&switchpos,posstep,chans,spacetyp,configno,configcnt,superperm);
  1972. position[stepcnt] = pos;
  1973. swpos[stepcnt] = switchpos;
  1974. if((position[stepcnt] != position[stepcnt-1]) || (swpos[stepcnt] != swpos[stepcnt-1]))
  1975. special_onoff = 1; // Where partial changes position, will need to fade-out then refade-in
  1976. }
  1977. }
  1978. // Randomly-> CHOOSE PARTIALS ON or OFF, ESTABLISH RELATIVE LEVEL, SET SPATIAL POSITION (if flagged)
  1979. if(partials_in_play == max_partials_cnt) { // If partials fill available range
  1980. for(n=0;n<partials_in_play;n++) { // All partials in range are on
  1981. onoff[n][stepcnt] = S_ON;
  1982. if(onoff[n][stepcnt-1] == S_OFF) { // If previously off
  1983. origspl[n][stepcnt] = splen; // Mark as fade-up
  1984. splcntr[n] = splen; // Set splice-counter to count back down to zero
  1985. llev[n][stepcnt] = (drand48() * 0.5) + 0.5; // Set new (rand)level [llev stands in for mono level]
  1986. if(dz->vflag[SYN_SPACED] && (spacetyp == 0)) { // If SPATIALISED
  1987. if(dz->vflag[SYN_JUMP]) { // If Jump flag in use, leftmost chan and levels already set
  1988. lmost[n][stepcnt] = jlmost;
  1989. rlev[n][stepcnt] = llev[n][stepcnt] * rightgain;
  1990. llev[n][stepcnt] *= leftgain;
  1991. } else { // Else create position for each individual partial
  1992. if(dz->iparam[SYNTH_EFROM] && (time < dz->param[SYNTH_ETIME]))
  1993. pos = emergepos(dz->iparam[SYNTH_EFROM],chans,time,dz->param[SYNTH_ETIME]);
  1994. else if(dz->iparam[SYNTH_CTO] && (time > dz->param[SYNTH_CTIME]))
  1995. pos = convergepos(dz->iparam[SYNTH_CTO],chans,time,dz->param[SYNTH_CTIME],dz->param[SYNTH_DUR]);
  1996. else
  1997. pos = chans * drand48();// Create spatial position at random (range 0 - chans)
  1998. lmost[n][stepcnt] = (int)floor(pos); // Find leftmost lspkr
  1999. pos -= (double)lmost[n][stepcnt]; // Range 0-1
  2000. pos = (pos * 2.0) - 1.0; // Range (-1 to 1)
  2001. pancalc(pos,&leftgain,&rightgain); // Calc relative levels of left and right signals
  2002. rlev[n][stepcnt] = llev[n][stepcnt] * rightgain;
  2003. llev[n][stepcnt] *= leftgain; // Readjust output levels
  2004. }
  2005. } else {
  2006. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2007. rlev[n][stepcnt] = 0.0;
  2008. }
  2009. } else { // Else, already on
  2010. llev[n][stepcnt] = llev[n][stepcnt-1];// Retain previous level(s)
  2011. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2012. if(dz->vflag[SYN_SPACED])
  2013. rlev[n][stepcnt] = rlev[n][stepcnt-1];
  2014. else
  2015. rlev[n][stepcnt] = 0.0;
  2016. if(special_onoff) {
  2017. splcntr[n] = splen * 2;
  2018. origspl[n][stepcnt] = splen * 2;
  2019. } else {
  2020. origspl[n][stepcnt] = 0;
  2021. splcntr[n] = 0; // SAFETY
  2022. }
  2023. }
  2024. }
  2025. while(n < total_partialcnt) { // For all remaining (unused) partials
  2026. onoff[n][stepcnt] = S_OFF;
  2027. if(onoff[n][stepcnt-1] == S_ON) { // If partial was on
  2028. origspl[n][stepcnt] = splen; // Mark it as fading out
  2029. splcntr[n] = splen; // Set splice-counter to count down to zero
  2030. llev[n][stepcnt] = llev[n][stepcnt-1];
  2031. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2032. if(dz->vflag[SYN_SPACED]) // retaining previous level(s)
  2033. rlev[n][stepcnt] = rlev[n][stepcnt-1];
  2034. else
  2035. rlev[n][stepcnt] = 0.0;
  2036. } else { // Else it was previously off
  2037. origspl[n][stepcnt] = 0;
  2038. splcntr[n] = 0; // SAFETY
  2039. origspl[n][stepcnt] = 0;
  2040. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2041. }
  2042. n++;
  2043. }
  2044. } else {
  2045. rndintperm(perm,max_partials_cnt); // Randomly permute all possible partials
  2046. if(dz->vflag[SYN_X]) // If Exclusuve, Force currently OFF-partials to top of list
  2047. xclusive(perm,permon,permoff,max_partials_cnt,partials_in_play,onoff,stepcnt);
  2048. for(n=0;n<partials_in_play;n++) // Switch first p_in_p partials in perm, ON
  2049. onoff[perm[n]][stepcnt] = S_ON;
  2050. while(n < max_partials_cnt) { // and switch remainder of those in range off
  2051. onoff[perm[n]][stepcnt] = S_OFF;
  2052. n++;
  2053. }
  2054. while(n < total_partialcnt) { // and switch remainder off
  2055. onoff[n][stepcnt] = S_OFF;
  2056. n++;
  2057. }
  2058. // ALGO ASSUMES THAT, BY THE TIME WE REACH NEXT STEP, splice has ended
  2059. for(n=0;n<total_partialcnt;n++) { // Switch first p_in_p partials in perm, ON
  2060. if(onoff[n][stepcnt] == S_ON) {
  2061. if(onoff[n][stepcnt-1] == S_ON) { // Partial remains on
  2062. llev[n][stepcnt] = llev[n][stepcnt-1];
  2063. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2064. if(dz->vflag[SYN_SPACED]) // Retain previous level(s)
  2065. rlev[n][stepcnt] = rlev[n][stepcnt-1];
  2066. else
  2067. rlev[n][stepcnt] = 0.0;
  2068. if(special_onoff) {
  2069. origspl[n][stepcnt] = splen * 2;
  2070. splcntr[n] = splen * 2;
  2071. } else {
  2072. origspl[n][stepcnt] = 0;
  2073. splcntr[n] = 0; // SAFETY
  2074. }
  2075. } else if(onoff[n][stepcnt-1] == S_OFF) {
  2076. origspl[n][stepcnt] = splen;
  2077. splcntr[n] = splen; // Partial is switched on
  2078. llev[n][stepcnt] = (drand48() * 0.5) + 0.5; // Set new (rand)level
  2079. if(dz->vflag[SYN_SPACED] && (spacetyp == 0)) { // If SPATIALISED...etc
  2080. if(dz->vflag[SYN_JUMP]) { // If Jump flag in use, leftmost chan and levels already set
  2081. lmost[n][stepcnt] = jlmost;
  2082. rlev[n][stepcnt] = llev[n][stepcnt] * rightgain;
  2083. llev[n][stepcnt] *= leftgain;
  2084. } else { // Else create position for each individual partial
  2085. if(dz->iparam[SYNTH_EFROM] && (time < dz->param[SYNTH_ETIME]))
  2086. pos = emergepos(dz->iparam[SYNTH_EFROM],chans,time,dz->param[SYNTH_ETIME]);
  2087. else if(dz->iparam[SYNTH_CTO] && (time > dz->param[SYNTH_CTIME]))
  2088. pos = convergepos(dz->iparam[SYNTH_CTO],chans,time,dz->param[SYNTH_CTIME],dz->param[SYNTH_DUR]);
  2089. else
  2090. pos = chans * drand48();
  2091. lmost[n][stepcnt] = (int)floor(pos);
  2092. pos -= (double)lmost[n][stepcnt];
  2093. pos = (pos * 2.0) - 1.0;
  2094. pancalc(pos,&leftgain,&rightgain);
  2095. rlev[n][stepcnt] = llev[n][stepcnt] * rightgain;
  2096. llev[n][stepcnt] *= leftgain;
  2097. }
  2098. } else {
  2099. rlev[n][stepcnt] = 0.0;
  2100. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2101. }
  2102. }
  2103. } else { // Marked as OFF
  2104. if(onoff[n][stepcnt-1] == S_ON) {
  2105. origspl[n][stepcnt] = splen; // Partial is switched off
  2106. splcntr[n] = splen; // Set up dnsplice, retaining previous level
  2107. llev[n][stepcnt] = llev[n][stepcnt-1];
  2108. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2109. if(dz->vflag[SYN_SPACED]) // Retain previous level(s)
  2110. rlev[n][stepcnt] = rlev[n][stepcnt-1];
  2111. else
  2112. rlev[n][stepcnt] = 0.0;
  2113. } else if(onoff[n][stepcnt-1] == S_OFF) {
  2114. origspl[n][stepcnt] = 0; // Partial already OFF
  2115. splcntr[n] = 0; // SAFETY
  2116. lmost[n][stepcnt] = lmost[n][stepcnt-1];
  2117. }
  2118. }
  2119. }
  2120. }
  2121. }
  2122. }
  2123. // USING THE ON/OFF, RELATIVE LEVEL, SPLICING, AND SPATIALISATION INFO, WRITE VARIOUS PARTIALS
  2124. base_sampcnt = sampcnt;
  2125. for(n=0;n<total_partialcnt;n++) {
  2126. sampcnt = base_sampcnt;
  2127. if(onoff[n][stepcnt]) { // If partial is NOW on
  2128. loindex = (int)floor(sinptr[n]); // Read from sintable, using partial-increment
  2129. hiindex = loindex + 1;
  2130. loval = sintab[loindex];
  2131. hival = sintab[hiindex];
  2132. valdiff = hival - loval;
  2133. timefrac = sinptr[n] - (double)loindex;
  2134. val = loval + (valdiff * timefrac);
  2135. level = read_level(n,time,dz); // Read corresponding level
  2136. indownsplice = 0;
  2137. if(splcntr[n] > 0) { // Get any splice contribution
  2138. if(splcntr[n] > splen) { // This indicates an OFF/ON splice
  2139. localspliceval = (double)(splcntr[n] - splen)/(double)splen;
  2140. indownsplice = 1; // Down-splice
  2141. } else {
  2142. indownsplice = 0; // Up-splice
  2143. localspliceval = (double)(splen - splcntr[n])/(double)splen;
  2144. }
  2145. val *= localspliceval; // Upfade, splcntr falling, splen-splcntr rising
  2146. splcntr[n]--; // Advance splicecnt towards zero
  2147. }
  2148. if(dz->vflag[SYN_SPACED]) { // If spatialisation, get spatial contributions
  2149. if(spacetyp > 0) {
  2150. if(indownsplice) {
  2151. pos = position[stepcnt-1];
  2152. switchpos = swpos[stepcnt-1];
  2153. spacebox_apply(pos,llev[n][stepcnt-1],chans,&l_most,&r_most,&valr,&vall,spacetyp);
  2154. } else {
  2155. pos = position[stepcnt];
  2156. switchpos = swpos[stepcnt];
  2157. spacebox_apply(pos,llev[n][stepcnt],chans,&l_most,&r_most,&valr,&vall,spacetyp);
  2158. }
  2159. valr = val * valr;
  2160. val = val * vall;
  2161. } else { // If spatialisation, get spatial contributions
  2162. valr = val * rlev[n][stepcnt];
  2163. val *= llev[n][stepcnt];
  2164. }
  2165. } else
  2166. val *= llev[n][stepcnt]; // Or just incorporate calculated atten for this element
  2167. if(dz->vflag[SYN_SPACED]) { // if spatialised, find rightmost channel from leftmost
  2168. if(spacetyp > 0) {
  2169. output_special_spatialisation_sample(obuf,sampcnt,switchpos,chans,val,valr,l_most,r_most,spacetyp);
  2170. sampcnt += chans;
  2171. } else {
  2172. rmost = (lmost[n][stepcnt] + 1) % chans;
  2173. for(k = 0;k< chans;k++) {
  2174. if(k == lmost[n][stepcnt]) // Add output only to the 2 relevant channels
  2175. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2176. else if(k == rmost)
  2177. obuf[sampcnt] = (float)(obuf[sampcnt] + valr);
  2178. sampcnt++;
  2179. }
  2180. }
  2181. } else { // If NOT spatialised, add output to all outchans
  2182. for(k = 0;k < chans;k++) {
  2183. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2184. sampcnt++;
  2185. }
  2186. }
  2187. } else { // Partial is OFF
  2188. if(splcntr[n] > 0) { // BUT IF its still a fade-out, Get any splice contribution
  2189. loindex = (int)floor(sinptr[n]);
  2190. hiindex = loindex + 1;
  2191. loval = sintab[loindex];
  2192. hival = sintab[hiindex];
  2193. valdiff = hival - loval;
  2194. timefrac = sinptr[n] - (double)loindex;
  2195. val = loval + (valdiff * timefrac);
  2196. level = read_level(n,time,dz);
  2197. localspliceval = (double)splcntr[n]/(double)splen; // Downfade, splcntr falling
  2198. val *= localspliceval;
  2199. splcntr[n]--; // Advance splicecnt towards zero
  2200. if(dz->vflag[SYN_SPACED]) {
  2201. if(spacetyp > 0) {
  2202. pos = position[stepcnt-1];
  2203. switchpos = swpos[stepcnt-1];
  2204. spacebox_apply(pos,llev[n][stepcnt-1],chans,&l_most,&r_most,&valr,&vall,spacetyp);
  2205. valr = val * valr;
  2206. val = val * vall;
  2207. } else {
  2208. valr = val * rlev[n][stepcnt];
  2209. val *= llev[n][stepcnt];
  2210. }
  2211. } else
  2212. val *= llev[n][stepcnt];
  2213. if(dz->vflag[SYN_SPACED]) {
  2214. if(spacetyp > 0) {
  2215. output_special_spatialisation_sample(obuf,sampcnt,switchpos,chans,val,valr,l_most,r_most,spacetyp);
  2216. sampcnt += chans;
  2217. } else {
  2218. rmost = (lmost[n][stepcnt] + 1) % chans;
  2219. for(k = 0;k < chans;k++) {
  2220. if(k == lmost[n][stepcnt])
  2221. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2222. else if(k == rmost)
  2223. obuf[sampcnt] = (float)(obuf[sampcnt] + valr);
  2224. sampcnt++;
  2225. }
  2226. }
  2227. } else {
  2228. for(k = 0;k < chans;k++) {
  2229. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2230. sampcnt++;
  2231. }
  2232. }
  2233. }
  2234. }
  2235. incr_sinptr(n,time,onehzincr,dz);
  2236. }
  2237. if(instartsplice) { // Do big splice at start of output
  2238. sampcnt = base_sampcnt;
  2239. for(k = 0;k < chans;k++) {
  2240. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  2241. sampcnt++;
  2242. }
  2243. spliceval += spliceincr;
  2244. spliceval = min(spliceval,1.0);
  2245. } else if(inendsplice) { // Do big splice at end of output
  2246. sampcnt = base_sampcnt;
  2247. for(k = 0;k < chans;k++) {
  2248. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  2249. sampcnt++;
  2250. }
  2251. spliceval -= spliceincr;
  2252. spliceval = max(spliceval,0.0);
  2253. }
  2254. sampcnt = base_sampcnt; // Find maxval over all channels
  2255. for(k = 0;k< chans;k++) {
  2256. maxval = max(maxval,fabs(obuf[sampcnt]));
  2257. sampcnt++;
  2258. }
  2259. if(sampcnt >= dz->buflen) { // Check if buffer full - refresh
  2260. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2261. sampcnt = 0;
  2262. }
  2263. total_samps_synthed += chans; // Find out if (still) in startsplice or endsplice
  2264. if(!inendsplice && (total_samps_synthed >= endsplicestart)) {
  2265. inendsplice = 1;
  2266. spliceval = 1.0;
  2267. }
  2268. if(instartsplice && (total_samps_synthed >= startspliceend))
  2269. instartsplice = 0;
  2270. break;
  2271. }
  2272. }
  2273. if(sloom) {
  2274. fprintf(stdout,"INFO: at %.1lf secs\n",time);
  2275. fflush(stdout);
  2276. }
  2277. packet_phase = 1;
  2278. normaliser = 0.85/maxval;
  2279. time = 0.0;
  2280. spliceval = 0.0;
  2281. instartsplice = 1;
  2282. inendsplice = 0;
  2283. total_samps_synthed = 0;
  2284. sampcnt = 0;
  2285. for(n=0;n<dz->itemcnt;n++) // Zero sine-table pointers for all partials
  2286. sinptr[n] = 0.0;
  2287. if(dz->mode == 2) {
  2288. for(n=0;n < partialcnt;n++) {
  2289. onoff[n][0] = S_OFF;// all partials initially flagged off
  2290. lmost[n][0] = 0; // all leftmost-outchan initially set to left - SAFETY
  2291. origspl[n][0] = 0; // all original-settings of splice-counters to zero
  2292. splcntr[n] = 0; // all splicecounters initially set to zero - SAFETY
  2293. llev[n][0] = 0.0; // all partial gains initially set to zero - SAFETY
  2294. rlev[n][0] = 0.0;
  2295. }
  2296. stepcnt = 0;
  2297. terminate = 0;
  2298. resort_partials_into_original_frq_order(total_partialcnt,pvals,sinptr,llev,rlev,onoff,lmost,origspl,splordr,dz);
  2299. }
  2300. fprintf(stdout,"INFO: Second pass: synthesis.\n");
  2301. fflush(stdout);
  2302. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2303. while(total_samps_synthed < totaloutsamps) {
  2304. time = (double)(total_samps_synthed/chans)/srate;
  2305. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2306. return exit_status;
  2307. switch(dz->mode) {
  2308. case(0):
  2309. for(n=0;n<dz->itemcnt;n++) {
  2310. loindex = (int)floor(sinptr[n]); // Read from sintable, using partial-increment
  2311. hiindex = loindex + 1;
  2312. loval = sintab[loindex];
  2313. hival = sintab[hiindex];
  2314. valdiff = hival - loval;
  2315. timefrac = sinptr[n] - (double)loindex;
  2316. val = loval + (valdiff * timefrac);
  2317. level = read_level(n,time,dz); // Read corresponding level
  2318. val *= level;
  2319. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2320. incr_sinptr(n,time,onehzincr,dz); // Track (modify if ness) the partial-incr value for this partial
  2321. }
  2322. obuf[sampcnt] = (float)(obuf[sampcnt] * normaliser);
  2323. if(instartsplice) {
  2324. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  2325. spliceval += spliceincr;
  2326. spliceval = min(spliceval,1.0);
  2327. } else if(inendsplice) {
  2328. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  2329. spliceval -= spliceincr;
  2330. spliceval = max(spliceval,0.0);
  2331. }
  2332. total_samps_synthed++;
  2333. if(!inendsplice && (total_samps_synthed >= endsplicestart)) {
  2334. inendsplice = 1;
  2335. spliceval = 1.0;
  2336. }
  2337. if(instartsplice && (total_samps_synthed >= startspliceend))
  2338. instartsplice = 0;
  2339. if(++sampcnt >= dz->buflen) {
  2340. if((exit_status = write_samps(obuf,sampcnt,dz))<0)
  2341. return(exit_status);
  2342. sampcnt = 0;
  2343. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2344. }
  2345. break;
  2346. case(1): // At start of each packet, set up packet shape, size and increment
  2347. if(!(flteq(dz->param[SYNTH_SQZ],1.0)) || !(flteq(dz->param[SYNTH_CTR],0.0)))
  2348. modify_packet_envelope(dz); // Packet duration determined by fundamental frq
  2349. packet_dur = (int)round((1.0/dz->param[SYNTH_FRQ]) * srate);
  2350. packet_incr = (double)TREMOLO_TABSIZE/(double)(packet_dur - 1);
  2351. for(n=0;n<dz->itemcnt;n++) // Zero sine-table pointers for all partials, at start of packet
  2352. sinptr[n] = 0.0;
  2353. for(kk = 0; kk<packet_dur;kk++) {
  2354. for(n=0;n<dz->itemcnt;n++) { // If not holding partial values steady WITHIN packets,
  2355. if(!dz->vflag[0]) // use absolute time to update partial frqs and levels.
  2356. time = (double)(total_samps_synthed + n)/srate; // Otherwise use packet_start-time,
  2357. loindex = (int)floor(sinptr[n]); // Read from sintable, using partial-increment
  2358. hiindex = loindex + 1;
  2359. loval = sintab[loindex];
  2360. hival = sintab[hiindex];
  2361. valdiff = hival - loval;
  2362. timefrac = sinptr[n] - (double)loindex;
  2363. val = loval + (valdiff * timefrac);
  2364. level = read_level(n,time,dz); // Read corresponding level
  2365. val *= level;
  2366. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2367. incr_sinptr(n,time,onehzincr,dz); // Track (modify if ness) the partial-incr value for this partial
  2368. }
  2369. // Once all partial-samples added, impose packet envelope
  2370. envv = read_packet_envelope(kk,packet_incr,dz);
  2371. obuf[sampcnt] = (float)(obuf[sampcnt] * envv * normaliser * packet_phase);
  2372. total_samps_synthed++;
  2373. if(++sampcnt >= dz->buflen) {
  2374. if((exit_status = write_samps(obuf,sampcnt,dz))<0)
  2375. return(exit_status);
  2376. sampcnt = 0;
  2377. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2378. }
  2379. }
  2380. packet_phase = -packet_phase;
  2381. break;
  2382. case(2):
  2383. if(sloom) // Forces correct read-out of time-bar
  2384. dz->insams[0] = dz->iparam[SYNTH_DUR] * chans;
  2385. if(time >= steptimes[stepcnt]) { // If we've reached the next partials-change time
  2386. stepcnt++; // Advance to next vals
  2387. get_current_partial_vals(time,pvals,total_partialcnt,dz);
  2388. sort_partials_into_ascending_frq_order(total_partialcnt,pvals,sinptr,llev,rlev,onoff,lmost,origspl,splordr,dz);
  2389. for(n=0;n<total_partialcnt;n++) // Set any splice counters needed
  2390. splcntr[n] = origspl[n][stepcnt];
  2391. }
  2392. base_sampcnt = sampcnt;
  2393. for(n=0;n<total_partialcnt;n++) {
  2394. sampcnt = base_sampcnt;
  2395. if(onoff[n][stepcnt]) { // If partial is on
  2396. loindex = (int)floor(sinptr[n]); // Read from sintable, using partial-increment
  2397. hiindex = loindex + 1;
  2398. loval = sintab[loindex];
  2399. hival = sintab[hiindex];
  2400. valdiff = hival - loval;
  2401. timefrac = sinptr[n] - (double)loindex;
  2402. val = loval + (valdiff * timefrac);
  2403. level = read_level(n,time,dz); // Read corresponding level
  2404. indownsplice = 0;
  2405. if(splcntr[n] > 0) { // Get any splice contribution
  2406. if(splcntr[n] > splen) { // This indicates an OFF/ON splice
  2407. localspliceval = (double)(splcntr[n] - splen)/(double)splen;
  2408. indownsplice = 1; // Down-splice
  2409. } else {
  2410. localspliceval = (double)(splen - splcntr[n])/(double)splen;
  2411. indownsplice = 0; // Up-splice
  2412. }
  2413. val *= localspliceval; // Upfade, splcntr falling, splen-splcntr rising
  2414. splcntr[n]--; // Advance splicecnt towards zero
  2415. }
  2416. if(dz->vflag[SYN_SPACED]) { // If spatialisation, get spatial contributions
  2417. if(spacetyp > 0) {
  2418. if(indownsplice) {
  2419. pos = position[stepcnt-1];
  2420. switchpos = swpos[stepcnt-1];
  2421. spacebox_apply(pos,llev[n][stepcnt-1],chans,&l_most,&r_most,&valr,&vall,spacetyp);
  2422. } else {
  2423. pos = position[stepcnt];
  2424. switchpos = swpos[stepcnt];
  2425. spacebox_apply(pos,llev[n][stepcnt],chans,&l_most,&r_most,&valr,&vall,spacetyp);
  2426. }
  2427. valr = val * valr;
  2428. val = val * vall;
  2429. } else { // If spatialisation, get spatial contributions
  2430. valr = val * rlev[n][stepcnt];
  2431. val = val * llev[n][stepcnt];
  2432. }
  2433. } else
  2434. val = val * llev[n][stepcnt]; // Or just incorporate calculated atten for this element
  2435. if(dz->vflag[SYN_SPACED]) { // if spatialised, find rightmost channel from leftmost
  2436. if(spacetyp > 0) {
  2437. output_special_spatialisation_sample(obuf,sampcnt,switchpos,chans,val,valr,l_most,r_most,spacetyp);
  2438. sampcnt += chans;
  2439. } else {
  2440. rmost = (lmost[n][stepcnt] + 1) % chans;
  2441. for(k = 0;k< chans;k++) {
  2442. if(k == lmost[n][stepcnt]) // Add output only to the 2 relevant channels
  2443. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2444. else if(k == rmost)
  2445. obuf[sampcnt] = (float)(obuf[sampcnt] + valr);
  2446. sampcnt++;
  2447. }
  2448. }
  2449. } else { // If NOT spatialised, add output to all outchans
  2450. for(k = 0;k < chans;k++) {
  2451. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2452. sampcnt++;
  2453. }
  2454. }
  2455. } else { // Partial is OFF
  2456. if(splcntr[n] > 0) { // BUT IF its still a fade-out, Get any splice contribution
  2457. loindex = (int)floor(sinptr[n]);
  2458. hiindex = loindex + 1;
  2459. loval = sintab[loindex];
  2460. hival = sintab[hiindex];
  2461. valdiff = hival - loval;
  2462. timefrac = sinptr[n] - (double)loindex;
  2463. val = loval + (valdiff * timefrac);
  2464. level = read_level(n,time,dz);
  2465. localspliceval = (double)splcntr[n]/(double)splen; // Downfade, splcntr falling
  2466. val *= localspliceval;
  2467. splcntr[n]--; // Advance splicecnt towards zero
  2468. if(dz->vflag[SYN_SPACED]) { // If spatialisation, get spatial contributions FROM PREVIOUS STEP
  2469. if(spacetyp > 0) {
  2470. pos = position[stepcnt-1];
  2471. switchpos = swpos[stepcnt-1];
  2472. spacebox_apply(pos,llev[n][stepcnt-1],chans,&l_most,&r_most,&valr,&vall,spacetyp);
  2473. valr = val * valr;
  2474. val = val * vall;
  2475. } else { // If spatialisation, get spatial contributions
  2476. valr = val * rlev[n][stepcnt-1];
  2477. val = val * llev[n][stepcnt-1];
  2478. }
  2479. } else
  2480. val = val * llev[n][stepcnt-1];
  2481. if(dz->vflag[SYN_SPACED]) { // As fadeout of last sound, keep PREVIOUS STEP spatial coords
  2482. if(spacetyp > 0) {
  2483. output_special_spatialisation_sample(obuf,sampcnt,switchpos,chans,val,valr,l_most,r_most,spacetyp);
  2484. sampcnt += chans;
  2485. } else {
  2486. rmost = (lmost[n][stepcnt-1] + 1) % chans;
  2487. for(k = 0;k < chans;k++) {
  2488. if(k == lmost[n][stepcnt-1])
  2489. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2490. else if(k == rmost)
  2491. obuf[sampcnt] = (float)(obuf[sampcnt] + valr);
  2492. sampcnt++;
  2493. }
  2494. }
  2495. } else {
  2496. for(k = 0;k < chans;k++) {
  2497. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  2498. sampcnt++;
  2499. }
  2500. }
  2501. }
  2502. }
  2503. incr_sinptr(n,time,onehzincr,dz); // Track (modify if ness) the partial-incr value for this partial
  2504. }
  2505. if(instartsplice) { // Do big splice at start of output
  2506. sampcnt = base_sampcnt;
  2507. for(k = 0;k < chans;k++) {
  2508. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  2509. sampcnt++;
  2510. }
  2511. spliceval += spliceincr;
  2512. spliceval = min(spliceval,1.0);
  2513. } else if(inendsplice) { // Do big splice at end of output
  2514. sampcnt = base_sampcnt;
  2515. for(k = 0;k < chans;k++) {
  2516. obuf[sampcnt] = (float)(obuf[sampcnt] * spliceval);
  2517. sampcnt++;
  2518. }
  2519. spliceval -= spliceincr;
  2520. spliceval = max(spliceval,0.0);
  2521. }
  2522. sampcnt = base_sampcnt; // Normalise output
  2523. for(k = 0;k < chans;k++) {
  2524. obuf[sampcnt] = (float)(obuf[sampcnt] * normaliser);
  2525. sampcnt++;
  2526. }
  2527. if(sampcnt >= dz->buflen) { // Check if buffer full - write_samps and refresh
  2528. if((exit_status = write_samps(obuf,sampcnt,dz))<0)
  2529. return(exit_status);
  2530. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2531. sampcnt = 0;
  2532. }
  2533. total_samps_synthed += chans; // Find out if (still) in startsplice or endsplice
  2534. if(!inendsplice && (total_samps_synthed >= endsplicestart)) {
  2535. inendsplice = 1;
  2536. spliceval = 1.0;
  2537. }
  2538. if(instartsplice && (total_samps_synthed >= startspliceend))
  2539. instartsplice = 0;
  2540. break;
  2541. }
  2542. }
  2543. if(sampcnt) {
  2544. if((exit_status = write_samps(obuf,sampcnt,dz))<0)
  2545. return(exit_status);
  2546. }
  2547. return FINISHED;
  2548. }
  2549. /**************************** INCR_SINPTR ****************************/
  2550. void incr_sinptr(int n,double time,double onehzincr,dataptr dz)
  2551. {
  2552. int m;
  2553. double hival, loval, hitime, lotime, timediff, timefrac, valdiff, partialval, thisincr;
  2554. double *sinptr = dz->parray[(dz->itemcnt * 2) + 1];
  2555. double *thispartial = dz->parray[n];
  2556. m = 0;
  2557. while(thispartial[m] < time) {
  2558. m += 2;
  2559. if(m >= dz->ringsize)
  2560. break;
  2561. }
  2562. if(m==0)
  2563. partialval = thispartial[1];
  2564. else if(m < dz->ringsize) {
  2565. hival = thispartial[m+1];
  2566. loval = thispartial[m-1];
  2567. hitime = thispartial[m];
  2568. lotime = thispartial[m-2];
  2569. timediff = hitime - lotime;
  2570. timefrac = (time - lotime)/timediff;
  2571. valdiff = hival - loval;
  2572. partialval = loval + (valdiff * timefrac);
  2573. } else
  2574. partialval = thispartial[dz->ringsize-1];
  2575. // Convert partial numbers to table-increments
  2576. thisincr = partialval * onehzincr;
  2577. thisincr *= dz->param[SYNTH_FRQ];
  2578. sinptr[n] += thisincr;
  2579. if(sinptr[n] >= SYNTH_TABSIZE)
  2580. sinptr[n] -= (double)SYNTH_TABSIZE;
  2581. }
  2582. /**************************** GET_CURRENT_PARTIAL_VALS ****************************/
  2583. void get_current_partial_vals(double time,double *pvals,int partialcnt,dataptr dz)
  2584. {
  2585. int m, n;
  2586. double hival, loval, hitime, lotime, timediff, timefrac, valdiff, partialval;
  2587. double *thispartial;
  2588. for(n = 0;n < partialcnt;n++ ) {
  2589. thispartial = dz->parray[n];
  2590. m = 0;
  2591. while(thispartial[m] < time) {
  2592. m += 2;
  2593. if(m >= dz->ringsize)
  2594. break;
  2595. }
  2596. if(m==0)
  2597. partialval = thispartial[1];
  2598. else if(m < dz->ringsize) {
  2599. hival = thispartial[m+1];
  2600. loval = thispartial[m-1];
  2601. hitime = thispartial[m];
  2602. lotime = thispartial[m-2];
  2603. timediff = hitime - lotime;
  2604. timefrac = (time - lotime)/timediff;
  2605. valdiff = hival - loval;
  2606. partialval = loval + (valdiff * timefrac);
  2607. } else
  2608. partialval = thispartial[dz->ringsize-1];
  2609. pvals[n] = partialval;
  2610. }
  2611. }
  2612. /**************************** READ_LEVEL ****************************/
  2613. double read_level(int n,double time,dataptr dz)
  2614. {
  2615. int m;
  2616. double hival, loval, hitime, lotime, timediff, timefrac, valdiff, level;
  2617. double *thislevel = dz->parray[n + dz->itemcnt];
  2618. m = 0;
  2619. while(thislevel[m] < time) {
  2620. m += 2;
  2621. if(m >= dz->ringsize)
  2622. break;
  2623. }
  2624. if(m==0) {
  2625. level = thislevel[1];
  2626. } else if(m < dz->ringsize) {
  2627. hival = thislevel[m+1];
  2628. loval = thislevel[m-1];
  2629. hitime = thislevel[m];
  2630. lotime = thislevel[m-2];
  2631. timediff = hitime - lotime;
  2632. timefrac = (time - lotime)/timediff;
  2633. valdiff = hival - loval;
  2634. level = loval + (valdiff * timefrac);
  2635. } else {
  2636. level = thislevel[dz->ringsize-1];
  2637. }
  2638. return level;
  2639. }
  2640. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  2641. int handle_the_special_data(char *str,dataptr dz)
  2642. {
  2643. double dummy = 0.0, lasttime = 0.0, lastpartial = 1.0, maxval = 0.0, normaliser;
  2644. int entrycnt = 0, partialcnt, n, timepos, valpos, pno_cnt, lev_cnt = 0;
  2645. int zz, nupno_cnt = 0, nulev_cnt,lstart, m, k, nn, mm;
  2646. double *sortptr;
  2647. int totalpartials = 0, tablecnt, lno_cnt;
  2648. FILE *fp;
  2649. int cnt, linecnt;
  2650. char temp[8000], *p;
  2651. if((fp = fopen(str,"r"))==NULL) {
  2652. sprintf(errstr,"Cannot open file %s to read times.\n",str);
  2653. return(DATA_ERROR);
  2654. }
  2655. linecnt = 0;
  2656. while(fgets(temp,8000,fp)!=NULL) {
  2657. p = temp;
  2658. while(isspace(*p))
  2659. p++;
  2660. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  2661. continue;
  2662. cnt = 0;
  2663. while(get_float_from_within_string(&p,&dummy)) {
  2664. switch(cnt) {
  2665. case(0):
  2666. if(linecnt == 0) {
  2667. if(dummy != 0) {
  2668. sprintf(errstr,"First time in partials data (%lf) must be zero.\n",dummy);
  2669. return(DATA_ERROR);
  2670. } else
  2671. lasttime = dummy;
  2672. } else {
  2673. if(dummy <= lasttime) {
  2674. sprintf(errstr,"Times do not advance at line %d in partials data.\n",linecnt+1);
  2675. return(DATA_ERROR);
  2676. }
  2677. }
  2678. break;
  2679. default:
  2680. if(ODD(cnt)) { // ODD entries, partial numbers
  2681. if(dummy < 1.0) {
  2682. sprintf(errstr,"Invalid partial (%lf) (less than 1) on line %d.\n",dummy,linecnt+1);
  2683. return(DATA_ERROR);
  2684. }
  2685. if(cnt == 1) {
  2686. if(dz->mode == 0 && dummy != 1.0) {
  2687. sprintf(errstr,"Invalid first partial (%lf) (must be 1 in this tone-generation mode)\n",dummy);
  2688. return(DATA_ERROR);
  2689. }
  2690. lastpartial = dummy;
  2691. }
  2692. else {
  2693. if(dummy <= lastpartial) {
  2694. sprintf(errstr,"Partial numbers do not increase through line %d.\n",linecnt+1);
  2695. return(DATA_ERROR);
  2696. }
  2697. lastpartial = dummy;
  2698. }
  2699. } else // EVEN values are levels, which can be -ve (inverted phase)
  2700. maxval = max(maxval,fabs(dummy));
  2701. break;
  2702. }
  2703. cnt++;
  2704. }
  2705. if(cnt < 3 || EVEN(cnt)) {
  2706. sprintf(errstr,"Invalid number of entries (%d) on line %d\n",cnt,linecnt+1);
  2707. return(DATA_ERROR);
  2708. }
  2709. if(linecnt == 0)
  2710. entrycnt = cnt;
  2711. else if(cnt != entrycnt) {
  2712. sprintf(errstr,"Line %d has different number of entries (%d) to previous lines which have (%d)\n",linecnt+1,cnt,entrycnt);
  2713. return(DATA_ERROR);
  2714. }
  2715. linecnt++;
  2716. }
  2717. if(linecnt == 0) {
  2718. sprintf(errstr,"No data found in partials data file.\n");
  2719. return(DATA_ERROR);
  2720. }
  2721. if(flteq(maxval,0.0)) {
  2722. sprintf(errstr,"No significant level found in partials data file.\n");
  2723. return(DATA_ERROR);
  2724. }
  2725. normaliser = 1.0/maxval;
  2726. partialcnt = (entrycnt - 1)/2;
  2727. if(dz->mode == 2) {
  2728. /*
  2729. * MODE 2 arrays
  2730. * mpcnt = maxpartial cnt (partials + all transpositions) | | |
  2731. * | current
  2732. * | frqs
  2733. * parray |----------|----------|-|-|-----------------|-----------------|-|-|-|
  2734. * | tvarying pno+plevel |s|s| left_level | right-level step|p|
  2735. * | (Mpcnt*2) |i|i| mpcnt | mpcnt timeso|
  2736. * | |n|n| | | | |s|
  2737. * address 0 mpcnt*2| |p|(mpcnt*2)+2 |(mpcnt*3)+2 | (mpcnt*4)+3
  2738. * | | |t| | (mpcnt*4)+2
  2739. * | | |r| | | | (mpcnt*4)+4
  2740. * lengths | linelen of srcdata | | | maxsteps | maxsteps | |m|
  2741. * |s|t| |t|p|
  2742. * (slen = sintablen) |l|o| |o|c|
  2743. * (totl = estimate of no |e|t| |t|n|
  2744. * of timesteps used) |n|l| |l|t|
  2745. */
  2746. totalpartials = partialcnt * dz->iparam[SYNTH_MAX];
  2747. dz->array_cnt = (totalpartials * 2) + 2;// An array for every partial-and-partial-transposition, every pandp-level,
  2748. // and Sin-table + sintab-incr-pointers
  2749. dz->temp_sampsize = dz->array_cnt;
  2750. dz->array_cnt += (totalpartials * 2) + 3; // An array for the left and right level of every partial-and-partial-transposition.
  2751. // and One array for the steptimes, and one array for the frqs of partials at current-time
  2752. dz->itemcnt = totalpartials; // Array for every partial-pno and partial-level + Array for position at every step.
  2753. } else {
  2754. dz->array_cnt = (partialcnt * 2) + 5; // An array for every partial-pno, every partial-level,
  2755. // + snd-sintable + sintab-incr-pointers + packet envelope + 2 packet-envelope-temp-arrays
  2756. dz->itemcnt = partialcnt; // Array for every partial-pno and partial-level.
  2757. }
  2758. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  2759. sprintf(errstr,"INSUFFICIENT MEMORY to create partial data arrays.\n");
  2760. return(MEMORY_ERROR);
  2761. }
  2762. if(dz->mode == 2)
  2763. zz = totalpartials * 2;
  2764. else
  2765. zz = partialcnt * 2;
  2766. for(n=0;n <zz;n++) { // 2 entries (time and value) for every line in the data.
  2767. if((dz->parray[n] = (double *)malloc((linecnt * 2) * sizeof(double)))==NULL) {
  2768. sprintf(errstr,"INSUFFICIENT MEMORY to store partial data.\n");
  2769. return(MEMORY_ERROR);
  2770. }
  2771. }
  2772. fseek(fp,0,0);
  2773. timepos = 0; // Pointer to time-values in all arrays
  2774. valpos = 1; // Pointer to val-at-time in all arrays
  2775. pno_cnt = 0; // Pointer to partial-pno table
  2776. lstart = partialcnt; // Start of partial-level table
  2777. if(dz->mode == 2)
  2778. lstart *= dz->iparam[SYNTH_MAX];
  2779. while(fgets(temp,8000,fp)!=NULL) {
  2780. p = temp;
  2781. if(*p == ';') // Allow comments in file
  2782. continue;
  2783. cnt = 0;
  2784. while(get_float_from_within_string(&p,&dummy)) {
  2785. switch(cnt) {
  2786. case(0):
  2787. for(n=0;n <partialcnt;n++) // Put time in all pno arrays
  2788. dz->parray[n][timepos] = dummy;
  2789. for(m = lstart,n=0;n <partialcnt;n++,m++)// Put time in all level arrays
  2790. dz->parray[m][timepos] = dummy;
  2791. pno_cnt = 0; // Point to start of pnos, and levels
  2792. lev_cnt = lstart;
  2793. break;
  2794. default:
  2795. if(ODD(cnt)) // Put pno in appropriate pno-array
  2796. dz->parray[pno_cnt++][valpos] = dummy;
  2797. else // Put level in appropriate level-array
  2798. dz->parray[lev_cnt++][valpos] = dummy * normaliser;
  2799. break;
  2800. }
  2801. cnt++;
  2802. }
  2803. if(cnt) {
  2804. timepos += 2; // Advance pointers in pno and level tables
  2805. valpos +=2;
  2806. }
  2807. }
  2808. if(fclose(fp)<0) {
  2809. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",str);
  2810. fflush(stdout);
  2811. }
  2812. if(dz->mode == 2) {
  2813. dz->scalefact = dz->parray[partialcnt-1][1]; // Remember the original range
  2814. tablecnt = partialcnt; // Total number of original partial-no (or level) tables
  2815. entrycnt = timepos; // Total number of entries in each table
  2816. if(dz->iparam[SYNTH_MAX] > 1) {
  2817. // COPY ORIGINAL PARTIAL-NO AND LEVEL TABLES INTO HIGHER OCTAVES
  2818. nupno_cnt = partialcnt; // Start of new partial-transpositions tables
  2819. nulev_cnt = lstart + partialcnt;// Pointer to new levels tables
  2820. for(n=1;n<dz->iparam[SYNTH_MAX];n++) { // For every additional 8va
  2821. for(pno_cnt=0,lno_cnt=lstart;pno_cnt<tablecnt;pno_cnt++,lno_cnt++) {// For every original partial-table, and level-table
  2822. for(k=0;k<entrycnt;k+=2) { // For every entry in original tables
  2823. dz->parray[nupno_cnt][k] = dz->parray[pno_cnt][k]; // At same time
  2824. dz->parray[nupno_cnt][k+1] = (dz->parray[pno_cnt][k+1]) * (n+1); // Create new table, partials up n octs
  2825. dz->parray[nulev_cnt][k] = dz->parray[lno_cnt][k]; // At same time
  2826. dz->parray[nulev_cnt][k+1] = dz->parray[lno_cnt][k+1]; // Create new table with same levels
  2827. }
  2828. nupno_cnt++;
  2829. nulev_cnt++;
  2830. }
  2831. }
  2832. // SORT PARTIAL-NOS INTO ASCENDING ORDER
  2833. for(n = 0, m = lstart; n < nupno_cnt-1; n++,m++) {
  2834. for(nn = n+1, mm = m+1; nn < nupno_cnt;nn++, mm++) {
  2835. if(dz->parray[nn][1] < dz->parray[n][1]) { // Sort of first partialval in array
  2836. sortptr = dz->parray[nn];
  2837. dz->parray[nn] = dz->parray[n];
  2838. dz->parray[n] = sortptr;
  2839. sortptr = dz->parray[mm];
  2840. dz->parray[mm] = dz->parray[m];
  2841. dz->parray[m] = sortptr;
  2842. }
  2843. }
  2844. }
  2845. }
  2846. }
  2847. dz->ringsize = linecnt * 2; // Store lengths of partial tables (1 time and 1 value entry from each dataline)
  2848. return(FINISHED);
  2849. }
  2850. /**************************** CREATE_SYNTHESIZER_SNDBUFS ****************************/
  2851. int create_synthesizer_sndbufs(dataptr dz)
  2852. {
  2853. int n, exit_status;
  2854. int bigbufsize;
  2855. int framesize, wavelen, segsize;
  2856. double frqmin;
  2857. framesize = F_SECSIZE * dz->infile->channels;
  2858. if(dz->mode == 2)
  2859. framesize = F_SECSIZE * dz->iparam[SYNTH_CHANS];
  2860. if(dz->mode == 3) {
  2861. if(dz->brksize[SYNTH_FRQ]) {
  2862. if((exit_status = get_minvalue_in_brktable(&frqmin,SYNTH_FRQ,dz))<0)
  2863. return exit_status;
  2864. } else
  2865. frqmin = dz->param[SYNTH_FRQ];
  2866. wavelen = (int)ceil((double)dz->iparam[SYNTHSRAT]/frqmin);
  2867. segsize = wavelen/framesize;
  2868. if(segsize + framesize != wavelen)
  2869. segsize++;
  2870. wavelen = segsize * framesize;
  2871. dz->spikelen = dz->iparam[SYNTH_ATK] + dz->iparam[SYNTH_DEC] + 1;
  2872. dz->buflen = wavelen + wavelen + dz->spikelen;
  2873. bigbufsize = dz->buflen * sizeof(float);
  2874. if((dz->bigbuf = (float *)malloc(bigbufsize)) == NULL) {
  2875. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  2876. return(PROGRAM_ERROR);
  2877. }
  2878. dz->bufcnt = 3;
  2879. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  2880. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  2881. return(MEMORY_ERROR);
  2882. }
  2883. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  2884. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  2885. return(MEMORY_ERROR);
  2886. }
  2887. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf;
  2888. dz->sbufptr[1] = dz->sampbuf[1] = dz->bigbuf + wavelen;
  2889. dz->sbufptr[2] = dz->sampbuf[2] = dz->sampbuf[1] + wavelen;
  2890. dz->sampbuf[3] = dz->sampbuf[2] + dz->spikelen;
  2891. dz->buflen = wavelen; // This is size of outbuf
  2892. return FINISHED;
  2893. }
  2894. dz->bufcnt = 1;
  2895. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  2896. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  2897. return(MEMORY_ERROR);
  2898. }
  2899. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  2900. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  2901. return(MEMORY_ERROR);
  2902. }
  2903. bigbufsize = (int)Malloc(-1);
  2904. bigbufsize /= dz->bufcnt;
  2905. if(bigbufsize <=0)
  2906. bigbufsize = framesize * sizeof(float);
  2907. dz->buflen = bigbufsize / sizeof(float);
  2908. dz->buflen = (dz->buflen / framesize) * framesize;
  2909. bigbufsize = dz->buflen * sizeof(float);
  2910. if((dz->bigbuf = (float *)malloc(bigbufsize * dz->bufcnt)) == NULL) {
  2911. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  2912. return(PROGRAM_ERROR);
  2913. }
  2914. for(n=0;n<dz->bufcnt;n++)
  2915. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  2916. dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  2917. return(FINISHED);
  2918. }
  2919. /****************************** GET_THE_MODE_FROM_CMDLINE *********************************/
  2920. int get_the_mode_from_cmdline(char *str,dataptr dz)
  2921. {
  2922. char temp[200], *p;
  2923. if(sscanf(str,"%s",temp)!=1) {
  2924. fprintf(stderr,"Cannot read mode of program.\n");
  2925. return(USAGE_ONLY);
  2926. }
  2927. p = temp + strlen(temp) - 1;
  2928. while(p >= temp) {
  2929. if(!isdigit(*p)) {
  2930. fprintf(stderr,"Invalid mode of program entered.\n");
  2931. return(USAGE_ONLY);
  2932. }
  2933. p--;
  2934. }
  2935. if(sscanf(str,"%d",&dz->mode)!=1) {
  2936. fprintf(stderr,"Cannot read mode of program.\n");
  2937. return(USAGE_ONLY);
  2938. }
  2939. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  2940. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  2941. return(USAGE_ONLY);
  2942. }
  2943. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  2944. return(FINISHED);
  2945. }
  2946. /**************************** GENERATE_PACKET_ENVELOPE *************************/
  2947. int generate_packet_envelope (dataptr dz)
  2948. {
  2949. int n, halftabsize = TREMOLO_TABSIZE/2;
  2950. int isneg = 0, tablopos, tabhipos, cosarray = (dz->itemcnt * 2) + 2;
  2951. double *costab, *temptab, *origtab, diff, tabrem, tabincr, lotabincr, hitabincr, readpos, frac;
  2952. if((dz->parray[cosarray] = (double *)malloc((TREMOLO_TABSIZE + 1) * sizeof(double)))==NULL) {
  2953. sprintf(errstr,"INSUFFICIENT MEMORY for sine table.\n");
  2954. return(MEMORY_ERROR);
  2955. }
  2956. costab = dz->parray[cosarray];
  2957. if((dz->parray[cosarray+1] = (double *)malloc((TREMOLO_TABSIZE + 1) * sizeof(double)))==NULL) {
  2958. sprintf(errstr,"INSUFFICIENT MEMORY for sine table.\n");
  2959. return(MEMORY_ERROR);
  2960. }
  2961. temptab = dz->parray[cosarray + 1];
  2962. if((dz->parray[cosarray+2] = (double *)malloc((TREMOLO_TABSIZE + 1) * sizeof(double)))==NULL) {
  2963. sprintf(errstr,"INSUFFICIENT MEMORY for sine table.\n");
  2964. return(MEMORY_ERROR);
  2965. }
  2966. origtab = dz->parray[cosarray + 2];
  2967. for(n=0;n<TREMOLO_TABSIZE;n++) {
  2968. costab[n] = cos(PI * 2.0 * ((double)n/(double)TREMOLO_TABSIZE));
  2969. costab[n] += 1.0;
  2970. costab[n] /= 2.0;
  2971. costab[n] = 1.0 - costab[n];
  2972. origtab[n] = costab[n];
  2973. }
  2974. costab[n] = 0.0; /* wrap around point */
  2975. origtab[n] = 0.0; /* wrap around point */
  2976. if(!dz->brksize[SYNTH_SQZ] && !dz->brksize[SYNTH_CTR]) {
  2977. if(flteq(dz->param[SYNTH_SQZ],1.0)) {
  2978. for(n=0;n<=TREMOLO_TABSIZE;n++)
  2979. temptab[n] = origtab[n];
  2980. } else {
  2981. for(n=0;n<=TREMOLO_TABSIZE;n++)
  2982. temptab[n] = pow(origtab[n],dz->param[SYNTH_SQZ]);
  2983. }
  2984. if(flteq(dz->param[SYNTH_CTR],1.0)) {
  2985. for(n=0;n<=TREMOLO_TABSIZE;n++)
  2986. costab[n] = temptab[n];
  2987. } else {
  2988. if(dz->param[SYNTH_CTR] < 0.0) {
  2989. frac = 1.0 + dz->param[SYNTH_CTR];
  2990. isneg = 1;
  2991. } else
  2992. frac = 1.0 - dz->param[SYNTH_CTR];
  2993. if(isneg) {
  2994. lotabincr = 1.0/frac;
  2995. hitabincr = 1.0/(2.0 - frac);
  2996. } else {
  2997. lotabincr = 1.0/(2.0 - frac);
  2998. hitabincr = 1.0/frac;
  2999. }
  3000. readpos = 0;
  3001. tabincr = lotabincr;
  3002. for(n=0;n<TREMOLO_TABSIZE;n++) {
  3003. if(readpos >= halftabsize) {
  3004. tabincr = hitabincr;
  3005. }
  3006. tablopos = (int)floor(readpos);
  3007. tabhipos = min(tablopos + 1,TREMOLO_TABSIZE);
  3008. tabrem = readpos - (double)tablopos;
  3009. diff = temptab[tabhipos] - temptab[tablopos];
  3010. costab[n] = temptab[tablopos] + (diff * tabrem);
  3011. readpos += tabincr;
  3012. }
  3013. }
  3014. }
  3015. return(FINISHED);
  3016. }
  3017. /**************************** MODIFY_PACKET_ENVELOPE *************************/
  3018. int modify_packet_envelope (dataptr dz)
  3019. {
  3020. int n, halftabsize = TREMOLO_TABSIZE/2;
  3021. int isneg = 0, tablopos, tabhipos, cosarray = (dz->itemcnt * 2) + 2;
  3022. double *costab, *temptab, *origtab, diff, tabrem, tabincr, lotabincr, hitabincr, readpos, frac;
  3023. costab = dz->parray[cosarray];
  3024. temptab = dz->parray[cosarray + 1];
  3025. origtab = dz->parray[cosarray + 2];
  3026. if(flteq(dz->param[SYNTH_SQZ],1.0)) {
  3027. for(n=0;n<=TREMOLO_TABSIZE;n++)
  3028. temptab[n] = origtab[n];
  3029. } else {
  3030. for(n=0;n<=TREMOLO_TABSIZE;n++)
  3031. temptab[n] = pow(origtab[n],dz->param[SYNTH_SQZ]);
  3032. }
  3033. if(flteq(dz->param[SYNTH_CTR],1.0)) {
  3034. for(n=0;n<=TREMOLO_TABSIZE;n++)
  3035. costab[n] = temptab[n];
  3036. } else {
  3037. if(dz->param[SYNTH_CTR] < 0.0) {
  3038. frac = 1.0 + dz->param[SYNTH_CTR];
  3039. isneg = 1;
  3040. } else
  3041. frac = 1.0 - dz->param[SYNTH_CTR];
  3042. if(isneg) {
  3043. lotabincr = 1.0/frac;
  3044. hitabincr = 1.0/(2.0 - frac);
  3045. } else {
  3046. lotabincr = 1.0/(2.0 - frac);
  3047. hitabincr = 1.0/frac;
  3048. }
  3049. readpos = 0;
  3050. tabincr = lotabincr;
  3051. for(n=0;n<TREMOLO_TABSIZE;n++) {
  3052. if(readpos >= halftabsize) {
  3053. tabincr = hitabincr;
  3054. }
  3055. tablopos = (int)floor(readpos);
  3056. tabhipos = min(tablopos + 1,TREMOLO_TABSIZE);
  3057. tabrem = readpos - (double)tablopos;
  3058. diff = temptab[tabhipos] - temptab[tablopos];
  3059. costab[n] = temptab[tablopos] + (diff * tabrem);
  3060. readpos += tabincr;
  3061. }
  3062. }
  3063. return(FINISHED);
  3064. }
  3065. /**************************** READ_PACKET_ENVELOPE *************************/
  3066. double read_packet_envelope(int kk,double incr,dataptr dz)
  3067. {
  3068. double *costab, tabpos, tabrem, diff, envv;
  3069. int tablopos, tabhipos, cosarray = (dz->itemcnt * 2) + 2;
  3070. costab = dz->parray[cosarray];
  3071. tabpos = (double)kk * incr;
  3072. tablopos = (int)floor(tabpos);
  3073. tabhipos = min(tablopos + 1,TREMOLO_TABSIZE);
  3074. tabrem = tabpos - (double)tablopos;
  3075. diff = costab[tabhipos] - costab[tablopos];
  3076. envv = costab[tablopos] + (diff * tabrem);
  3077. return envv;
  3078. }
  3079. /*********************** RNDINTPERM ************************/
  3080. void rndintperm(int *perm,int cnt)
  3081. {
  3082. int n,t,k;
  3083. memset((char *)perm,0,cnt * sizeof(int));
  3084. for(n=0;n<cnt;n++) {
  3085. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  3086. if(t==n) {
  3087. for(k=n;k>0;k--)
  3088. perm[k] = perm[k-1];
  3089. perm[0] = n;
  3090. } else {
  3091. for(k=n;k>t;k--)
  3092. perm[k] = perm[k-1];
  3093. perm[t] = n;
  3094. }
  3095. }
  3096. }
  3097. /************************************ PANCALC *******************************/
  3098. void pancalc(double position,double *leftgain,double *rightgain)
  3099. {
  3100. int dirflag;
  3101. double temp;
  3102. double relpos;
  3103. double reldist, invsquare;
  3104. if(position < 0.0)
  3105. dirflag = SIGNAL_TO_LEFT; /* signal on left */
  3106. else
  3107. dirflag = SIGNAL_TO_RIGHT;
  3108. if(position < 0)
  3109. relpos = -position;
  3110. else
  3111. relpos = position;
  3112. if(relpos <= 1.0){ /* between the speakers */
  3113. temp = 1.0 + (relpos * relpos);
  3114. reldist = ROOT2 / sqrt(temp);
  3115. temp = (position + 1.0) / 2.0;
  3116. *rightgain = temp * reldist;
  3117. *leftgain = (1.0 - temp ) * reldist;
  3118. } else { /* outside the speakers */
  3119. temp = (relpos * relpos) + 1.0;
  3120. reldist = sqrt(temp) / ROOT2; /* relative distance to source */
  3121. invsquare = 1.0 / (reldist * reldist);
  3122. if(dirflag == SIGNAL_TO_LEFT){
  3123. *leftgain = invsquare;
  3124. *rightgain = 0.0;
  3125. } else { /* SIGNAL_TO_RIGHT */
  3126. *rightgain = invsquare;
  3127. *leftgain = 0;
  3128. }
  3129. }
  3130. }
  3131. /************************************ SORT_PARTIALS_INTO_ASCENDING_FRQ_ORDER *******************************/
  3132. void sort_partials_into_ascending_frq_order(int total_partialcnt,double *pvals,double *sinptr,double **llev,double **rlev,int **onoff,int **lmost,int **origspl,int *splordr,dataptr dz)
  3133. {
  3134. double *sortptr, temp;
  3135. int n, m, nn, mm, itemp;
  3136. int *iptr;
  3137. for(n = 0, m = total_partialcnt; n < total_partialcnt-1; n++,m++) { // m indexes levels
  3138. for(nn = n+1, mm = m+1; nn < total_partialcnt;nn++, mm++) {
  3139. if(pvals[nn] < pvals[n]) { // Sort on partialval
  3140. // Shuffle arrays so they're in ascending frq order, of CURRENT frqs
  3141. sortptr = dz->parray[nn];
  3142. dz->parray[nn] = dz->parray[n];
  3143. dz->parray[n] = sortptr;
  3144. sortptr = dz->parray[mm];
  3145. dz->parray[mm] = dz->parray[m];
  3146. dz->parray[m] = sortptr;
  3147. // Shuffle associated sinptrs
  3148. temp = sinptr[nn];
  3149. sinptr[nn] = sinptr[n];
  3150. sinptr[n] = temp;
  3151. // Shuffle associated (left-)level pointers
  3152. sortptr = llev[nn];
  3153. llev[nn] = llev[n];
  3154. llev[n] = sortptr;
  3155. // Shuffle associated right-level pointers
  3156. sortptr = rlev[nn];
  3157. rlev[nn] = rlev[n];
  3158. rlev[n] = sortptr;
  3159. // Shuffle associated onoff flags
  3160. iptr = onoff[nn];
  3161. onoff[nn] = onoff[n];
  3162. onoff[n] = iptr;
  3163. // Shuffle associated lmost-spkr info
  3164. iptr = lmost[nn];
  3165. lmost[nn] = lmost[n];
  3166. lmost[n] = iptr;
  3167. // Shuffle associated splicectr origins
  3168. iptr = origspl[nn];
  3169. origspl[nn] = origspl[n];
  3170. origspl[n] = iptr;
  3171. // Finally swap frqs into correct order
  3172. temp = pvals[nn];
  3173. pvals[nn] = pvals[n];
  3174. pvals[n] = temp;
  3175. // And keep track of reordering, for 2nd pass
  3176. itemp = splordr[nn];
  3177. splordr[nn] = splordr[n];
  3178. splordr[n] = itemp;
  3179. }
  3180. }
  3181. }
  3182. }
  3183. /************************************ RESORT_PARTIALS_INTO_ORIGINAL_FRQ_ORDER *******************************/
  3184. void resort_partials_into_original_frq_order(int total_partialcnt,double *pvals,double *sinptr,double **llev,double **rlev,int **onoff,int **lmost,int **origspl,int *splordr,dataptr dz)
  3185. {
  3186. double *sortptr, temp;
  3187. int n, m, nn, mm;
  3188. int *iptr;
  3189. for(n = 0, m = total_partialcnt; n < total_partialcnt-1; n++,m++) { // m indexes levels
  3190. for(nn = n+1, mm = m+1; nn < total_partialcnt;nn++, mm++) {
  3191. if(splordr[nn] < splordr[n]) { // Sort on original order value
  3192. // Shuffle arrays so they're in original order
  3193. sortptr = dz->parray[nn];
  3194. dz->parray[nn] = dz->parray[n];
  3195. dz->parray[n] = sortptr;
  3196. sortptr = dz->parray[mm];
  3197. dz->parray[mm] = dz->parray[m];
  3198. dz->parray[m] = sortptr;
  3199. // Shuffle associated sinptrs
  3200. temp = sinptr[nn];
  3201. sinptr[nn] = sinptr[n];
  3202. sinptr[n] = temp;
  3203. // Shuffle associated (left-)level pointers
  3204. sortptr = llev[nn];
  3205. llev[nn] = llev[n];
  3206. llev[n] = sortptr;
  3207. // Shuffle associated right-level pointers
  3208. sortptr = rlev[nn];
  3209. rlev[nn] = rlev[n];
  3210. rlev[n] = sortptr;
  3211. // Shuffle associated onoff flags
  3212. iptr = onoff[nn];
  3213. onoff[nn] = onoff[n];
  3214. onoff[n] = iptr;
  3215. // Shuffle associated lmost-spkr info
  3216. iptr = lmost[nn];
  3217. lmost[nn] = lmost[n];
  3218. lmost[n] = iptr;
  3219. // Shuffle associated splicectr origins
  3220. iptr = origspl[nn];
  3221. origspl[nn] = origspl[n];
  3222. origspl[n] = iptr;
  3223. // Finally swap frqs into correct order
  3224. temp = pvals[nn];
  3225. pvals[nn] = pvals[n];
  3226. pvals[n] = temp;
  3227. }
  3228. }
  3229. }
  3230. }
  3231. /**************************************** XCLUSIVE **************************************
  3232. *
  3233. * Resort an existing permuutation (of partials chosen)
  3234. * so they already ON partials occur after all the corrently-OFF partials
  3235. */
  3236. void xclusive(int *perm,int *permon,int *permoff,int max_partials_cnt,int partials_in_play, int **onoff,int stepcnt)
  3237. {
  3238. int permoncnt = 0, permoffcnt = 0, n, ptl;
  3239. if(partials_in_play == max_partials_cnt)
  3240. return;
  3241. for(n = 0;n < max_partials_cnt;n++) {
  3242. ptl = perm[n];
  3243. if(onoff[ptl][stepcnt]) // If this partial is already ON
  3244. permon[permoncnt++] = ptl; // Store the ON-partials, in order they were in initial perm
  3245. else
  3246. permoff[permoffcnt++] = ptl; // If this partial is OFF
  3247. } // Store the OFF-partials, in order they were in initial perm
  3248. for(n=0;n<permoffcnt;n++) // Place the OFF partials first in the permlist,
  3249. perm[n] = permoff[n]; // But otherwise preserving perm order.
  3250. while(n < max_partials_cnt) {
  3251. perm[n] = permon[n];
  3252. n++;
  3253. }
  3254. }
  3255. /**************************************** EMERGEPOS **************************************
  3256. *
  3257. * Find spatial position, where image emerging from single channel to gradually fill all channels
  3258. */
  3259. double emergepos(int emergchan,int chans,double time,double timespan)
  3260. {
  3261. double frac, chanspan, pos, lmost;
  3262. emergchan--;
  3263. frac = time/timespan; // Fraction of emerge-time covered
  3264. if(frac < 0.33)
  3265. chanspan = 0;
  3266. else {
  3267. frac = pow((frac - 0.33),1.5);
  3268. chanspan = (double)chans * frac; // Fraction of total-channels available
  3269. }
  3270. pos = drand48() * chanspan; // Position randomly within chanspan
  3271. lmost = (double)emergchan - (chanspan/2.0); // Find leftmost position (relative to emergence chan)
  3272. pos += lmost; // Find true position
  3273. if(pos < 0.0) // Adjust for %N chans
  3274. pos += (double)chans;
  3275. else if(pos >= chans) // Adjust for %N chans
  3276. pos -= (double)chans;
  3277. return pos;
  3278. }
  3279. /**************************************** EMERGEPOS **************************************
  3280. *
  3281. * Find spatial position, where image converging to single channel from all channels
  3282. */
  3283. double convergepos(int converchan,int chans,double time,double convergetime,double dur)
  3284. {
  3285. double frac, chanspan, pos, lmost; // Fraction of converge-time covered
  3286. int ipos;
  3287. converchan--;
  3288. frac = (time - convergetime)/(dur - convergetime);
  3289. frac = 1.0 - frac; // Amount of convergence
  3290. if(frac < 0.33)
  3291. chanspan = 0;
  3292. else {
  3293. frac = pow((frac - 0.33),2.0);
  3294. chanspan = (double)chans * frac; // Fraction of total-channels available
  3295. }
  3296. pos = drand48() * chanspan; // Position randomly within chanspan
  3297. ipos = (int)round(pos/0.1);
  3298. pos = ipos * 0.1;
  3299. lmost = (double)converchan - (chanspan/2.0);// Find leftmost position (relative to convergence chan)
  3300. pos += lmost; // Find true position
  3301. if(pos < 0.0) // Adjust for %N chans
  3302. pos += (double)chans;
  3303. else if(pos >= chans) // Adjust for %N chans
  3304. pos -= (double)chans;
  3305. return pos;
  3306. }
  3307. /**************************************** SPACEBOX **************************************/
  3308. void spacebox(double *pos, int *switchpos, double posstep, int chans, int spacetyp, int configno, int configcnt,int *superperm)
  3309. {
  3310. switch(spacetyp) {
  3311. case(SB_LRRAND): // Alternate Left and Right sides, random position
  3312. *pos = chans/2 * drand48(); // Random choice of half of chan positions
  3313. if(*switchpos) // If switch on, put in 2nd half
  3314. *pos += chans/2;
  3315. *switchpos = -(*switchpos);
  3316. break;
  3317. case(SB_FBRAND): // Alternate Front and Back sides, random position
  3318. *pos = chans/2 * drand48(); // Simil for front and back
  3319. if(*switchpos) {
  3320. *pos += 2;
  3321. if(*pos >= chans)
  3322. *pos -= chans;
  3323. } else {
  3324. *pos += 6;
  3325. if(*pos >= chans)
  3326. *pos -= chans;
  3327. }
  3328. *switchpos = -(*switchpos);
  3329. break;
  3330. case(SB_ROTATE): // Rotating clockwise or anticlockwise
  3331. *pos += posstep;
  3332. if(*pos >= chans)
  3333. *pos -= chans;
  3334. else if(*pos < 0.0)
  3335. *pos += chans;
  3336. break;
  3337. case(SB_SUPERSPACE):
  3338. case(SB_SUPERSPACE2):
  3339. case(SB_SUPERSPACE3):
  3340. case(SB_SUPERSPACE4): // Get item in current permutaion of possibilities
  3341. *switchpos = superperm[configcnt];
  3342. break;
  3343. case(SB_LR): // Alternate all-left/all-right Switch between the 2 alternatives
  3344. case(SB_FB): // Alternate all-back/all-front
  3345. case(SB_FRAMESWITCH): // Switch all-square/all-diamond
  3346. *switchpos = !(*switchpos);
  3347. break;
  3348. case(SB_TRIROT1): // Rotate triangle formed by spkrs 2-apart clockwise
  3349. case(SB_TRIROT2): // Rotate triangle formed by spkrs 3-apart clockwise
  3350. (*switchpos)++; // Advance apex of triangle
  3351. if(*switchpos >= chans)
  3352. *switchpos -= chans;
  3353. break;
  3354. case(SB_ANTITRIROT1): // Rotate triangle formed by spkrs 2-apart anticlockwise
  3355. case(SB_ANTITRIROT2): // Rotate triangle formed by spkrs 2-apart anticlockwise
  3356. (*switchpos)--; // Regress apex of triangle
  3357. if(*switchpos < chans)
  3358. *switchpos += chans;
  3359. break;
  3360. }
  3361. }
  3362. /**************************************** SPACEBOX_APPLY **************************************/
  3363. void spacebox_apply(double pos, double lev,int chans,int *lmost, int *rmost,double *rlev,double *llev,int spacetyp)
  3364. {
  3365. double leftgain, rightgain;
  3366. switch(spacetyp) {
  3367. case(SB_LRRAND): // These options use true stereo between adjacent speakers
  3368. case(SB_FBRAND): // Find levels and left/right lspkrs
  3369. case(SB_ROTATE):
  3370. *lmost = (int)floor(pos);
  3371. pos -= (double)(*lmost);
  3372. pos = (pos * 2.0) - 1.0;
  3373. pancalc(pos,&leftgain,&rightgain);
  3374. *rlev = lev * rightgain;
  3375. *llev = lev * leftgain;
  3376. *rmost = (*lmost + 1) % chans;
  3377. break;
  3378. case(SB_LR):
  3379. case(SB_FB):
  3380. case(SB_TRIROT1):
  3381. case(SB_ANTITRIROT1):
  3382. case(SB_TRIROT2):
  3383. case(SB_ANTITRIROT2):
  3384. case(SB_FRAMESWITCH):
  3385. case(SB_SUPERSPACE):
  3386. case(SB_SUPERSPACE2):
  3387. case(SB_SUPERSPACE3):
  3388. case(SB_SUPERSPACE4):
  3389. *llev = lev; // Input level is distributed (as is) amongst various lspkrs
  3390. break;
  3391. }
  3392. }
  3393. /**************************************** OUTPUT_SPECIAL_SPATIALISATION_SAMPLE **************************************/
  3394. void output_special_spatialisation_sample(float *obuf,int sampcnt,int switchpos,int chans,double val,double valr,int lmost,int rmost,int spacetyp)
  3395. {
  3396. int k, tri1, tri2, tri3, a, b;
  3397. switch(spacetyp) {
  3398. case(SB_LR):
  3399. if(switchpos) {
  3400. for(k = (chans/2)+1;k < chans;k++)
  3401. obuf[sampcnt+k] = (float)(obuf[sampcnt+k] + val);
  3402. } else {
  3403. for(k = 1;k < chans/2;k++)
  3404. obuf[sampcnt+k] = (float)(obuf[sampcnt+k] + val);
  3405. }
  3406. break;
  3407. case(SB_FB):
  3408. if(switchpos) {
  3409. for(k = 0;k < chans;k++) {
  3410. if(k < 2 || k == 7)
  3411. obuf[sampcnt+k] = (float)(obuf[sampcnt+k] + val);
  3412. }
  3413. } else {
  3414. for(k = 3;k < 6;k++)
  3415. obuf[sampcnt+k] = (float)(obuf[sampcnt+k] + val);
  3416. }
  3417. break;
  3418. case(SB_TRIROT1):
  3419. case(SB_ANTITRIROT1):
  3420. tri1 = switchpos;
  3421. tri2 = (switchpos + 2) % chans;
  3422. tri3 = (switchpos + 6) % chans;
  3423. for(k = 0;k< chans;k++) {
  3424. if(k == tri1 || k == tri2 || k == tri3) // Add output only to the 2 relevant channels
  3425. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3426. sampcnt++;
  3427. }
  3428. break;
  3429. case(SB_TRIROT2):
  3430. case(SB_ANTITRIROT2):
  3431. tri1 = switchpos;
  3432. tri2 = (switchpos + 3) % chans;
  3433. tri3 = (switchpos + 5) % chans;
  3434. for(k = 0;k< chans;k++) {
  3435. if(k == tri1 || k == tri2 || k == tri3) // Add output only to the 2 relevant channels
  3436. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3437. sampcnt++;
  3438. }
  3439. break;
  3440. case(SB_FRAMESWITCH):
  3441. if(switchpos) {
  3442. for(k = 0;k< chans;k++) { // SQUARE
  3443. if(ODD(k))
  3444. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3445. sampcnt++;
  3446. }
  3447. } else {
  3448. for(k = 0;k< chans;k++) { // DIAMOND
  3449. if(EVEN(k))
  3450. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3451. sampcnt++;
  3452. }
  3453. }
  3454. break;
  3455. case(SB_SUPERSPACE):
  3456. case(SB_SUPERSPACE2):
  3457. case(SB_SUPERSPACE3):
  3458. case(SB_SUPERSPACE4):
  3459. if(switchpos <= 7) { // 0 - 7 Single chans
  3460. obuf[sampcnt+switchpos] = (float)(obuf[sampcnt+switchpos] + val);
  3461. } else if(switchpos <=35) { // 8 - 35
  3462. switchpos -= 8; // 0 - 27
  3463. if(switchpos >=24) { // 24 - 27
  3464. switchpos -= 24; // 0 - 3 paired with its opposite
  3465. obuf[sampcnt+switchpos] = (float)(obuf[sampcnt+switchpos] + val);
  3466. switchpos += chans/2; // 4 - 7
  3467. obuf[sampcnt+switchpos] = (float)(obuf[sampcnt+switchpos] + val);
  3468. } else { // 0 - 23
  3469. a = switchpos/3; // 0-7 = a
  3470. b = switchpos - (a*3); // 0-2
  3471. b++; // 1-3
  3472. b = (a + b) % chans; // a+(1-3)
  3473. obuf[sampcnt+a] = (float)(obuf[sampcnt+a] + val);
  3474. obuf[sampcnt+b] = (float)(obuf[sampcnt+b] + val);
  3475. }
  3476. } else if(switchpos <= 43) { // 36 - 43 TRIANGLE 1
  3477. switchpos -=36; // 0 - 7
  3478. tri1 = switchpos; // 0,1,2...
  3479. tri2 = (switchpos + 2) % chans; // 2,3,4...
  3480. tri3 = (switchpos + 6) % chans; // 7,6,0...
  3481. for(k = 0;k< chans;k++) {
  3482. if(k == tri1 || k == tri2 || k == tri3) // Add output only to the 2 relevant channels
  3483. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3484. sampcnt++;
  3485. }
  3486. } else if(switchpos <= 51) { // 44 - 51 TRIANGLE 2
  3487. switchpos -= 44; // 0 - 7
  3488. tri1 = switchpos; // 0,1,2,...
  3489. tri2 = (switchpos + 3) % chans; // 3,4,5...
  3490. tri3 = (switchpos + 5) % chans; // 5,6,7...
  3491. for(k = 0;k< chans;k++) {
  3492. if(k == tri1 || k == tri2 || k == tri3) // Add output only to the 2 relevant channels
  3493. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3494. sampcnt++;
  3495. }
  3496. } else if(switchpos == 52) { // SQUARE
  3497. for(k = 0;k< chans;k++) {
  3498. if(EVEN(k)) // 0,2,4,6
  3499. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3500. sampcnt++;
  3501. }
  3502. break;
  3503. } else if(switchpos == 53) { // DIAMOND
  3504. for(k = 0;k< chans;k++) {
  3505. if(ODD(k)) // 1,3,5,7
  3506. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3507. sampcnt++;
  3508. }
  3509. break;
  3510. } else { // 54 ALL
  3511. for(k = 0;k< chans;k++) { // 0,1,2,3,4,5,6,7
  3512. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3513. sampcnt++;
  3514. }
  3515. break;
  3516. }
  3517. break;
  3518. default: // STEREO POSITIONED BETWEEN SOME PAIR OF CHANNELS
  3519. for(k = 0;k< chans;k++) {
  3520. if(k == lmost) // Add output only to the 2 relevant channels
  3521. obuf[sampcnt] = (float)(obuf[sampcnt] + val);
  3522. else if(k == rmost)
  3523. obuf[sampcnt] = (float)(obuf[sampcnt] + valr);
  3524. sampcnt++;
  3525. }
  3526. }
  3527. }
  3528. /**************************** DUFFING *************************/
  3529. int duffing(dataptr dz)
  3530. {
  3531. int exit_status, passno;
  3532. int sampcnt, bufpos, n;
  3533. double time, maxsamp = 0.0, spliceamp, normaliser = 1.0, srate = (double)dz->iparam[SYNTHSRAT], tabpos, val, vel;
  3534. double delta_t = 1.0/srate; // Time-increment between sample-generation
  3535. float *obuf = dz->sampbuf[0];
  3536. int outlen = (int)round(dz->infile->srate * dz->param[SYNTH_DUR]);
  3537. double spliceincr = 1.0/dz->rampbrksize;
  3538. int splicestart = outlen - dz->rampbrksize;
  3539. dz->scalefact = (double)SYNTH_TABSIZE/srate; // Constant in sintable read
  3540. for(passno = 0;passno < 2;passno++) {
  3541. switch(passno) {
  3542. case(0): fprintf(stdout,"INFO: Assessing level.\n"); break;
  3543. case(1): fprintf(stdout,"INFO: Generating output sound.\n"); break;
  3544. }
  3545. fflush(stdout);
  3546. sampcnt = 0;
  3547. bufpos = 0;
  3548. tabpos = 0.0; // Initial position in table reading VELOCITY of point
  3549. val = 0.0; // Initial POSITION of point
  3550. vel = 0.0; // Initial velocity of point
  3551. if(splicestart < 0) // If outduration too short to include whole endsplice
  3552. spliceamp = outlen/dz->rampbrksize; // Preset start-amp at appropriate level within endsplice
  3553. else
  3554. spliceamp = 1.0;
  3555. while(sampcnt < outlen) {
  3556. obuf[bufpos] = (float)val;
  3557. if(sampcnt >= splicestart) { // If in endsplice, do end splice
  3558. obuf[bufpos] = (float)(obuf[bufpos] * spliceamp);
  3559. spliceamp -= spliceincr;
  3560. spliceamp = max(spliceamp,0.0);
  3561. }
  3562. bufpos++;
  3563. if(bufpos >= dz->buflen) {
  3564. switch(passno) {
  3565. case(0):
  3566. for(n=0;n<dz->buflen;n++)
  3567. maxsamp = max(maxsamp,fabs(obuf[n]));
  3568. break;
  3569. case(1):
  3570. for(n=0;n<dz->buflen;n++)
  3571. obuf[n] = (float)(obuf[n] * normaliser);
  3572. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3573. return(exit_status);
  3574. break;
  3575. }
  3576. bufpos = 0;
  3577. }
  3578. time = (double)sampcnt/srate;
  3579. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3580. return exit_status;
  3581. duffing_osc(&val,&vel,delta_t,&tabpos,dz);
  3582. sampcnt++;
  3583. }
  3584. if(bufpos > 0) {
  3585. switch(passno) {
  3586. case(0):
  3587. for(n=0;n<bufpos;n++)
  3588. maxsamp = max(maxsamp,fabs(obuf[n]));
  3589. if(maxsamp <= 0.0) {
  3590. sprintf(errstr,"NO SIGNIFICANT SOUND-LEVEL PRODUCED.\n");
  3591. return(GOAL_FAILED);
  3592. } else if(maxsamp > 0.95) {
  3593. if(maxsamp >= HUGE) {
  3594. fprintf(stdout,"INFO: Output blew up\n");
  3595. fflush(stdout);
  3596. exit(1);
  3597. }
  3598. normaliser = 1.0/maxsamp;
  3599. fprintf(stdout,"INFO: Max Level %lf Normalising output by %lf\n",maxsamp,normaliser);
  3600. fflush(stdout);
  3601. }
  3602. break;
  3603. case(1):
  3604. for(n=0;n<bufpos;n++)
  3605. obuf[n] = (float)(obuf[n] * normaliser);
  3606. if((exit_status = write_samps(obuf,bufpos,dz))<0)
  3607. return(exit_status);
  3608. break;
  3609. }
  3610. }
  3611. }
  3612. return FINISHED;
  3613. }
  3614. /**************************** SINREAD *************************/
  3615. double sinread(double *tabpos,double frq,dataptr dz)
  3616. {
  3617. double tabincr, val, valdiff, timefrac, *sintab = dz->parray[0];
  3618. int lopos, hipos;
  3619. lopos = (int)floor(*tabpos);
  3620. hipos = (int)ceil(*tabpos);
  3621. timefrac = *tabpos - (double)lopos;
  3622. val = sintab[lopos];
  3623. valdiff = sintab[hipos] - val;
  3624. val += valdiff * timefrac;
  3625. tabincr = frq * dz->scalefact;
  3626. *tabpos += tabincr;
  3627. if(*tabpos >= SYNTH_TABSIZE)
  3628. *tabpos -= SYNTH_TABSIZE;
  3629. return val;
  3630. }
  3631. /**************************** DUFFING_OSC *************************
  3632. *
  3633. *
  3634. * dx/dt = y velocity is rate of change of position (x)
  3635. *
  3636. * 3
  3637. * dy/dt = x - x - Dy + Fcoswt acceleration is driven partly by sinusoid-forcing and partly by system-damping
  3638. *
  3639. * where Fcoswt is a driving sinusoidal oscillation
  3640. * and x - x3 - Dy is the damping due to the Duffing double well.
  3641. */
  3642. void duffing_osc(double *val,double *vel, double delta_t,double *tabpos,dataptr dz)
  3643. {
  3644. double delta_vel, damped_acc, forced_acc;
  3645. damped_acc = (dz->param[SYNTH_K] * (*val)) - (dz->param[SYNTH_B] * pow((*val),3.0)); // Duffing damping of acceleration
  3646. damped_acc -= dz->param[SYNTH_DAMP] * (*vel);
  3647. forced_acc = sinread(tabpos,dz->param[SYNTH_FRQ],dz); // Sinusoidally varying acceleration
  3648. forced_acc *= 1000000; // scaled in amplitude
  3649. delta_vel = (damped_acc + forced_acc) * delta_t; // Change in velocity caused by acceleration
  3650. *val += *vel * delta_t; // position changed due to velocity
  3651. *vel += delta_vel; // velocity changed due to aceleration
  3652. }
  3653. /**************************** CHECK_SYNTH_PARAM_VALIDITY_AND_CONSISTENCY *************************/
  3654. int check_synth_param_validity_and_consistency(dataptr dz)
  3655. {
  3656. if(dz->vflag[0] && dz->param[SYNTH_RAND] != 0) {
  3657. sprintf(errstr,"Cannot set \"Maximim spike separation\" with a non-zero randomisation.\n");
  3658. return DATA_ERROR;
  3659. }
  3660. return FINISHED;
  3661. }
  3662. /************************************ FRACTAL ***********************************
  3663. *
  3664. * a b a b
  3665. * ____ ____
  3666. * | | | |
  3667. * | | | |
  3668. * | |____| |____|_________________
  3669. *
  3670. * |_________| |
  3671. * halfgrouplen = h |
  3672. * |
  3673. * |___________________|_________________|
  3674. * grouplen = g trailing silence
  3675. * |_____________________________________|
  3676. * wavelen
  3677. *
  3678. * ---------------------------------------------------------------------------
  3679. * After how many spikes do spikes flip from +ve to -ve (and vice versa) ??
  3680. * ---------------------------------------------------------------------------
  3681. * |-------------------------------------------------------------------------------|
  3682. * / = +ve splike: \ = -ve spike | +- flip at level M means a flip after how many spikes ?? |
  3683. * |-------------------------------------------------------------------------------|
  3684. * maxfrac |----------grouplen-------------| flip at level 0 | flip at level 1 | flip at level 2 | flip at level 3 |
  3685. *------------------------------------------|-------------------------------------------------------------------------------|
  3686. * 0 / \ | pow(2,0-0) = 1 | ---- | ---- | ---- |
  3687. * | | | | |
  3688. * 1 / \ / \ | pow(2,1-0) = 2 | pow(2,1-1) = 1 | ---- | ---- |
  3689. * | | | | |
  3690. * 2 / \ / \ / \ / \ | pow(2,2-0) = 4 | pow(2,2-1) = 2 | pow(2,2-2) = 1 | ---- |
  3691. * | | | | |
  3692. * 3 /\/\ /\/\ /\/\ /\/\ | pow(2,3-0) = 8 | pow(2,3-1) = 4 | pow(2,3-2) = 2 | pow(2,3-3) = 1 |
  3693. * | | | | |
  3694. * 4 /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\| pow(2,4-0) = 16 | pow(2,4-1) = 8 | pow(2,4-2) = 4 | pow(2,4-3) = 2 |
  3695. * | | | | |
  3696. * ETC | ETC | ETC | ETC | ETC |
  3697. *------------------------------------------|-------------------------------------------------------------------------------|
  3698. *
  3699. * count of spikes at which +- flipping takes place, depends on degree of fractalisation, and the flip-level specified..
  3700. *
  3701. * flipcnt = 2 ^ frac - dz->iparam[SYNTH_FLEVEL];
  3702. *
  3703. */
  3704. int fractal(dataptr dz)
  3705. {
  3706. int exit_status;
  3707. float *spikebuf = dz->sampbuf[2]; // length is dz->spikelen
  3708. float *ibuf = dz->sampbuf[0]; // length to copy to obuf depends on input frq/wavelen
  3709. float *obuf = dz->sampbuf[1]; // length to OUTPUT depends only on dz->buflen
  3710. int outdur, endsplicestart, total_samps_written;
  3711. int frac = MAXFRAC; // unrealistic huge value, reduced during Pass 1
  3712. int fraccnt; // counts depth of fractalisation
  3713. int *asub; // samplelen of each layer of fractalisation
  3714. int wavelen, total_wavelen, grouplen, halfgrouplen, total_grouplen, bufpos, obufpos, obufend, samps_to_write, samps_written, endpos, rlen;
  3715. int spikecnt, flipcnt, n, quit = 0;
  3716. double spliceincr, spliceratio, srate, time, dur, rr;
  3717. int splicelen = dz->rampbrksize, splicepos, spliceseg;
  3718. spliceincr = 1.0/splicelen;
  3719. spliceratio = 1.0; // splicevalue initialised to 1.0 (no splice)
  3720. splicepos = 0; // position in endsplice initialsed to 0
  3721. srate = (double)dz->iparam[SYNTHSRAT];
  3722. if((dz->lparray = (int **)malloc(2 * sizeof(int *)))==NULL) {
  3723. sprintf(errstr,"INSUFFICIENT MEMORY for arrays to store fractalisation lengths.\n");
  3724. return(MEMORY_ERROR);
  3725. }
  3726. if((dz->lparray[0] = (int *)malloc(MAXFRAC * sizeof(int)))==NULL) {
  3727. sprintf(errstr,"INSUFFICIENT MEMORY for arrays to store possible fractalisation lengths.\n");
  3728. return(MEMORY_ERROR);
  3729. }
  3730. asub = dz->lparray[0];
  3731. outdur = (int)(dz->param[SYNTH_DUR] * (double)dz->iparam[SYNTHSRAT]);
  3732. endsplicestart = outdur - splicelen;
  3733. // PASS 1 : CALCULATE MAXIMUM POSSIBLE FRACTALISATION
  3734. total_samps_written = 0;
  3735. time = 0.0;
  3736. // LOOP THROUGH EACH WAVECYCLE OF THE INPUT FREQUENCY
  3737. while(total_samps_written < outdur) {
  3738. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3739. return exit_status;
  3740. dur = 1.0/dz->param[SYNTH_FRQ]; // Duration of wavelen
  3741. wavelen = (int)ceil(srate * dur); // Wavelength
  3742. total_samps_written += wavelen;
  3743. grouplen = (int)floor((double)wavelen * dz->param[SYNTH_GTOW]);
  3744. halfgrouplen = grouplen/2;
  3745. fraccnt = 0; // initialise count of fractal levels
  3746. asub[fraccnt] = (int)floor((double)halfgrouplen * dz->param[SYNTH_ATOH]);
  3747. memset((char *)ibuf,0,dz->buflen * sizeof(float)); // Clear buffer
  3748. // LOOP THROUGH EACH LEVEL OF FRACTALISATION, FINDING THE MAXIMUM POSSIBLE FRACTALISATION
  3749. for(;;) {
  3750. if(asub[fraccnt] < dz->spikelen)
  3751. break; // Once fractal divisions are smaller than spike-signal, quit
  3752. wavelen = asub[fraccnt]; // Proceed to next fractal subdivision
  3753. grouplen = (int)floor((double)wavelen * dz->param[SYNTH_GTOW]);
  3754. halfgrouplen = grouplen/2;
  3755. fraccnt++; // count fractal subdivisions
  3756. asub[fraccnt] = (int)floor((double)halfgrouplen * dz->param[SYNTH_ATOH]);
  3757. }
  3758. time += dur; // Advance time by duration of current wavecycle
  3759. if(fraccnt < frac)
  3760. frac = fraccnt; // "frac" gets the (limit of) minimum degree of fractalisation conpatible with input params
  3761. // i.e. minimum fractalisation = frac - 1
  3762. }
  3763. frac--; // Maximum depth of fractalisation
  3764. if(frac < 0) {
  3765. sprintf(errstr,"Cannot proceed with these parameters (frq possibly too high).\n");
  3766. return DATA_ERROR;
  3767. } else {
  3768. fprintf(stdout,"INFO: Fractalisation depth = %d\n",frac);
  3769. fflush(stdout);
  3770. }
  3771. if(dz->iparam[SYNTH_FLEVEL] > frac) {
  3772. fprintf(stdout,"WARNING: Flip Level (%d) exceeds max possible fractalisation (%d) : adjusting.\n",dz->iparam[SYNTH_FLEVEL],frac-1);
  3773. fflush(stdout);
  3774. }
  3775. while(dz->iparam[SYNTH_FLEVEL] > frac) // Adjust +- flip level, if it exceeds max fractalisation
  3776. dz->iparam[SYNTH_FLEVEL]--;
  3777. // PASS 2 : OUTPUT SOUND, FRACTALISING ONLY TO MAX-POSSIBLE
  3778. total_samps_written = 0;
  3779. time = 0.0;
  3780. // LOOP THROUGH EACH WAVECYCLE OF THE INPUT FREQUENCY
  3781. obufpos = 0;
  3782. memset((char *)obuf,0,dz->buflen * sizeof(float)); // Clear output buffer
  3783. while(total_samps_written < outdur) {
  3784. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  3785. return exit_status;
  3786. dur = 1.0/dz->param[SYNTH_FRQ]; // Duration of wavelen
  3787. wavelen = (int)ceil(srate * dur); // Wavelength
  3788. total_wavelen = wavelen;
  3789. total_samps_written += wavelen;
  3790. grouplen = (int)floor((double)wavelen * dz->param[SYNTH_GTOW]);
  3791. total_grouplen = grouplen;
  3792. halfgrouplen = grouplen/2;
  3793. fraccnt = 0; // initialise count of fractal levels
  3794. asub[fraccnt] = (int)floor((double)halfgrouplen * dz->param[SYNTH_ATOH]);
  3795. memset((char *)ibuf,0,dz->buflen * sizeof(float)); // Clear buffer
  3796. // LOOP THROUGH EACH LEVEL OF FRACTALISATION, MARKING SPIKE-ENTRY POINTS
  3797. while(fraccnt <= frac) {
  3798. bufpos = 0; // point to buffer start
  3799. if(fraccnt == 0) {
  3800. ibuf[bufpos] = 1.0; // Mark 1st point of pair
  3801. endpos = grouplen - asub[fraccnt];
  3802. if(dz->vflag[AT_END]) // Mark off second point of pair : options
  3803. bufpos += endpos; // (1) Offset to endmost point of grouplen
  3804. else if(dz->param[SYNTH_RAND] > 0.0) {
  3805. rr = drand48() * dz->param[SYNTH_RAND]; // (2) Offset randomly between halfgrouplen and endmostpoint
  3806. rlen = endpos - halfgrouplen;
  3807. rlen = (int)round((double)rlen * rr);
  3808. bufpos += halfgrouplen + rlen;
  3809. } else
  3810. bufpos += halfgrouplen; // (3) Offset to halfgrouplen
  3811. ibuf[bufpos] = 1.0;
  3812. } else {
  3813. while(bufpos < total_grouplen) {
  3814. if(ibuf[bufpos] > 0.0) { // For each marked 'a' segment, subdivide it.
  3815. endpos = grouplen - asub[fraccnt];
  3816. if(dz->vflag[AT_END])
  3817. bufpos += endpos;
  3818. else if(dz->param[SYNTH_RAND] > 0.0) {
  3819. rr = drand48() * dz->param[SYNTH_RAND];
  3820. rlen = endpos - halfgrouplen;
  3821. rlen = (int)round((double)rlen * rr);
  3822. bufpos += halfgrouplen + rlen;
  3823. } else
  3824. bufpos += halfgrouplen;
  3825. ibuf[bufpos] = 1.0;
  3826. }
  3827. bufpos++;
  3828. }
  3829. }
  3830. wavelen = asub[fraccnt]; // Proceed to next fractal subdivision
  3831. grouplen = (int)floor((double)wavelen * dz->param[SYNTH_GTOW]);
  3832. halfgrouplen = grouplen/2;
  3833. fraccnt++; // count fractal subdivisions
  3834. asub[fraccnt] = (int)floor((double)halfgrouplen * dz->param[SYNTH_ATOH]);
  3835. }
  3836. // WRITE SPIKES AT MARKED POSITIONS
  3837. bufpos = 0;
  3838. spikecnt = 0; // Count spikes.
  3839. flipcnt = (int)round(pow(2,frac - dz->iparam[SYNTH_FLEVEL])); // Number of spikes before +- flip
  3840. while(bufpos < total_grouplen) {
  3841. if(ibuf[bufpos] > 0.0) {
  3842. memcpy((char *)(ibuf + bufpos),(char *)spikebuf,dz->spikelen * sizeof(float));
  3843. bufpos += dz->spikelen;
  3844. spikecnt++;
  3845. if(spikecnt >= flipcnt) { // If set of +ve spikes reaches flipcnt
  3846. for(n = 0; n< dz->spikelen;n++) // invert the spike
  3847. spikebuf[n] = (float)(spikebuf[n] * -1.0);
  3848. spikecnt = 0; // and reset spikecnt to zero
  3849. }
  3850. } else
  3851. bufpos++;
  3852. }
  3853. // IF IN FINAL SPLICE, DO SPLICING
  3854. if(total_samps_written > endsplicestart) {
  3855. if(splicepos == 0) { // If splice has not started
  3856. spliceseg = total_samps_written - endsplicestart;
  3857. bufpos = total_wavelen - spliceseg; // Start in buf where splice should start
  3858. } else
  3859. bufpos = 0; // Else, already in splice, start from bufstart
  3860. while(splicepos < splicelen) {
  3861. spliceratio -= spliceincr;
  3862. spliceratio = max(spliceratio,0.0);
  3863. ibuf[bufpos] = (float)(ibuf[bufpos] * spliceratio);
  3864. splicepos++;
  3865. if(++bufpos >= dz->buflen) // On reaching buffer end, before splice-end, quit, (continuing splice in next buffer)
  3866. break;
  3867. }
  3868. while(bufpos < dz->buflen) // On reaching splice end, before buffer-end, zero rest of buffer.
  3869. ibuf[bufpos++] = (float)0.0;
  3870. }
  3871. // COPY SYNTHED SIGNAL TO OUTPUT BUFFER, AND WRITE TO FILE
  3872. if(total_samps_written > outdur) {
  3873. total_wavelen -= total_samps_written - outdur;
  3874. quit = 1;
  3875. }
  3876. if(total_wavelen < 0) { // SAFETY
  3877. fprintf(stdout,"WARNING: Unanticipated termination of output.\n");
  3878. fflush(stdout);
  3879. break;
  3880. }
  3881. obufend = obufpos + total_wavelen;
  3882. if(obufend < dz->buflen) {
  3883. memcpy((char *)(obuf + obufpos),(char *)ibuf,total_wavelen * sizeof(float));
  3884. obufpos = obufend;
  3885. } else {
  3886. samps_to_write = dz->buflen - obufpos;
  3887. memcpy((char *)(obuf + obufpos),(char *)ibuf,samps_to_write * sizeof(float));
  3888. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  3889. return(exit_status);
  3890. samps_written = samps_to_write;
  3891. obufpos = 0;
  3892. memset((char *)obuf,0,dz->buflen * sizeof(float)); // Clear output buffer
  3893. samps_to_write = total_wavelen - samps_written;
  3894. memcpy((char *)obuf,(char *)(ibuf + samps_written),samps_to_write * sizeof(float));
  3895. samps_written = samps_to_write;
  3896. obufpos += samps_written;
  3897. }
  3898. if(quit)
  3899. break;
  3900. time += dur; // Advance time by duration of current wavecycle
  3901. }
  3902. if(obufpos > 0) {
  3903. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  3904. return(exit_status);
  3905. }
  3906. return FINISHED;
  3907. }