fractal.c 103 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391
  1. /*
  2. * Copyright (c) 1983-2023 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. // see HEREH
  22. // TEST cmdline =
  23. // _cdprogs\fractal wave 1 sin_cycle.wav testfrac.wav fracshape.brk 4 -m2
  24. // Only getting 1/2-way through the pattern ... why??
  25. // look at "seedata.txt" to check times advance!!!!
  26. // _cdprogs\fractal spectrum zzz.ana testfrac.ana fracshape5.brk
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <structures.h>
  30. #include <tkglobals.h>
  31. #include <pnames.h>
  32. #include <filetype.h>
  33. #include <processno.h>
  34. #include <modeno.h>
  35. #include <logic.h>
  36. #include <globcon.h>
  37. #include <cdpmain.h>
  38. #include <math.h>
  39. #include <mixxcon.h>
  40. #include <osbind.h>
  41. #include <standalone.h>
  42. #include <science.h>
  43. #include <ctype.h>
  44. #include <sfsys.h>
  45. #include <string.h>
  46. #include <srates.h>
  47. #ifdef unix
  48. #define round(x) lround((x))
  49. #endif
  50. #ifndef HUGE
  51. #define HUGE 3.40282347e+38F
  52. #endif
  53. #define FRAC_SPLICELEN 50 // Ms
  54. #define FRAC_FORMANTS 4 // No of formants used
  55. #define FRAC_SHRINK 0
  56. #define FRAC_OUTIMES 1
  57. #define mintime timemark // Minimum possible duration of any fractal element
  58. #define startfrq frametime // Frq of first pitch in (Mode 1) fractal_pitch-pattern
  59. #define maxtrnsp is_flat // Maximum possible upward-transpostion of any fractal element
  60. #define arraysize rampbrksize // Array size for totally fractalised pattern
  61. #define fracdur minbrk // Input duration of the fractal template
  62. #define minstep scalefact // Minimum element-duration in fractal template
  63. #define minfracratio halfchwidth // Time shrinkage of smallest element in fractal template, when proceeding from one fractal level to next
  64. #define maxfractalise ringsize // Maximum degree of fractalisation
  65. #define timevary is_transpos // Inicates that fractal patterning varies through time
  66. #define fracsize fzeroset // Number of elements in current totally-fractalised pattern
  67. #define convertor chwidth
  68. #define total_splice specenv_type // Total number of samples used in (any) end-splice
  69. #define splicesmps deal_with_chan_data // No of grouped-samples in (any) end-splice
  70. #define maxtransshrink is_sharp // Time-shrinkage of the element with maximum upward transposition, when proceeding from one fractal level to next
  71. #define mintransshrink minnum // Time-shrinkage of the element with maximum downward transposition, when proceeding from one fractal level to next
  72. #define FRACDUR 0
  73. #define FRACMAX 1
  74. #define FRACTSTR 2
  75. #define FRACISTR 3
  76. char errstr[2400];
  77. int anal_infiles = 1;
  78. int sloom = 0;
  79. int sloombatch = 0;
  80. const char* cdp_version = "6.1.0";
  81. //CDP LIB REPLACEMENTS
  82. static int check_fractal_param_validity_and_consistency(dataptr dz);
  83. static int setup_fractal_application(dataptr dz);
  84. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  85. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  86. static int setup_fractal_param_ranges_and_defaults(dataptr dz);
  87. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  88. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  89. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  90. static int establish_application(dataptr dz);
  91. static int initialise_vflags(dataptr dz);
  92. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  93. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  94. static int mark_parameter_types(dataptr dz,aplptr ap);
  95. static int assign_file_data_storage(int infilecnt,dataptr dz);
  96. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  97. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  98. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  99. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  100. static int handle_the_special_data(char *str,dataptr dz);
  101. static int create_fractal_sndbufs(dataptr dz);
  102. static void get_max_fractalisation(dataptr dz);
  103. static int fractalise(dataptr dz);
  104. static int fractal_initialise_specenv(int *arraycnt,dataptr dz);
  105. static int fractal_set_specenv_frqs(int arraycnt,dataptr dz);
  106. static int fractal_setup_octaveband_steps(double **interval,dataptr dz);
  107. static int fractal_setup_low_octave_bands(int arraycnt,dataptr dz);
  108. static int fractal_extract_specenv(dataptr dz);
  109. static int fractal_tranpose_within_formant_envelope(int vc,double transpose,dataptr dz);
  110. static int fractal_reposition_partials_in_appropriate_channels(double transpose,dataptr dz);
  111. static int fractal_spectrnsf(double transpose,dataptr dz);
  112. static int fractal_getspecenvamp(double *thisamp,double thisfrq,dataptr dz);
  113. static int fractal_get_channel_corresponding_to_frq(int *chan,double thisfrq,dataptr dz);
  114. /**************************************** MAIN *********************************************/
  115. int main(int argc,char *argv[])
  116. {
  117. int exit_status;
  118. dataptr dz = NULL;
  119. char **cmdline;
  120. int cmdlinecnt;
  121. int arraycnt = 0;
  122. char specialname[1200];
  123. // aplptr ap;
  124. int is_launched = FALSE;
  125. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  126. fprintf(stdout,"%s\n",cdp_version);
  127. fflush(stdout);
  128. return 0;
  129. }
  130. /* CHECK FOR SOUNDLOOM */
  131. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  132. sloom = 0;
  133. sloombatch = 1;
  134. }
  135. if(sflinit("cdp")){
  136. sfperror("cdp: initialisation\n");
  137. return(FAILED);
  138. }
  139. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  140. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  141. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  142. return(FAILED);
  143. }
  144. if(!sloom) {
  145. if(argc == 1) {
  146. usage1();
  147. return(FAILED);
  148. } else if(argc == 2) {
  149. usage2(argv[1]);
  150. return(FAILED);
  151. }
  152. }
  153. if(!sloom) {
  154. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  155. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  156. return(FAILED);
  157. }
  158. cmdline = argv;
  159. cmdlinecnt = argc;
  160. if((get_the_process_no(argv[0],dz))<0)
  161. return(FAILED);
  162. cmdline++;
  163. cmdlinecnt--;
  164. if(dz->process == FRACTAL) {
  165. dz->maxmode = 2;
  166. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  167. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  168. return(exit_status);
  169. }
  170. cmdline++;
  171. cmdlinecnt--;
  172. } else
  173. dz->maxmode = 0;
  174. // setup_particular_application =
  175. if((exit_status = setup_fractal_application(dz))<0) {
  176. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  177. return(FAILED);
  178. }
  179. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  180. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  181. return(FAILED);
  182. }
  183. } else {
  184. //parse_TK_data() =
  185. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  186. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  187. return(exit_status);
  188. }
  189. }
  190. // ap = dz->application;
  191. // parse_infile_and_hone_type() =
  192. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  193. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  194. return(FAILED);
  195. }
  196. // setup_param_ranges_and_defaults() =
  197. if((exit_status = setup_fractal_param_ranges_and_defaults(dz))<0) {
  198. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  199. return(FAILED);
  200. }
  201. // open_first_infile CDP LIB
  202. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  203. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  204. return(FAILED);
  205. }
  206. cmdlinecnt--;
  207. cmdline++;
  208. if(dz->process == FRACSPEC) {
  209. dz->nyquist = dz->infile->origrate/2.0;
  210. dz->frametime = (float)(1.0/dz->infile->arate);
  211. dz->clength = dz->wanted / 2;
  212. dz->chwidth = dz->nyquist/(double)(dz->clength-1);
  213. dz->halfchwidth = dz->chwidth/2.0;
  214. if((exit_status = fractal_initialise_specenv(&arraycnt,dz))<0) {
  215. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  216. return(FAILED);
  217. }
  218. dz->formant_bands = FRAC_FORMANTS;
  219. if((exit_status = fractal_set_specenv_frqs(arraycnt,dz))<0) {
  220. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  221. return(FAILED);
  222. }
  223. }
  224. // handle_extra_infiles() : redundant
  225. // handle_outfile() =
  226. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  227. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  228. return(FAILED);
  229. }
  230. // handle_formants() redundant
  231. // handle_formant_quiksearch() redundant
  232. // handle_special_data() redundant
  233. strcpy(specialname,cmdline[0]);
  234. cmdlinecnt--;
  235. cmdline++;
  236. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  237. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  238. return(FAILED);
  239. }
  240. if((exit_status = handle_the_special_data(specialname,dz))<0) {
  241. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  242. return(FAILED);
  243. }
  244. // check_param_validity_and_consistency ..
  245. if((exit_status = check_fractal_param_validity_and_consistency(dz))<0) {
  246. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  247. return(FAILED);
  248. }
  249. is_launched = TRUE;
  250. if(dz->process == FRACTAL)
  251. dz->bufcnt = 4;
  252. else
  253. dz->bufcnt = 2;
  254. if((exit_status = create_fractal_sndbufs(dz))<0) {
  255. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  256. return(FAILED);
  257. }
  258. //param_preprocess() redundant
  259. //spec_process_file =
  260. if((exit_status = fractalise(dz))<0) {
  261. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  262. return(FAILED);
  263. }
  264. if((exit_status = complete_output(dz))<0) { // CDP LIB
  265. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  266. return(FAILED);
  267. }
  268. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  269. free(dz);
  270. return(SUCCEEDED);
  271. }
  272. /**********************************************
  273. REPLACED CDP LIB FUNCTIONS
  274. **********************************************/
  275. /****************************** SET_PARAM_DATA *********************************/
  276. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  277. {
  278. ap->special_data = (char)special_data;
  279. ap->param_cnt = (char)paramcnt;
  280. ap->max_param_cnt = (char)maxparamcnt;
  281. if(ap->max_param_cnt>0) {
  282. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  283. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  284. return(MEMORY_ERROR);
  285. }
  286. strcpy(ap->param_list,paramlist);
  287. }
  288. return(FINISHED);
  289. }
  290. /****************************** SET_VFLGS *********************************/
  291. int set_vflgs
  292. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  293. {
  294. ap->option_cnt = (char) optcnt; /*RWD added cast */
  295. if(optcnt) {
  296. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  297. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  298. return(MEMORY_ERROR);
  299. }
  300. strcpy(ap->option_list,optlist);
  301. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  302. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  303. return(MEMORY_ERROR);
  304. }
  305. strcpy(ap->option_flags,optflags);
  306. }
  307. ap->vflag_cnt = (char) vflagcnt;
  308. ap->variant_param_cnt = (char) vparamcnt;
  309. if(vflagcnt) {
  310. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  311. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  312. return(MEMORY_ERROR);
  313. }
  314. strcpy(ap->variant_list,varlist);
  315. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  316. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  317. return(MEMORY_ERROR);
  318. }
  319. strcpy(ap->variant_flags,varflags);
  320. }
  321. return(FINISHED);
  322. }
  323. /***************************** APPLICATION_INIT **************************/
  324. int application_init(dataptr dz)
  325. {
  326. int exit_status;
  327. int storage_cnt;
  328. int tipc, brkcnt;
  329. aplptr ap = dz->application;
  330. if(ap->vflag_cnt>0)
  331. initialise_vflags(dz);
  332. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  333. ap->total_input_param_cnt = (char)tipc;
  334. if(tipc>0) {
  335. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  336. return(exit_status);
  337. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  338. return(exit_status);
  339. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  340. return(exit_status);
  341. }
  342. brkcnt = tipc;
  343. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  344. if(brkcnt>0) {
  345. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  346. return(exit_status);
  347. }
  348. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  349. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  350. return(exit_status);
  351. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  352. return(exit_status);
  353. }
  354. if((exit_status = mark_parameter_types(dz,ap))<0)
  355. return(exit_status);
  356. // establish_infile_constants() replaced by
  357. dz->infilecnt = 1;
  358. //establish_bufptrs_and_extra_buffers():
  359. return(FINISHED);
  360. }
  361. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  362. /* RWD mallo changed to calloc; helps debug verison run as release! */
  363. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  364. {
  365. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  366. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  367. return(MEMORY_ERROR);
  368. }
  369. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  370. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  371. return(MEMORY_ERROR);
  372. }
  373. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  374. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  375. return(MEMORY_ERROR);
  376. }
  377. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  378. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  379. return(MEMORY_ERROR);
  380. }
  381. return(FINISHED);
  382. }
  383. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  384. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  385. {
  386. int n;
  387. for(n=0;n<storage_cnt;n++) {
  388. dz->is_int[n] = (char)0;
  389. dz->no_brk[n] = (char)0;
  390. }
  391. return(FINISHED);
  392. }
  393. /***************************** MARK_PARAMETER_TYPES **************************/
  394. int mark_parameter_types(dataptr dz,aplptr ap)
  395. {
  396. int n, m; /* PARAMS */
  397. for(n=0;n<ap->max_param_cnt;n++) {
  398. switch(ap->param_list[n]) {
  399. case('0'): break; /* dz->is_active[n] = 0 is default */
  400. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  401. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  402. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  403. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  404. default:
  405. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  406. return(PROGRAM_ERROR);
  407. }
  408. } /* OPTIONS */
  409. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  410. switch(ap->option_list[n]) {
  411. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  412. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  413. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  414. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  415. default:
  416. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  417. return(PROGRAM_ERROR);
  418. }
  419. } /* VARIANTS */
  420. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  421. switch(ap->variant_list[n]) {
  422. case('0'): break;
  423. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  424. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  425. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  426. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  427. default:
  428. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  429. return(PROGRAM_ERROR);
  430. }
  431. } /* INTERNAL */
  432. for(n=0,
  433. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  434. switch(ap->internal_param_list[n]) {
  435. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  436. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  437. case('d'): dz->no_brk[m] = (char)1; break;
  438. default:
  439. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  440. return(PROGRAM_ERROR);
  441. }
  442. }
  443. return(FINISHED);
  444. }
  445. /************************ HANDLE_THE_OUTFILE *********************/
  446. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  447. {
  448. int exit_status;
  449. char *filename = (*cmdline)[0];
  450. if(filename[0]=='-' && filename[1]=='f') {
  451. dz->floatsam_output = 1;
  452. dz->true_outfile_stype = SAMP_FLOAT;
  453. filename+= 2;
  454. }
  455. if(!sloom) {
  456. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  457. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  458. return(DATA_ERROR);
  459. }
  460. }
  461. strcpy(dz->outfilename,filename);
  462. if((exit_status = create_sized_outfile(filename,dz))<0)
  463. return(exit_status);
  464. (*cmdline)++;
  465. (*cmdlinecnt)--;
  466. return(FINISHED);
  467. }
  468. /***************************** ESTABLISH_APPLICATION **************************/
  469. int establish_application(dataptr dz)
  470. {
  471. aplptr ap;
  472. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  473. sprintf(errstr,"establish_application()\n");
  474. return(MEMORY_ERROR);
  475. }
  476. ap = dz->application;
  477. memset((char *)ap,0,sizeof(struct applic));
  478. return(FINISHED);
  479. }
  480. /************************* INITIALISE_VFLAGS *************************/
  481. int initialise_vflags(dataptr dz)
  482. {
  483. int n;
  484. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  485. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  486. return(MEMORY_ERROR);
  487. }
  488. for(n=0;n<dz->application->vflag_cnt;n++)
  489. dz->vflag[n] = FALSE;
  490. return FINISHED;
  491. }
  492. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  493. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  494. {
  495. int n;
  496. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  497. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  498. return(MEMORY_ERROR);
  499. }
  500. for(n=0;n<tipc;n++)
  501. ap->default_val[n] = 0.0;
  502. return(FINISHED);
  503. }
  504. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  505. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  506. {
  507. int n;
  508. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  509. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  510. return(MEMORY_ERROR);
  511. }
  512. for(n=0;n<tipc;n++)
  513. dz->is_active[n] = (char)0;
  514. return(FINISHED);
  515. }
  516. /************************* SETUP_FRACTAL_APPLICATION *******************/
  517. int setup_fractal_application(dataptr dz)
  518. {
  519. int exit_status;
  520. aplptr ap;
  521. if((exit_status = establish_application(dz))<0) // GLOBAL
  522. return(FAILED);
  523. ap = dz->application;
  524. // SEE parstruct FOR EXPLANATION of next 2 functions
  525. if(dz->process == FRACTAL) {
  526. if (dz->mode == 0)
  527. exit_status = set_param_data(ap,FRACSHAPE,1,0,"0");
  528. else
  529. exit_status = set_param_data(ap,FRACSHAPE,1,1,"d");
  530. } else
  531. exit_status = set_param_data(ap,FRACSHAPE,1,0,"0");
  532. if(exit_status<0)
  533. return(FAILED);
  534. if(dz->process == FRACTAL) {
  535. if(dz->mode == 0)
  536. exit_status = set_vflgs(ap,"mti",3,"IDD","so",2,0,"00");
  537. else
  538. exit_status = set_vflgs(ap,"mti",3,"IDD","s",1,0,"0");
  539. } else
  540. exit_status = set_vflgs(ap,"mti",3,"IDD","sn",2,0,"00");
  541. if(exit_status<0)
  542. return(FAILED);
  543. // set_legal_infile_structure -->
  544. dz->has_otherfile = FALSE;
  545. // assign_process_logic -->
  546. if(dz->process == FRACSPEC) {
  547. dz->input_data_type = ANALFILE_ONLY;
  548. dz->process_type = BIG_ANALFILE;
  549. dz->outfiletype = ANALFILE_OUT;
  550. dz->maxmode = 0;
  551. } else {
  552. dz->input_data_type = SNDFILES_ONLY;
  553. dz->process_type = UNEQUAL_SNDFILE;
  554. dz->outfiletype = SNDFILE_OUT;
  555. dz->maxmode = 2;
  556. }
  557. return application_init(dz); //GLOBAL
  558. }
  559. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  560. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  561. {
  562. int exit_status;
  563. infileptr infile_info;
  564. if(!sloom) {
  565. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  566. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  567. return(MEMORY_ERROR);
  568. }
  569. if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  570. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  571. return(PROGRAM_ERROR);
  572. }
  573. if(dz->process == FRACTAL) {
  574. if(infile_info->filetype != SNDFILE) {
  575. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  576. return(DATA_ERROR);
  577. }
  578. if(dz->mode == 1 && infile_info->channels != 1) {
  579. sprintf(errstr,"File %s is not of correct type (must be mono for mode %d)\n",cmdline[0],dz->mode+1);
  580. return(DATA_ERROR);
  581. }
  582. } else if(infile_info->filetype != ANALFILE) {
  583. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  584. return(DATA_ERROR);
  585. }
  586. if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  587. sprintf(errstr,"Failed to copy file parsing information\n");
  588. return(PROGRAM_ERROR);
  589. }
  590. free(infile_info);
  591. }
  592. return(FINISHED);
  593. }
  594. /************************* SETUP_FRACTAL_PARAM_RANGES_AND_DEFAULTS *******************/
  595. int setup_fractal_param_ranges_and_defaults(dataptr dz)
  596. {
  597. int exit_status;
  598. aplptr ap = dz->application;
  599. // set_param_ranges()
  600. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  601. // NB total_input_param_cnt is > 0 !!!
  602. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  603. return(FAILED);
  604. // get_param_ranges()
  605. if(dz->process == FRACTAL && dz->mode == 1) {
  606. ap->lo[FRACDUR] = 1;
  607. ap->hi[FRACDUR] = FRAC_MAXDUR;
  608. ap->default_val[FRACDUR] = 10;
  609. }
  610. ap->lo[FRACMAX] = 0;
  611. ap->hi[FRACMAX] = FRAC_MAXFRACT;
  612. ap->default_val[FRACMAX] = 0;
  613. ap->lo[FRACTSTR] = 1;
  614. ap->hi[FRACTSTR] = 2;
  615. ap->default_val[FRACTSTR] = 1;
  616. ap->lo[FRACISTR] = 0;
  617. ap->hi[FRACISTR] = 8;
  618. ap->default_val[FRACISTR] = 0;
  619. if(dz->process == FRACTAL)
  620. dz->maxmode = 2;
  621. else
  622. dz->maxmode = 0;
  623. if(!sloom)
  624. put_default_vals_in_all_params(dz);
  625. return(FINISHED);
  626. }
  627. /********************************* PARSE_SLOOM_DATA *********************************/
  628. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  629. {
  630. int exit_status;
  631. int cnt = 1, infilecnt;
  632. int filesize, insams, inbrksize;
  633. double dummy;
  634. int true_cnt = 0;
  635. // aplptr ap;
  636. while(cnt<=PRE_CMDLINE_DATACNT) {
  637. if(cnt > argc) {
  638. sprintf(errstr,"Insufficient data sent from TK\n");
  639. return(DATA_ERROR);
  640. }
  641. switch(cnt) {
  642. case(1):
  643. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  644. sprintf(errstr,"Cannot read process no. sent from TK\n");
  645. return(DATA_ERROR);
  646. }
  647. break;
  648. case(2):
  649. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  650. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  651. return(DATA_ERROR);
  652. }
  653. if(dz->mode > 0)
  654. dz->mode--;
  655. //setup_particular_application() =
  656. if((exit_status = setup_fractal_application(dz))<0)
  657. return(exit_status);
  658. // ap = dz->application;
  659. break;
  660. case(3):
  661. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  662. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  663. return(DATA_ERROR);
  664. }
  665. if(infilecnt < 1) {
  666. true_cnt = cnt + 1;
  667. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  668. }
  669. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  670. return(exit_status);
  671. break;
  672. case(INPUT_FILETYPE+4):
  673. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  674. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  675. return(DATA_ERROR);
  676. }
  677. break;
  678. case(INPUT_FILESIZE+4):
  679. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  680. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  681. return(DATA_ERROR);
  682. }
  683. dz->insams[0] = filesize;
  684. break;
  685. case(INPUT_INSAMS+4):
  686. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  687. sprintf(errstr,"Cannot read insams sent from TK\n");
  688. return(DATA_ERROR);
  689. }
  690. dz->insams[0] = insams;
  691. break;
  692. case(INPUT_SRATE+4):
  693. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  694. sprintf(errstr,"Cannot read srate sent from TK\n");
  695. return(DATA_ERROR);
  696. }
  697. break;
  698. case(INPUT_CHANNELS+4):
  699. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  700. sprintf(errstr,"Cannot read channels sent from TK\n");
  701. return(DATA_ERROR);
  702. }
  703. break;
  704. case(INPUT_STYPE+4):
  705. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  706. sprintf(errstr,"Cannot read stype sent from TK\n");
  707. return(DATA_ERROR);
  708. }
  709. break;
  710. case(INPUT_ORIGSTYPE+4):
  711. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  712. sprintf(errstr,"Cannot read origstype sent from TK\n");
  713. return(DATA_ERROR);
  714. }
  715. break;
  716. case(INPUT_ORIGRATE+4):
  717. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  718. sprintf(errstr,"Cannot read origrate sent from TK\n");
  719. return(DATA_ERROR);
  720. }
  721. break;
  722. case(INPUT_MLEN+4):
  723. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  724. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  725. return(DATA_ERROR);
  726. }
  727. break;
  728. case(INPUT_DFAC+4):
  729. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  730. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  731. return(DATA_ERROR);
  732. }
  733. break;
  734. case(INPUT_ORIGCHANS+4):
  735. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  736. sprintf(errstr,"Cannot read origchans sent from TK\n");
  737. return(DATA_ERROR);
  738. }
  739. break;
  740. case(INPUT_SPECENVCNT+4):
  741. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  742. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  743. return(DATA_ERROR);
  744. }
  745. dz->specenvcnt = dz->infile->specenvcnt;
  746. break;
  747. case(INPUT_WANTED+4):
  748. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  749. sprintf(errstr,"Cannot read wanted sent from TK\n");
  750. return(DATA_ERROR);
  751. }
  752. break;
  753. case(INPUT_WLENGTH+4):
  754. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  755. sprintf(errstr,"Cannot read wlength sent from TK\n");
  756. return(DATA_ERROR);
  757. }
  758. break;
  759. case(INPUT_OUT_CHANS+4):
  760. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  761. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  762. return(DATA_ERROR);
  763. }
  764. break;
  765. /* RWD these chanegs to samps - tk will have to deal with that! */
  766. case(INPUT_DESCRIPTOR_BYTES+4):
  767. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  768. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  769. return(DATA_ERROR);
  770. }
  771. break;
  772. case(INPUT_IS_TRANSPOS+4):
  773. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  774. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  775. return(DATA_ERROR);
  776. }
  777. break;
  778. case(INPUT_COULD_BE_TRANSPOS+4):
  779. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  780. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  781. return(DATA_ERROR);
  782. }
  783. break;
  784. case(INPUT_COULD_BE_PITCH+4):
  785. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  786. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  787. return(DATA_ERROR);
  788. }
  789. break;
  790. case(INPUT_DIFFERENT_SRATES+4):
  791. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  792. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  793. return(DATA_ERROR);
  794. }
  795. break;
  796. case(INPUT_DUPLICATE_SNDS+4):
  797. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  798. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  799. return(DATA_ERROR);
  800. }
  801. break;
  802. case(INPUT_BRKSIZE+4):
  803. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  804. sprintf(errstr,"Cannot read brksize sent from TK\n");
  805. return(DATA_ERROR);
  806. }
  807. if(inbrksize > 0) {
  808. switch(dz->input_data_type) {
  809. case(WORDLIST_ONLY):
  810. break;
  811. case(PITCH_AND_PITCH):
  812. case(PITCH_AND_TRANSPOS):
  813. case(TRANSPOS_AND_TRANSPOS):
  814. dz->tempsize = inbrksize;
  815. break;
  816. case(BRKFILES_ONLY):
  817. case(UNRANGED_BRKFILE_ONLY):
  818. case(DB_BRKFILES_ONLY):
  819. case(ALL_FILES):
  820. case(ANY_NUMBER_OF_ANY_FILES):
  821. if(dz->extrabrkno < 0) {
  822. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  823. return(DATA_ERROR);
  824. }
  825. if(dz->brksize == NULL) {
  826. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  827. return(PROGRAM_ERROR);
  828. }
  829. dz->brksize[dz->extrabrkno] = inbrksize;
  830. break;
  831. default:
  832. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  833. dz->input_data_type);
  834. return(PROGRAM_ERROR);
  835. }
  836. break;
  837. }
  838. break;
  839. case(INPUT_NUMSIZE+4):
  840. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  841. sprintf(errstr,"Cannot read numsize sent from TK\n");
  842. return(DATA_ERROR);
  843. }
  844. break;
  845. case(INPUT_LINECNT+4):
  846. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  847. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  848. return(DATA_ERROR);
  849. }
  850. break;
  851. case(INPUT_ALL_WORDS+4):
  852. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  853. sprintf(errstr,"Cannot read all_words sent from TK\n");
  854. return(DATA_ERROR);
  855. }
  856. break;
  857. case(INPUT_ARATE+4):
  858. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  859. sprintf(errstr,"Cannot read arate sent from TK\n");
  860. return(DATA_ERROR);
  861. }
  862. break;
  863. case(INPUT_FRAMETIME+4):
  864. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  865. sprintf(errstr,"Cannot read frametime sent from TK\n");
  866. return(DATA_ERROR);
  867. }
  868. dz->frametime = (float)dummy;
  869. break;
  870. case(INPUT_WINDOW_SIZE+4):
  871. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  872. sprintf(errstr,"Cannot read window_size sent from TK\n");
  873. return(DATA_ERROR);
  874. }
  875. break;
  876. case(INPUT_NYQUIST+4):
  877. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  878. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  879. return(DATA_ERROR);
  880. }
  881. break;
  882. case(INPUT_DURATION+4):
  883. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  884. sprintf(errstr,"Cannot read duration sent from TK\n");
  885. return(DATA_ERROR);
  886. }
  887. break;
  888. case(INPUT_MINBRK+4):
  889. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  890. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  891. return(DATA_ERROR);
  892. }
  893. break;
  894. case(INPUT_MAXBRK+4):
  895. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  896. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  897. return(DATA_ERROR);
  898. }
  899. break;
  900. case(INPUT_MINNUM+4):
  901. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  902. sprintf(errstr,"Cannot read minnum sent from TK\n");
  903. return(DATA_ERROR);
  904. }
  905. break;
  906. case(INPUT_MAXNUM+4):
  907. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  908. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  909. return(DATA_ERROR);
  910. }
  911. break;
  912. default:
  913. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  914. return(PROGRAM_ERROR);
  915. }
  916. cnt++;
  917. }
  918. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  919. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  920. return(DATA_ERROR);
  921. }
  922. if(true_cnt)
  923. cnt = true_cnt;
  924. *cmdlinecnt = 0;
  925. while(cnt < argc) {
  926. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  927. return(exit_status);
  928. cnt++;
  929. }
  930. return(FINISHED);
  931. }
  932. /********************************* GET_TK_CMDLINE_WORD *********************************/
  933. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  934. {
  935. if(*cmdlinecnt==0) {
  936. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  937. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  938. return(MEMORY_ERROR);
  939. }
  940. } else {
  941. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  942. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  943. return(MEMORY_ERROR);
  944. }
  945. }
  946. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  947. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  948. return(MEMORY_ERROR);
  949. }
  950. strcpy((*cmdline)[*cmdlinecnt],q);
  951. (*cmdlinecnt)++;
  952. return(FINISHED);
  953. }
  954. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  955. int assign_file_data_storage(int infilecnt,dataptr dz)
  956. {
  957. int exit_status;
  958. int no_sndfile_system_files = FALSE;
  959. dz->infilecnt = infilecnt;
  960. if((exit_status = allocate_filespace(dz))<0)
  961. return(exit_status);
  962. if(no_sndfile_system_files)
  963. dz->infilecnt = 0;
  964. return(FINISHED);
  965. }
  966. /************************* redundant functions: to ensure libs compile OK *******************/
  967. int assign_process_logic(dataptr dz)
  968. {
  969. return(FINISHED);
  970. }
  971. void set_legal_infile_structure(dataptr dz)
  972. {}
  973. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  974. {
  975. return(FINISHED);
  976. }
  977. int setup_internal_arrays_and_array_pointers(dataptr dz)
  978. {
  979. return(FINISHED);
  980. }
  981. int establish_bufptrs_and_extra_buffers(dataptr dz)
  982. {
  983. return(FINISHED);
  984. }
  985. int read_special_data(char *str,dataptr dz)
  986. {
  987. return(FINISHED);
  988. }
  989. int inner_loop
  990. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  991. {
  992. return(FINISHED);
  993. }
  994. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  995. {
  996. return(FINISHED);
  997. }
  998. /******************************** USAGE1 ********************************/
  999. int usage1(void)
  1000. {
  1001. fprintf(stderr,
  1002. "USAGE: fractal NAME (mode) infile outfile parameters\n"
  1003. "\n"
  1004. "where NAME can be any one of\n"
  1005. "\n"
  1006. "wave spectrum\n"
  1007. "\n"
  1008. "Type 'fractal wave' for more info on fractal wave option... ETC.\n");
  1009. return(USAGE_ONLY);
  1010. }
  1011. /********************************************************************************************/
  1012. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1013. {
  1014. if(!strcmp(prog_identifier_from_cmdline,"wave"))
  1015. dz->process = FRACTAL;
  1016. else if(!strcmp(prog_identifier_from_cmdline,"spectrum"))
  1017. dz->process = FRACSPEC;
  1018. else {
  1019. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1020. return(USAGE_ONLY);
  1021. }
  1022. return(FINISHED);
  1023. }
  1024. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1025. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1026. {
  1027. int n;
  1028. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1029. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1030. return(MEMORY_ERROR);
  1031. }
  1032. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1033. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1034. return(MEMORY_ERROR);
  1035. }
  1036. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1037. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1038. return(MEMORY_ERROR);
  1039. }
  1040. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1041. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1042. return(MEMORY_ERROR);
  1043. }
  1044. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1045. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1046. return(MEMORY_ERROR);
  1047. }
  1048. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1049. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1050. return(MEMORY_ERROR);
  1051. }
  1052. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1053. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1054. return(MEMORY_ERROR);
  1055. }
  1056. for(n=0;n<brkcnt;n++) {
  1057. dz->brk[n] = NULL;
  1058. dz->brkptr[n] = NULL;
  1059. dz->brkinit[n] = 0;
  1060. dz->brksize[n] = 0;
  1061. }
  1062. return(FINISHED);
  1063. }
  1064. /******************************** USAGE2 ********************************/
  1065. int usage2(char *str)
  1066. {
  1067. if(!strcmp(str,"wave")) {
  1068. fprintf(stderr,
  1069. "USAGE:\n"
  1070. "fractal wave 1 inf outf shape [-mmaxfrac] [-tstr] [-iwarp] [-s] [-o]\n"
  1071. "fractal wave 2 inf outf shape dur [-mmaxfrac] [-tstr] [-iwarp] [-s]\n"
  1072. "\n"
  1073. "Fractally distort (1 or more channel) input sound (Mode 1).\n"
  1074. "OR generate fractal wave from (mono) input wavecycle (Mode 2)\n"
  1075. "Fractal is time-pattern of transpositions (and, in Mode 1\n"
  1076. "causes corresponding time contractions and expansions).\n"
  1077. "Transposition happens over total duration specified in \"SHAPE\"\n"
  1078. "and is then repeated over every resulting sub-unit of pattern,\n"
  1079. "over every sub-sub-unit, etc. until smallest time-unit reached.\n"
  1080. "\n"
  1081. "SHAPE Breakpoint textfile of\n"
  1082. " (Mode 1) time-(semitone)transposition pairs, (Range -12 to 12)\n"
  1083. " (Mode 2) time-MIDIpitch pairs, (Range 0 to 127)\n"
  1084. " defining pitch-time contour of the (largest) fractal shape.\n"
  1085. " Times must start at zero and increase,\n"
  1086. " with final time indicating duration of pattern.\n"
  1087. " (Value at final time will be ignored).\n"
  1088. "\n"
  1089. "DUR (Mode 2) Output duration (secs) (max 2 hours).\n"
  1090. "MAXFRAC Max degree of fractalisation. (Time-variable). If not set (or zero),\n"
  1091. " fractalisation proceeds until min possible wavelength reached.\n"
  1092. "STR Time stretch of fractal pattern (Time-variable : values >= 1).\n"
  1093. " If set to zero, no timestretching is done.\n"
  1094. "WARP Interval warping of fractal pattern (Time-variable).\n"
  1095. " If set to zero, no warping is done.\n"
  1096. "\n"
  1097. "-s Shrink pitch-intervals as fractal time-scales shrink.\n"
  1098. "-o Brkpnt data read using time in outfile (default: Use time in infile).\n"
  1099. "\n");
  1100. } else if(!strcmp(str,"spectrum")) {
  1101. fprintf(stderr,
  1102. "USAGE:\n"
  1103. "fractal spectrum inf outf shape [-mmaxfrac] [-tstr] [-iwarp] [-s] [-n]\n"
  1104. "\n"
  1105. "Fractally distort input spectrum by transposition.\n"
  1106. "Transposition happens over total duration specified in \"SHAPE\"\n"
  1107. "and is then repeated over every resulting sub-unit of pattern,\n"
  1108. "over every sub-sub-unit, etc. until smallest time-unit reached.\n"
  1109. "\n"
  1110. "SHAPE Breakpoint textfile of\n"
  1111. " Time-(semitone)transposition pairs, (Range -12 to 12)\n"
  1112. " defining pitch-time contour of the (largest) fractal shape.\n"
  1113. " Times must start at zero and increase,\n"
  1114. " with final time indicating duration of pattern.\n"
  1115. " (Value at final time will be ignored).\n"
  1116. "\n"
  1117. "MAXFRAC Max degree of fractalisation. (Time-variable). If not set (or zero),\n"
  1118. " fractalisation proceeds until min possible wavelength reached.\n"
  1119. "STR Time stretch of fractal pattern (Time-variable : values >= 1).\n"
  1120. " If set to zero, no timestretching is done.\n"
  1121. "WARP Interval warping of fractal pattern (Time-variable).\n"
  1122. " If set to zero, no warping is done.\n"
  1123. "\n"
  1124. "-s Shrink pitch-intervals as fractal time-scales shrink.\n"
  1125. "-n Transposition only (default, retain formant envelope).\n"
  1126. "\n");
  1127. } else
  1128. fprintf(stdout,"Unknown option '%s'\n",str);
  1129. return(USAGE_ONLY);
  1130. }
  1131. int usage3(char *str1,char *str2)
  1132. {
  1133. fprintf(stderr,"Insufficient parameters on command line.\n");
  1134. return(USAGE_ONLY);
  1135. }
  1136. /****************************** GET_MODE *********************************/
  1137. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1138. {
  1139. char temp[200], *p;
  1140. if(sscanf(str,"%s",temp)!=1) {
  1141. sprintf(errstr,"Cannot read mode of program.\n");
  1142. return(USAGE_ONLY);
  1143. }
  1144. p = temp + strlen(temp) - 1;
  1145. while(p >= temp) {
  1146. if(!isdigit(*p)) {
  1147. fprintf(stderr,"Invalid mode of program entered.\n");
  1148. return(USAGE_ONLY);
  1149. }
  1150. p--;
  1151. }
  1152. if(sscanf(str,"%d",&dz->mode)!=1) {
  1153. fprintf(stderr,"Cannot read mode of program.\n");
  1154. return(USAGE_ONLY);
  1155. }
  1156. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1157. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1158. return(USAGE_ONLY);
  1159. }
  1160. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1161. return(FINISHED);
  1162. }
  1163. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  1164. int handle_the_special_data(char *str,dataptr dz)
  1165. {
  1166. int exit_status, n, m, cnt;
  1167. FILE *fp;
  1168. char temp[200], *p;
  1169. double dummy = 0, lasttime = 0.0, lastmintrans = 0, lastmaxtrans = 0, mintrans = 0, maxtrans = 0, fracmax = 0.0;
  1170. double firstmidi = 0, lastmaxpitch = 0, lastminpitch = 0, maxpitch = 0, minpitch = 0, max_step, min_step, srate = (double)dz->infile->srate;
  1171. double *fractemplate, *fracintvl, *fractimes;
  1172. double mindur_maxtrans, mindur_mintrans, maxelement, minelement, thisdur, min_step_now, max_step_now;
  1173. if(dz->process == FRACTAL)
  1174. dz->mintime = (float)(4.0/srate); // Minimum duration of fractal pattern (> 4 samples)
  1175. else {
  1176. dz->frametime = (float)(1.0/dz->infile->arate);
  1177. dz->mintime = dz->frametime; // Minimum duration of fractal pattern (> 1 analysis window)
  1178. }
  1179. dz->maxtrnsp = 256.0; // 8 octaves
  1180. dz->maxfractalise = 0;
  1181. dz->minstep = HUGE;
  1182. if((fp = fopen(str,"r"))==NULL) {
  1183. sprintf(errstr,"Cannot open file %s to read clip lengths.\n",str);
  1184. return(DATA_ERROR);
  1185. }
  1186. cnt = 0;
  1187. lasttime = 0;
  1188. while(fgets(temp,200,fp)!=NULL) {
  1189. p = temp;
  1190. while(isspace(*p))
  1191. p++;
  1192. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1193. continue;
  1194. while(get_float_from_within_string(&p,&dummy)) {
  1195. if (EVEN(cnt)) { // TIMES MUST START AT ZERO AND INCREASE
  1196. if(cnt == 0) {
  1197. if(dummy != 0.0) {
  1198. sprintf(errstr,"Invalid initial time (%lf) in file %s. (Should be zero).\n",dummy,str);
  1199. return DATA_ERROR;
  1200. }
  1201. } else {
  1202. if(dummy <= lasttime) {
  1203. sprintf(errstr,"Times do not increase at (%lf %lf) in file %s.\n",lasttime,dummy,str);
  1204. return DATA_ERROR;
  1205. }
  1206. dz->minstep = min(dz->minstep,dummy - lasttime);// Find smallest time-step in fractal-pattern
  1207. }
  1208. lasttime = dummy;
  1209. } else { // VALUES MUSY LIE WITHIN RANGE
  1210. if(dz->process == FRACTAL && dz->mode == 1) { // as pitch-pattern
  1211. if(dummy < FRAC_MINMIDI || dummy > FRAC_MAXMIDI) {
  1212. sprintf(errstr,"MIDIpitch (%lf) out of range (%lf to %lf) in file %s.\n",dummy,FRAC_MINMIDI,FRAC_MAXMIDI,str);
  1213. return DATA_ERROR;
  1214. }
  1215. if(cnt == 1) {
  1216. firstmidi = dummy; // Note initial MIDI pitch
  1217. lastmaxpitch = dummy; // And search for max and min pitches
  1218. lastminpitch = dummy; // NB maximum and minimum search IGNORES last value in table
  1219. } else {
  1220. maxpitch = lastmaxpitch;
  1221. minpitch = lastminpitch;
  1222. lastmaxpitch = max(lastmaxpitch,dummy);
  1223. lastminpitch = min(lastminpitch,dummy);
  1224. }
  1225. } else { // as semitone-transposition-pattern
  1226. if(dummy < FRAC_MINTRNS || dummy > FRAC_MAXTRNS) {
  1227. sprintf(errstr,"Transposition (%lf semitones) out of range (%lf to %lf) in file %s.\n",dummy,FRAC_MINTRNS,FRAC_MAXTRNS,str);
  1228. return DATA_ERROR;
  1229. }
  1230. if(cnt == 1) {
  1231. lastmintrans = dummy; // Search for max and min transpositions
  1232. lastmaxtrans = dummy; // NB maximum and minimum search IGNORES last value in table
  1233. } else {
  1234. mintrans = lastmintrans;
  1235. maxtrans = lastmaxtrans;
  1236. lastmintrans = min(lastmintrans,dummy);
  1237. lastmaxtrans = max(lastmaxtrans,dummy);
  1238. }
  1239. }
  1240. }
  1241. cnt++;
  1242. }
  1243. }
  1244. if(cnt == 0) { // Check data count
  1245. sprintf(errstr,"No data found in file %s.\n",str);
  1246. return DATA_ERROR;
  1247. }
  1248. if(ODD(cnt)) {
  1249. sprintf(errstr,"Values not correctly paired in file %s.\n",str);
  1250. return DATA_ERROR;
  1251. }
  1252. if(cnt < 4) {
  1253. sprintf(errstr,"Insufficient values for a fractal shape (needs 2 times and 2 vals = 4 total) in file %s.\n",str);
  1254. return DATA_ERROR;
  1255. }
  1256. dz->fracdur = lasttime; // Last time in data indicates total duration of fractal-shape
  1257. if(dz->process == FRACTAL && dz->mode == 1)
  1258. dz->startfrq = (float)miditohz(firstmidi); // In mode 1 (fractal-template of pitches), find initial frq of pattern
  1259. dz->itemcnt = cnt/2;
  1260. if((dz->parray = (double **)malloc(6 * sizeof(double *)))==NULL) {
  1261. sprintf(errstr,"INSUFFICIENT MEMORY to create fractalisation calculation arrays.\n");
  1262. return(MEMORY_ERROR);
  1263. }
  1264. if((dz->parray[3] = (double *)malloc((dz->itemcnt * 2) * sizeof(double)))==NULL) {
  1265. sprintf(errstr,"INSUFFICIENT MEMORY to store fractalisation data.\n"); // fractemplate : original (input) fractal template data
  1266. return(MEMORY_ERROR);
  1267. }
  1268. fractemplate = dz->parray[3]; // Original fractal template time-val pairs
  1269. cnt = 0;
  1270. fseek(fp,0,0);
  1271. while(fgets(temp,200,fp)!=NULL) {
  1272. p = temp;
  1273. while(isspace(*p))
  1274. p++;
  1275. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1276. continue;
  1277. while(get_float_from_within_string(&p,&dummy))
  1278. fractemplate[cnt++] = dummy;
  1279. }
  1280. if(dz->process == FRACTAL && dz->mode == 1) {
  1281. for(n=1;n<dz->itemcnt*2;n+=2) // Convert pitch input to transpositions of initial pitch
  1282. fractemplate[n] -= firstmidi;
  1283. }
  1284. // CHECK TIME LIMITS
  1285. if(dz->process == FRACTAL && dz->mode == 1) {
  1286. if(dz->fracdur > FRAC_MAXDUR) {
  1287. fprintf(stdout,"WARNING: Pattern total duration (%lf) greater than %.2lf hours, in file %s.\n",dz->fracdur,FRAC_MAXDUR/3600.0,str);
  1288. fflush(stdout);
  1289. }
  1290. }
  1291. if(dz->brksize[FRACTSTR]) { // If fractal-shape time-stretched anywhere, get maximal tstretch,
  1292. if((exit_status = get_maxvalue_in_brktable(&fracmax,FRACTSTR,dz))<0)
  1293. return exit_status;
  1294. dz->param[FRACTSTR] = (int)round(fracmax);
  1295. }
  1296. // CHECK MAXIMUM FRACTALISATION
  1297. dz->minfracratio = dz->minstep/dz->fracdur;
  1298. get_max_fractalisation(dz);
  1299. if(dz->maxfractalise < 1) {
  1300. sprintf(errstr,"Smallest time-unit in pattern (%lf) too short to allow fractalisation.\n",dz->minstep);
  1301. return DATA_ERROR;
  1302. }
  1303. if(dz->brksize[FRACMAX]) { // If maximum fractalisation is preset by user
  1304. if((exit_status = get_maxvalue_in_brktable(&fracmax,FRACMAX,dz))<0)
  1305. return exit_status;
  1306. dz->iparam[FRACMAX] = (int)round(fracmax);
  1307. } // compare it with the max possible fractalisation
  1308. if(dz->iparam[FRACMAX] > dz->maxfractalise) {
  1309. fprintf(stdout,"WARNING: Max fractalisation will be restricted to %d because of time proportions in given shape data.\n",dz->maxfractalise);
  1310. fflush(stdout);
  1311. } else if (dz->iparam[FRACMAX] > 0 && dz->iparam[FRACMAX] < dz->maxfractalise)
  1312. dz->maxfractalise = dz->iparam[FRACMAX];
  1313. if(dz->brksize[FRACISTR]) {
  1314. if((exit_status = get_maxvalue_in_brktable(&fracmax,FRACISTR,dz))<0)
  1315. return exit_status;
  1316. dz->param[FRACISTR] = fracmax;
  1317. }
  1318. // CHECK RESTRICTIONS ON FRACTALISATION TRANSPOSITION-DEPTH CAUSED BY CHAINED-TRANSPOSITIONS
  1319. // FinD time-shrinkage at maximum amd minimum pitch (transposition) elements of fractal shape
  1320. if(dz->vflag[FRAC_SHRINK]) {
  1321. mindur_maxtrans = HUGE;
  1322. mindur_mintrans = HUGE;
  1323. if(dz->process == FRACTAL && dz->mode == 1) {
  1324. maxelement = maxpitch - firstmidi;
  1325. minelement = minpitch - firstmidi;
  1326. } else {
  1327. maxelement = maxtrans;
  1328. minelement = mintrans;
  1329. }
  1330. for(n = 1; n < (dz->itemcnt -1) * 2; n+= 2) {
  1331. if(fractemplate[n] == maxelement) {
  1332. thisdur = fractemplate[n+1] - fractemplate[n-1];
  1333. mindur_maxtrans = min(mindur_maxtrans,thisdur);
  1334. }
  1335. if(fractemplate[n] == minelement) {
  1336. thisdur = fractemplate[n+1] - fractemplate[n-1];
  1337. mindur_mintrans = min(mindur_mintrans,thisdur);
  1338. }
  1339. }
  1340. if(mindur_maxtrans == HUGE || mindur_mintrans == HUGE) {
  1341. sprintf(errstr,"Problem determining duration of max:min elements in fractal.\n");
  1342. return PROGRAM_ERROR;
  1343. }
  1344. dz->maxtransshrink = mindur_maxtrans/dz->fracdur;
  1345. dz->mintransshrink = mindur_mintrans/dz->fracdur;
  1346. }
  1347. // Check what happens to maximum and minimum transpositions, after maximium fractalisation.
  1348. if(dz->process == FRACTAL && dz->mode == 1)
  1349. max_step = maxpitch - firstmidi; // Base-pitch assumed to be first pitch of pattern
  1350. else
  1351. max_step = maxtrans;
  1352. if(dz->param[FRACISTR] > 1.0)
  1353. max_step *= dz->param[FRACISTR];
  1354. if(max_step > 0.0) { // If highest pitch in fractal-shape is above initial pitch
  1355. if(dz->vflag[FRAC_SHRINK]) {
  1356. max_step_now = max_step;
  1357. max_step = 0;
  1358. for(n = 0;n < dz->maxfractalise;n++) {
  1359. max_step += max_step_now;
  1360. max_step_now *= dz->maxtransshrink;
  1361. }
  1362. } else
  1363. max_step *= dz->maxfractalise; // calculate how mich this will step upwards in successive fractalisations
  1364. if(dz->process == FRACTAL && dz->mode == 1) {
  1365. maxpitch += max_step ;
  1366. if(maxpitch > MIDIMAX) {
  1367. sprintf(errstr,"Max pitch after max fractalisation (%d times) (MIDI %.2lf) exceeds limit (127).\n",dz->maxfractalise,maxpitch);
  1368. return DATA_ERROR;
  1369. }
  1370. } else { // Convert to frq ratio
  1371. maxtrans = pow(2.0,(max_step/SEMITONES_PER_OCTAVE));
  1372. if(maxtrans > dz->maxtrnsp) {
  1373. sprintf(errstr,"Max transpos after max fractalisation (%d times) (%lf octaves) exceeds limit (8).\n",dz->maxfractalise,LOG2(maxtrans));
  1374. return DATA_ERROR;
  1375. }
  1376. }
  1377. }
  1378. if(dz->process == FRACTAL && dz->mode == 1)
  1379. min_step = minpitch - firstmidi;
  1380. else
  1381. min_step = mintrans;
  1382. if(dz->param[FRACISTR] > 1.0)
  1383. min_step *= dz->param[FRACISTR];
  1384. if(min_step < 0.0) { // If lowest pitch in fractal-shape is below initial pitch
  1385. if(dz->vflag[FRAC_SHRINK]) {
  1386. min_step_now = min_step;
  1387. min_step = 0;
  1388. for(n = 0;n < dz->maxfractalise;n++) {
  1389. min_step += min_step_now;
  1390. min_step_now *= dz->mintransshrink;
  1391. }
  1392. } else
  1393. min_step *= dz->maxfractalise; // calculate how mich this will step downwardsupwards in successive fractalisations
  1394. if(dz->process == FRACTAL && dz->mode == 1) {
  1395. minpitch += min_step;
  1396. if(minpitch < 0) {
  1397. sprintf(errstr,"Min pitch after max fractalisation (%d times) (MIDI %lf) falls below low limit (0).\n",dz->maxfractalise,minpitch);
  1398. return DATA_ERROR;
  1399. }
  1400. } else {
  1401. mintrans = pow(2.0,(mintrans/SEMITONES_PER_OCTAVE));
  1402. mintrans = pow(mintrans,dz->maxfractalise);
  1403. if(mintrans < 1.0/dz->maxtrnsp) {
  1404. sprintf(errstr,"Max transpos down after max fractalisation (%d times) (%lf octaves) exceeds limit (-8).\n",dz->maxfractalise,LOG2(mintrans));
  1405. return DATA_ERROR;
  1406. }
  1407. }
  1408. }
  1409. // CREATE WORKING ARRAYS, now we know maximum depth of fractalisation (dz->maxfractalise)
  1410. dz->arraysize = dz->itemcnt - 1; // Number of fractal elements
  1411. dz->arraysize = (int)round(pow(dz->arraysize,dz->maxfractalise)); // Number of entries needed for (largest) fractalisation
  1412. dz->arraysize *= 2; // .. then include space for timing entries ....
  1413. dz->arraysize += 64; // SAFETY
  1414. if((dz->parray[0] = (double *)malloc(dz->arraysize * sizeof(double)))==NULL) {
  1415. sprintf(errstr,"INSUFFICIENT MEMORY to create fractalisation array.\n");
  1416. return(MEMORY_ERROR); // fracpattern : Stores final conmplete fractalisation of data
  1417. }
  1418. if((dz->parray[1] = (double *)malloc(dz->arraysize * sizeof(double)))==NULL) {
  1419. sprintf(errstr,"INSUFFICIENT MEMORY to create swap buffer 1.\n");
  1420. return(MEMORY_ERROR); // swapbuffer1 : 1st itermediate buffers to calc fractalisation, stage by stage
  1421. }
  1422. if((dz->parray[2] = (double *)malloc(dz->arraysize * sizeof(double)))==NULL) {
  1423. sprintf(errstr,"INSUFFICIENT MEMORY to create swap buffer 2.\n");
  1424. return(MEMORY_ERROR); // swapbuffer2 : 2nd itermediate buffers to calc fractalisation, stage by stage
  1425. }
  1426. if((dz->parray[4] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  1427. sprintf(errstr,"INSUFFICIENT MEMORY to store transposing data.\n"); // fracintvl : Mode 0 : Intvls in fractal template
  1428. return(MEMORY_ERROR); // Mode 1 : Intvls btwn pitches in orig fractal pitch-template
  1429. }
  1430. if((dz->parray[5] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  1431. sprintf(errstr,"INSUFFICIENT MEMORY to store element duations.\n");
  1432. return(MEMORY_ERROR); // fractimes : Onset times of each element in fractal template
  1433. }
  1434. fracintvl = dz->parray[4]; // Intervals between pitches in original fractal pitch-template
  1435. fractimes = dz->parray[5]; // Fractal template element-start-times
  1436. for(n=0, m=0; n < (dz->itemcnt-1) * 2; n +=2, m++) { // Stores dz->itemcnt-1 items
  1437. fractimes[m] = fractemplate[n];
  1438. fracintvl[m] = fractemplate[n+1];
  1439. }
  1440. dz->itemcnt--; // Last element of fractal template was needed only to specify total pattern's duration. So now ignore
  1441. // dz->itemcnt is number of elements in fractal-template
  1442. return FINISHED;
  1443. }
  1444. /************************************* CREATE_FRACTAL_PATTERN ***************************/
  1445. int create_fractal_pattern(dataptr dz)
  1446. {
  1447. int fractalcnt = dz->itemcnt, total_fractalcnt, k, n, nn, t, v, ocnt = 0;
  1448. double *fracpattern = dz->parray[0]; // Stores final conmplete fractalisation of data
  1449. double *swapbuffer1 = dz->parray[1]; // Intermediate buffers to calc fractalisation, stage by stage
  1450. double *swapbuffer2 = dz->parray[2];
  1451. double *thisbuf = NULL, *thatbuf = NULL;
  1452. double *fractemplate = dz->parray[3]; // Original fractal template time-val pairs
  1453. double *fracintvl = dz->parray[4]; // Intervals between pitches in original fractal pitch-template
  1454. double *fractimes = dz->parray[5]; // Fractal template element-start-times
  1455. double starttime, startval, duration, shrinkage;
  1456. memset((char *)fracpattern,0,dz->arraysize * sizeof(double));
  1457. memset((char *)swapbuffer1,0,dz->arraysize * sizeof(double));
  1458. memset((char *)swapbuffer2,0,dz->arraysize * sizeof(double));
  1459. memcpy((char *)swapbuffer1,(char *)fractemplate,(dz->itemcnt+1) * 2 * sizeof(double)); // Get original fractal-shape, with wraparound time
  1460. // mode 0 = semitone transpos : mode1 = MIDIpitch
  1461. total_fractalcnt = fractalcnt; // If fractalise only once, this is enough
  1462. if(dz->maxfractalise == 1)
  1463. thatbuf = swapbuffer1;
  1464. else {
  1465. for(k = 1; k < dz->maxfractalise;k++) {
  1466. ocnt = 0;
  1467. if(ODD(k)) {
  1468. thisbuf = swapbuffer1;
  1469. thatbuf = swapbuffer2;
  1470. } else {
  1471. thisbuf = swapbuffer2;
  1472. thatbuf = swapbuffer1;
  1473. }
  1474. memset((char *)thatbuf,0,dz->arraysize * sizeof(double));
  1475. for(n = 0, t = 0, v = 1; n < total_fractalcnt; n++,t+=2,v+=2) { // Fractalise every element of the "total_fractalcnt" elements existing at this stage.
  1476. starttime = thisbuf[t];
  1477. startval = thisbuf[v];
  1478. duration = thisbuf[t+2] - thisbuf[t]; // There is a wrap-around time-point in orig fractal-template
  1479. shrinkage = duration/dz->fracdur;
  1480. for(nn = 0; nn < fractalcnt; nn++) {
  1481. if(ocnt + 2 >= dz->arraysize) {
  1482. sprintf(errstr,"Array overrun in generating fractal.\n");
  1483. return PROGRAM_ERROR;
  1484. }
  1485. thatbuf[ocnt++] = starttime + (fractimes[nn] * shrinkage);
  1486. if(dz->vflag[FRAC_SHRINK])
  1487. thatbuf[ocnt++] = startval + (fracintvl[nn] * shrinkage);
  1488. else
  1489. thatbuf[ocnt++] = startval + fracintvl[nn];
  1490. }
  1491. }
  1492. total_fractalcnt = ocnt/2; // No of fractal elements after this fractalisation now increaaed to new "total_fractalcnt"
  1493. if(ocnt >= dz->arraysize - 1) {
  1494. sprintf(errstr,"Array overrun in generating last timepoint of fractal.\n");
  1495. return PROGRAM_ERROR;
  1496. }
  1497. thatbuf[ocnt++] = fractemplate[dz->itemcnt*2]; // Retain wraparound time-point
  1498. }
  1499. }
  1500. for(n = 0, t = 0, v = 1; n < total_fractalcnt; n++,t+=2,v+=2) {
  1501. fracpattern[t] = thatbuf[t];
  1502. if((dz->brksize[FRACISTR] > 0) || (dz->param[FRACISTR] > 0.0)) // If fractal is interval warped, do it here
  1503. thatbuf[v] *= dz->param[FRACISTR];
  1504. fracpattern[v] = pow(2.0,(thatbuf[v]/SEMITONES_PER_OCTAVE)); // Convert to 8va-transpos
  1505. }
  1506. fracpattern[t] = thatbuf[t]; // Store wraparound time-point
  1507. if(dz->param[FRACTSTR] > 0.0) {
  1508. for(t=0;t <= total_fractalcnt * 2; t+=2) // If fractal is time-warped, do the timewarp
  1509. fracpattern[t] *= dz->param[FRACTSTR];
  1510. }
  1511. dz->fracsize = total_fractalcnt; // Remember length of fractal pattern
  1512. return FINISHED;
  1513. }
  1514. /************************************* CHECK_FRACTAL_PARAM_VALIDITY_AND_CONSISTENCY ***************************/
  1515. int check_fractal_param_validity_and_consistency(dataptr dz)
  1516. {
  1517. int exit_status;
  1518. double minwarp = 0.0;
  1519. dz->timevary = 0;
  1520. if(dz->brksize[FRACMAX] || dz->brksize[FRACTSTR] || dz->brksize[FRACISTR])
  1521. dz->timevary = 1;
  1522. if(dz->brksize[FRACTSTR]) {
  1523. if((exit_status = get_minvalue_in_brktable(&minwarp,FRACTSTR,dz))<0)
  1524. return exit_status;
  1525. if(minwarp < 1.0) {
  1526. sprintf(errstr,"Values in timewarp table must be >= 1.0\n");
  1527. return DATA_ERROR;
  1528. }
  1529. } else if(dz->param[FRACTSTR] > 0.0 && dz->param[FRACTSTR] < 1.0) {
  1530. sprintf(errstr,"Non-zero timewarp value must be >= 1.\n");
  1531. return DATA_ERROR;
  1532. }
  1533. if(dz->process == FRACTAL) {
  1534. dz->splicesmps = (int)ceil(FRAC_SPLICELEN * MS_TO_SECS * (double)dz->infile->srate);
  1535. dz->total_splice = dz->splicesmps * dz->infile->channels;
  1536. if(dz->mode == 1) {
  1537. if(dz->insams[0] < dz->total_splice) {
  1538. fprintf(stdout,"WARNING: Infile too short to enable endsplice to be made.\n");
  1539. fflush(stdout);
  1540. dz->total_splice = 0; // Don't attempt endsplice
  1541. }
  1542. } else
  1543. dz->total_splice = 0; // No endsplice needed in mode 0
  1544. } else {
  1545. dz->splicesmps = 0; // Probably redundant
  1546. dz->total_splice = 0;
  1547. }
  1548. return FINISHED;
  1549. }
  1550. /************************************* FRACTALISE ***************************/
  1551. int fractalise(dataptr dz)
  1552. {
  1553. int exit_status, chans = dz->infile->channels, done = 0, ch, nxt, n, m;
  1554. double intime = 0.0, outtime = 0.0, ztime, localtime, srate = (double)dz->infile->srate;
  1555. int ibufpos = 0, gpibufpos = 0, obufpos = 0, fracindex = 0, bufcnt = 0, abs_input_start_samp = 0, nextfracsampcnt, zsamps;
  1556. int gpbuflen = dz->buflen/chans, abs_window_cnt = 0, next_abs_window_cnt = 0;
  1557. double dibufpos = 0.0, localsampcnt, incr, frac, diff, spliceval, abs_time = 0, nexttime = 0.0, transpose = 1.0;
  1558. double *fracpattern = dz->parray[0];
  1559. float *ibuf, *obuf, *ovflwbuf = NULL;
  1560. double *val;
  1561. double *fractemplate = dz->parray[3];
  1562. if(dz->process == FRACTAL) {
  1563. ibuf = dz->sampbuf[0];
  1564. /* input overflow in = dz->sampbuf[1] */
  1565. obuf = dz->sampbuf[2];
  1566. ovflwbuf = dz->sampbuf[3];
  1567. } else {
  1568. ibuf = dz->sampbuf[0];
  1569. obuf = dz->sampbuf[1];
  1570. }
  1571. if((val = (double *)malloc(chans * sizeof(double))) == NULL) {
  1572. sprintf(errstr,"INSUFFICIENT MEMORY to create intermediate value storage.\n");
  1573. return(MEMORY_ERROR);
  1574. }
  1575. if(!dz->timevary) { // If fractal does not vary
  1576. if((exit_status = create_fractal_pattern(dz)) < 0)
  1577. return exit_status; // Create fixed fractal pattern
  1578. }
  1579. if(dz->process == FRACTAL) {
  1580. // FRACTAL reads a double buffer, so that we have wraparound points to use
  1581. if(dz->mode == 0) { // (If mode 1, source used as "table", and is already in buffer)
  1582. dz->buflen *= 2;
  1583. if((exit_status = read_samps(ibuf,dz))<0)
  1584. return(exit_status);
  1585. abs_input_start_samp = 0;
  1586. dz->buflen /= 2;
  1587. }
  1588. for(ch = 0;ch < chans; ch++) // Read initial src/table values to output value store
  1589. val[ch] = ibuf[ch];
  1590. } else { // FRACSPEC reads a single buffer of analysis samples
  1591. dz->flbufptr[0] = ibuf;
  1592. dz->flbufptr[1] = obuf;
  1593. if((exit_status = read_samps(ibuf,dz))<0)
  1594. return(exit_status);
  1595. memcpy((char *)obuf,(char *)ibuf,dz->wanted * sizeof(float));
  1596. abs_time = dz->frametime; // First window is copied (below)
  1597. abs_window_cnt = 1;
  1598. dz->flbufptr[0] += dz->wanted; // flbufptrs advance
  1599. dz->flbufptr[1] += dz->wanted;
  1600. }
  1601. while(!done) {
  1602. if(dz->timevary) { // If fractal varies in time
  1603. if(dz->mode == 1 || (dz->process == FRACTAL && dz->vflag[FRAC_OUTIMES])) { // Read brkpoint data using either time in infile or time in outfile
  1604. if((exit_status = read_values_from_all_existing_brktables(outtime,dz))<0)
  1605. return exit_status;
  1606. } else {
  1607. if((exit_status = read_values_from_all_existing_brktables(intime,dz))<0)
  1608. return exit_status;
  1609. }
  1610. if(dz->iparam[FRACMAX] > 0) // Find maximum fractalisation
  1611. dz->maxfractalise = dz->iparam[FRACMAX];
  1612. else
  1613. get_max_fractalisation(dz);
  1614. if(dz->maxfractalise > 0) // Create the fractal pattern, and remember length of fractal-pattern (dz->fracsize)
  1615. create_fractal_pattern(dz);
  1616. }
  1617. ztime = fractemplate[dz->itemcnt * 2];
  1618. if(dz->maxfractalise == 0) {
  1619. if(dz->process == FRACTAL) {
  1620. zsamps = (int)round(ztime * srate);
  1621. gpibufpos = (int)round(dibufpos); // Approximation of interpolating pointer involved here
  1622. ibufpos = gpibufpos * chans;
  1623. for(n = 0; n <zsamps; n++) {
  1624. if(ibufpos >= dz->buflen) {
  1625. if(dz->mode == 0) { // If reading countinuous input, advance by buflen
  1626. memset((char *)ibuf,0,dz->buflen * 2 * sizeof(float));
  1627. bufcnt++;
  1628. if(dz->buflen * bufcnt >= dz->insams[0]) {
  1629. done = 1; // Exit if attempted samps_read looks beyound input file end
  1630. break;
  1631. }
  1632. sndseekEx(dz->ifd[0],dz->buflen * bufcnt,0);
  1633. dz->buflen *= 2; // and read 2 * buflen (so we have wraparound)
  1634. abs_input_start_samp += dz->ssampsread/2;
  1635. if((exit_status = read_samps(ibuf,dz))<0)
  1636. return(exit_status);
  1637. dz->buflen /= 2;
  1638. if(dz->ssampsread == 0) { // Exit if no more samples to read (should be redundant as trap at snd seek above)
  1639. done = 1;
  1640. break;
  1641. }
  1642. }
  1643. ibufpos -= dz->buflen;
  1644. }
  1645. if(obufpos >= dz->buflen + dz->total_splice) { // Allow enough samples on end of output to perform splice. (ALPHA)
  1646. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1647. return(exit_status); // Write to outfile, then copy back ovflow into obuf
  1648. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1649. memcpy((char *)obuf,(char *)ovflwbuf,dz->buflen * sizeof(float));
  1650. memset((char *)ovflwbuf,0,dz->buflen * sizeof(float));
  1651. obufpos -= dz->buflen; // and reset obufptr
  1652. }
  1653. for(ch = 0;ch<chans;ch++)
  1654. obuf[obufpos++] = ibuf[ibufpos++];
  1655. }
  1656. gpibufpos = ibufpos/chans;
  1657. dibufpos = (double)gpibufpos;
  1658. intime += ztime; // overflow point in fractal template contains its duration, so advance time in input file
  1659. outtime += ztime; // time in output file
  1660. } else { // FRACSPEC
  1661. next_abs_window_cnt = (int)round(ztime/dz->frametime);
  1662. while(abs_window_cnt < next_abs_window_cnt) {
  1663. memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
  1664. dz->flbufptr[0] += dz->wanted;
  1665. dz->flbufptr[1] += dz->wanted;
  1666. if(dz->flbufptr[0] >= obuf) {
  1667. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1668. return(exit_status);
  1669. memset((char *)ibuf,0,dz->buflen * sizeof(float));
  1670. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1671. if((exit_status = read_samps(ibuf,dz))<0)
  1672. return(exit_status);
  1673. if(dz->ssampsread == 0) {
  1674. done = 1;
  1675. break;
  1676. }
  1677. dz->flbufptr[0] = ibuf;
  1678. dz->flbufptr[1] = obuf;
  1679. }
  1680. abs_window_cnt++;
  1681. abs_time += dz->frametime;
  1682. if(abs_window_cnt >= dz->wlength) {
  1683. done = 1;
  1684. break;
  1685. }
  1686. }
  1687. }
  1688. } else {
  1689. if(dz->process == FRACTAL) {
  1690. localsampcnt = 0; // This is a count in gp-samples
  1691. fracindex = 0;
  1692. while(fracindex < dz->fracsize * 2) { // For each unit of the fractal (2 entries - time:val - per fractal element)
  1693. nextfracsampcnt = (int)round(fracpattern[fracindex + 2] * srate);
  1694. while(localsampcnt > nextfracsampcnt) {
  1695. fracindex += 2;
  1696. if(fracindex >= dz->fracsize)
  1697. break;
  1698. nextfracsampcnt = (int)round(fracpattern[fracindex + 2] * srate);
  1699. }
  1700. incr = fracpattern[fracindex + 1]; // Get current input-read increment
  1701. while(localsampcnt < nextfracsampcnt) { // While we're still using the current increment
  1702. for(ch = 0;ch < chans; ch++)
  1703. obuf[obufpos++] = (float)val[ch]; // Copy current value from input to output
  1704. if(obufpos >= dz->buflen + dz->total_splice) {// Allow enough samples on end of output to perform splice. (ALPHA)
  1705. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1706. return(exit_status); // Write to outfile, then copy back ovflow into obuf
  1707. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1708. memcpy((char *)obuf,(char *)ovflwbuf,dz->buflen * sizeof(float));
  1709. memset((char *)ovflwbuf,0,dz->buflen * sizeof(float));
  1710. obufpos -= dz->buflen; // and reset obufptr
  1711. }
  1712. if(dz->mode == 1) {
  1713. dibufpos += incr * dz->convertor; // Advance in table-read
  1714. gpibufpos = (int)floor(dibufpos);
  1715. ibufpos = gpibufpos; // Mono
  1716. }else {
  1717. dibufpos += incr; // Advance pointer in infile src
  1718. gpibufpos = (int)floor(dibufpos);
  1719. ibufpos = gpibufpos * chans; // In mode 1, if run off end of input file, quit
  1720. if(abs_input_start_samp + ibufpos >= dz->insams[0]) {
  1721. done = 1;
  1722. break;
  1723. }
  1724. }
  1725. frac = dibufpos - (double)gpibufpos;
  1726. if(gpibufpos >= gpbuflen) {
  1727. if(dz->mode == 0) { // If reading countinuous input, advance by buflen
  1728. memset((char *)ibuf,0,dz->buflen * 2 * sizeof(float));
  1729. bufcnt++;
  1730. if(dz->buflen * bufcnt >= dz->insams[0]) {
  1731. done = 1; // Exit if attempted samps_read looks beyound input file end
  1732. break;
  1733. }
  1734. sndseekEx(dz->ifd[0],dz->buflen * bufcnt,0);
  1735. dz->buflen *= 2; // and read 2 * buflen (so we have wraparound)
  1736. abs_input_start_samp += dz->ssampsread/2;
  1737. if((exit_status = read_samps(ibuf,dz))<0)
  1738. return(exit_status);
  1739. dz->buflen /= 2;
  1740. if(dz->ssampsread == 0) { // Exit if no more samples to read (should be redundant as trap at snd seek above)
  1741. done = 1;
  1742. break;
  1743. }
  1744. }
  1745. gpibufpos -= gpbuflen;
  1746. dibufpos -= (double)gpbuflen;
  1747. ibufpos = gpibufpos * chans;
  1748. } // Working in absolute sample-frame get interpolated value(s) from src/table
  1749. for(ch = 0,nxt = chans;ch < chans;ch++,nxt++) {
  1750. val[ch] = ibuf[ibufpos + ch];
  1751. diff = ibuf[ibufpos + nxt] - val[ch];
  1752. val[ch] += diff * frac;
  1753. }
  1754. localsampcnt += incr; // Advance by given samp-time incr
  1755. if(localsampcnt >= nextfracsampcnt) // If we reach time of next fractal (we will therefore exit inner loop)
  1756. fracindex += 2; // incr fracindex-value, hence advance in fractal pattern in outer loop
  1757. }
  1758. if(done)
  1759. break;
  1760. }
  1761. intime += fracpattern[dz->fracsize]; // overflow point in fractal table contains its duration, so advance time in input file
  1762. outtime = (double)((dz->total_samps_written + obufpos)/chans)/srate; // time in output file
  1763. if(dz->mode == 1) {
  1764. if(outtime >= dz->param[FRACDUR])
  1765. done = 1;
  1766. } else {
  1767. if(intime >= dz->duration)
  1768. done = 1;
  1769. }
  1770. } else { // FRACSPEC
  1771. localtime = 0.0;
  1772. fracindex = 0;
  1773. while(fracindex < dz->fracsize * 2) { // For each unit of the fractal (2 entries - time:val - per fractal element)
  1774. nexttime = fracpattern[fracindex + 2];
  1775. transpose = fracpattern[fracindex + 1];
  1776. while(localtime < nexttime) {
  1777. if((exit_status = fractal_spectrnsf(transpose,dz))<0)
  1778. return(exit_status);
  1779. memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
  1780. dz->flbufptr[0] += dz->wanted;
  1781. dz->flbufptr[1] += dz->wanted;
  1782. if(dz->flbufptr[0] >= obuf) { // obuf abutts to end of ibuf
  1783. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1784. return(exit_status);
  1785. memset((char *)ibuf,0,dz->buflen * sizeof(float));
  1786. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1787. if((exit_status = read_samps(ibuf,dz))<0)
  1788. return(exit_status);
  1789. if(dz->ssampsread == 0) {
  1790. done = 1;
  1791. break;
  1792. }
  1793. dz->flbufptr[0] = ibuf;
  1794. dz->flbufptr[1] = obuf;
  1795. }
  1796. abs_window_cnt++;
  1797. abs_time += dz->frametime;
  1798. localtime += dz->frametime;
  1799. if(abs_time >= dz->duration) {
  1800. done = 1;
  1801. break;
  1802. }
  1803. }
  1804. fracindex += 2;
  1805. if(done)
  1806. break;
  1807. }
  1808. }
  1809. }
  1810. }
  1811. if(obufpos > 0) {
  1812. if(dz->process == FRACTAL) {
  1813. if(dz->mode == 1 && dz->total_splice > 0) {
  1814. for(n=0,m = obufpos - chans;n < dz->splicesmps;n++,m -= chans) {
  1815. spliceval = (double)n/(double)dz->splicesmps;
  1816. for(ch = 0;ch < chans;ch++) // Splice end of output
  1817. obuf[m+ch] = (float)(obuf[m+ch] * spliceval);
  1818. }
  1819. }
  1820. }
  1821. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1822. return(exit_status); // Write last samples to outfile
  1823. }
  1824. return FINISHED;
  1825. }
  1826. /**************************** GET_MAX_FRACTALISATION ****************************/
  1827. void get_max_fractalisation(dataptr dz)
  1828. {
  1829. double minlen = dz->minstep; // minimum duration in fractal-shape
  1830. dz->maxfractalise = 0;
  1831. if(dz->param[FRACTSTR] > 1.0) // If fractal-shape gets stretched anywhere, expand minlen appropriately
  1832. minlen *= dz->param[FRACTSTR];
  1833. while(minlen > dz->mintime) { // Calculate the max possible fractalisation
  1834. minlen *= dz->minfracratio;
  1835. dz->maxfractalise++;
  1836. }
  1837. }
  1838. /**************************** CREATE_FRACTAL_SNDBUFS ****************************/
  1839. int create_fractal_sndbufs(dataptr dz)
  1840. {
  1841. int exit_status, n;
  1842. int bigbufsize, secsize, m;
  1843. int framesize = F_SECSIZE * dz->infile->channels;
  1844. double srate = (double)dz->infile->srate;
  1845. if(dz->process == FRACTAL) {
  1846. if (dz->mode == 1) // Mode 1, source file is used as a table to read cyclically
  1847. bigbufsize = dz->insams[0] * sizeof(float);
  1848. else
  1849. bigbufsize = (int)(size_t) Malloc(-1);
  1850. secsize = bigbufsize/framesize;
  1851. if(secsize * framesize < bigbufsize) {
  1852. secsize++;
  1853. bigbufsize = secsize * framesize;
  1854. }
  1855. } else
  1856. bigbufsize = dz->wanted * BUF_MULTIPLIER * sizeof(float);
  1857. dz->buflen = bigbufsize/sizeof(float);
  1858. if(bigbufsize * dz->bufcnt <= 0) {
  1859. if(dz->process == FRACTAL && dz->mode == 1)
  1860. sprintf(errstr,"Infile too large to create sound buffers.\n");
  1861. else
  1862. sprintf(errstr,"Insufficent memory to create sound buffers.\n");
  1863. return(PROGRAM_ERROR);
  1864. }
  1865. if((dz->bigbuf = (float *)malloc(bigbufsize * dz->bufcnt)) == NULL) {
  1866. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1867. return(PROGRAM_ERROR);
  1868. }
  1869. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  1870. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  1871. return(MEMORY_ERROR);
  1872. }
  1873. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  1874. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  1875. return(MEMORY_ERROR);
  1876. }
  1877. if(dz->process == FRACSPEC) {
  1878. if((dz->flbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  1879. sprintf(errstr,"INSUFFICIENT MEMORY for float sample buffers.\n");
  1880. return(MEMORY_ERROR);
  1881. }
  1882. for(n = 0;n <dz->bufcnt; n++)
  1883. dz->flbufptr[n] = NULL;
  1884. }
  1885. for(n=0;n<dz->bufcnt;n++)
  1886. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  1887. dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  1888. // FRACTAL
  1889. // dz->sampbuf[0] ibuf
  1890. // dz->sampbuf[1] iovflwbuf
  1891. // dz->sampbuf[2] obuf
  1892. // dz->sampbuf[3] ovflwbuf dz->sampbuf[4] end of ovflwbuf
  1893. // FRACSPEC
  1894. // dz->sampbuf[0] ibuf
  1895. // dz->sampbuf[1] obuf
  1896. if(dz->process == FRACTAL && dz->mode == 1) {
  1897. if((exit_status = read_samps(dz->sampbuf[0],dz))<0) // Read source into buffer
  1898. return(exit_status);
  1899. for(n=0, m = dz->insams[0];n < dz->infile->channels;n++,m++)
  1900. dz->sampbuf[0][m] = 0; // wraparound points go into iovflwbuf
  1901. dz->convertor = (double)dz->insams[0]/srate; // Table-read convertor for a 1Hz read
  1902. dz->convertor *= dz->startfrq; // Table-read convertor for a fractal-startfrq read
  1903. }
  1904. return FINISHED;
  1905. }
  1906. /********************************** SPECTRNSF **********************************
  1907. *
  1908. * transpose spectrum, but retain original spectral envelope.
  1909. */
  1910. int fractal_spectrnsf(double transpose,dataptr dz)
  1911. {
  1912. int exit_status;
  1913. double pre_totalamp, post_totalamp;
  1914. int cc, vc;
  1915. rectify_window(dz->flbufptr[0],dz);
  1916. if((exit_status = fractal_extract_specenv(dz))<0)
  1917. return(exit_status);
  1918. if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
  1919. return(exit_status);
  1920. if(dz->vflag[1]) {
  1921. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
  1922. dz->flbufptr[0][FREQ] = (float)(fabs(dz->flbufptr[0][FREQ])*transpose);
  1923. } else {
  1924. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  1925. if((exit_status = fractal_tranpose_within_formant_envelope(vc,transpose,dz))<0)
  1926. return(exit_status);
  1927. }
  1928. }
  1929. if((exit_status = fractal_reposition_partials_in_appropriate_channels(transpose,dz))<0)
  1930. return(exit_status);
  1931. if((exit_status = get_totalamp(&post_totalamp,dz->flbufptr[0],dz->wanted))<0)
  1932. return(exit_status);
  1933. return normalise(pre_totalamp,post_totalamp,dz);
  1934. }
  1935. /************************** TRANPOSE_WITHIN_FORMANT_ENVELOPE *****************************/
  1936. int fractal_tranpose_within_formant_envelope(int vc,double transpose,dataptr dz)
  1937. {
  1938. int exit_status;
  1939. double thisspecamp, newspecamp, thisamp, formantamp_ratio;
  1940. if((exit_status = fractal_getspecenvamp(&thisspecamp,(double)dz->flbufptr[0][FREQ],dz))<0)
  1941. return(exit_status);
  1942. dz->flbufptr[0][FREQ] = (float)(fabs(dz->flbufptr[0][FREQ])*transpose);
  1943. if(dz->flbufptr[0][FREQ] < dz->nyquist) {
  1944. if(thisspecamp < VERY_TINY_VAL)
  1945. dz->flbufptr[0][AMPP] = 0.0f;
  1946. else {
  1947. if((exit_status = fractal_getspecenvamp(&newspecamp,(double)dz->flbufptr[0][FREQ],dz))<0)
  1948. return(exit_status);
  1949. if(newspecamp < VERY_TINY_VAL)
  1950. dz->flbufptr[0][AMPP] = 0.0f;
  1951. else {
  1952. formantamp_ratio = newspecamp/thisspecamp;
  1953. if((thisamp = dz->flbufptr[0][AMPP] * formantamp_ratio) < VERY_TINY_VAL)
  1954. dz->flbufptr[0][AMPP] = 0.0f;
  1955. else
  1956. dz->flbufptr[0][AMPP] = (float)thisamp;
  1957. }
  1958. }
  1959. }
  1960. return(FINISHED);
  1961. }
  1962. /************************ REPOSITION_PARTIALS_IN_APPROPRIATE_CHANNELS *************************
  1963. *
  1964. * (1) At each pass, preset store-buffer channel amps to zero.
  1965. * (2) Move frq data into appropriate channels, carrying the
  1966. * amplitude information along with them.
  1967. * Work down spectrum for upward transposition, and
  1968. * (3) up spectrum for downward transposition,
  1969. * so that we do not overwrite transposed data before we move it.
  1970. * (4) Put new frqs back into src buff.
  1971. */
  1972. int fractal_reposition_partials_in_appropriate_channels(double transpose,dataptr dz)
  1973. {
  1974. int exit_status;
  1975. int truecc,truevc;
  1976. int cc, vc;
  1977. for(vc = 0, cc= 0; vc < dz->wanted; vc+=2, cc++) { /* 1 */
  1978. dz->windowbuf[0][AMPP] = 0.0f;
  1979. dz->windowbuf[0][FREQ] = (float)(cc * dz->chwidth);
  1980. }
  1981. if(transpose > 1.0f) { /* 2 */
  1982. for(cc=dz->clength-1,vc = dz->wanted-2; cc>=0; cc--, vc-=2) {
  1983. if(dz->flbufptr[0][FREQ] < dz->nyquist && dz->flbufptr[0][AMPP] > 0.0f) {
  1984. if((exit_status = fractal_get_channel_corresponding_to_frq(&truecc,(double)dz->flbufptr[0][FREQ],dz))<0)
  1985. return(exit_status);
  1986. truevc = truecc * 2;
  1987. if((exit_status = move_data_into_appropriate_channel(vc,truevc,dz->flbufptr[0][AMPP],dz->flbufptr[0][FREQ],dz))<0)
  1988. return(exit_status);
  1989. }
  1990. }
  1991. for(vc = 0; vc < dz->wanted; vc++)
  1992. dz->flbufptr[0][vc] = dz->windowbuf[0][vc];
  1993. } else if(transpose < 1.0f){ /* 3 */
  1994. for(cc=0,vc = 0; cc < dz->clength; cc++, vc+=2) {
  1995. if(dz->flbufptr[0][FREQ] < dz->nyquist && dz->flbufptr[0][FREQ]>0.0) {
  1996. if((exit_status = fractal_get_channel_corresponding_to_frq(&truecc,(double)dz->flbufptr[0][FREQ],dz))<0)
  1997. return(exit_status);
  1998. truevc = truecc * 2;
  1999. if((exit_status = move_data_into_appropriate_channel(vc,truevc,dz->flbufptr[0][AMPP],dz->flbufptr[0][FREQ],dz))<0)
  2000. return(exit_status);
  2001. }
  2002. }
  2003. for(vc = 0; vc < dz->wanted; vc++)
  2004. dz->flbufptr[0][vc] = dz->windowbuf[0][vc]; /* 4 */
  2005. }
  2006. return(FINISHED);
  2007. }
  2008. /******************* ZERO_OUTOFRANGE_CHANNELS *****************/
  2009. int fractal_zero_outofrange_channels(double *totalamp,double lofrq_limit,double hifrq_limit,dataptr dz)
  2010. {
  2011. int cc, vc;
  2012. *totalamp = 0.0;
  2013. for(cc = 0,vc = 0; cc < dz->clength; cc++, vc += 2) {
  2014. if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
  2015. dz->flbufptr[0][AMPP] = 0.0f;
  2016. else
  2017. *totalamp += dz->flbufptr[0][AMPP];
  2018. }
  2019. return(FINISHED);
  2020. }
  2021. /**************************** GETSPECENVAMP *************************/
  2022. int fractal_getspecenvamp(double *thisamp,double thisfrq,dataptr dz)
  2023. {
  2024. double pp, ratio, ampdiff;
  2025. int z = 1;
  2026. if(thisfrq<0.0) { /* NOT SURE THIS IS CORRECT */
  2027. *thisamp = 0.0; /* SHOULD WE PHASE INVERT & RETURN A -ve AMP ?? */
  2028. return(FINISHED);
  2029. }
  2030. if(thisfrq<=1.0)
  2031. pp = 0.0;
  2032. else
  2033. pp = log10(thisfrq);
  2034. while( dz->specenvpch[z] < pp){
  2035. z++;
  2036. /*RWD may need to trap on size of array? */
  2037. if(z == dz->infile->specenvcnt -1)
  2038. break;
  2039. }
  2040. ratio = (pp - dz->specenvpch[z-1])/(dz->specenvpch[z] - dz->specenvpch[z-1]);
  2041. ampdiff = dz->specenvamp[z] - dz->specenvamp[z-1];
  2042. *thisamp = dz->specenvamp[z-1] + (ampdiff * ratio);
  2043. *thisamp = max(0.0,*thisamp);
  2044. return(FINISHED);
  2045. }
  2046. /********************** EXTRACT_SPECENV *******************/
  2047. int fractal_extract_specenv(dataptr dz)
  2048. {
  2049. int n, cc, vc, specenvcnt_less_one;
  2050. int botchan, topchan;
  2051. double botfreq, topfreq;
  2052. double bwidth_in_chans;
  2053. specenvcnt_less_one = dz->infile->specenvcnt - 1;
  2054. vc = 0;
  2055. // RECTIFY_CHANNEL_FRQ_ORDER
  2056. for(n=0;n<dz->infile->specenvcnt;n++)
  2057. dz->specenvamp[n] = (float)0.0;
  2058. topfreq = 0.0f;
  2059. n = 0;
  2060. while(n < specenvcnt_less_one) {
  2061. botfreq = topfreq;
  2062. botchan = (int)((botfreq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  2063. botchan -= 4; // CHAN_SRCHRANGE_F
  2064. botchan = max(botchan,0);
  2065. topfreq = dz->specenvtop[n];
  2066. topchan = (int)((topfreq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  2067. topchan += 4; // CHAN_SRCHRANGE_F;
  2068. topchan = min(topchan,dz->clength);
  2069. for(cc = botchan,vc = botchan * 2; cc < topchan; cc++,vc += 2) {
  2070. if(dz->flbufptr[0][FREQ] >= botfreq && dz->flbufptr[0][FREQ] < topfreq)
  2071. dz->specenvamp[n] = (float)(dz->specenvamp[n] + dz->flbufptr[0][AMPP]);
  2072. }
  2073. bwidth_in_chans = (double)(topfreq - botfreq)/dz->chwidth;
  2074. dz->specenvamp[n] = (float)(dz->specenvamp[n]/bwidth_in_chans);
  2075. n++;
  2076. }
  2077. return(FINISHED);
  2078. }
  2079. /************************** INITIALISE_SPECENV *********************
  2080. *
  2081. * MAR 1998: not sure if the follwoing comment is relevant any more
  2082. * but I wont risk changing it at this stage.
  2083. *
  2084. * WANTED and CLENGTH are calculated from scratch here, as dz->wanted
  2085. * gets set equal to dz->specenvcnt for calculations on formant data,
  2086. * while dz->clength may not yet be set!!
  2087. */
  2088. int fractal_initialise_specenv(int *arraycnt,dataptr dz)
  2089. {
  2090. *arraycnt = (dz->infile->channels/2) + 1;
  2091. if((dz->specenvfrq = (float *)malloc((*arraycnt) * sizeof(float)))==NULL) {
  2092. sprintf(errstr,"INSUFFICIENT MEMORY for formant frq array.\n");
  2093. return(MEMORY_ERROR);
  2094. }
  2095. if((dz->specenvpch = (float *)malloc((*arraycnt) * sizeof(float)))==NULL) {
  2096. sprintf(errstr,"INSUFFICIENT MEMORY for formant pitch array.\n");
  2097. return(MEMORY_ERROR);
  2098. }
  2099. /*RWD zero the data */
  2100. memset(dz->specenvpch,0,*arraycnt * sizeof(float));
  2101. if((dz->specenvamp = (float *)malloc((*arraycnt) * sizeof(float)))==NULL) {
  2102. sprintf(errstr,"INSUFFICIENT MEMORY for formant aplitude array.\n");
  2103. return(MEMORY_ERROR);
  2104. }
  2105. if((dz->specenvtop = (float *)malloc((*arraycnt) * sizeof(float)))==NULL) {
  2106. sprintf(errstr,"INSUFFICIENT MEMORY for formant frq limit array.\n");
  2107. return(MEMORY_ERROR);
  2108. }
  2109. if((dz->windowbuf = (float **)malloc(sizeof(float *)))==NULL) {
  2110. sprintf(errstr,"INSUFFICIENT MEMORY for extra float sample buffers.\n");
  2111. return(MEMORY_ERROR);
  2112. }
  2113. if((dz->windowbuf[0] = (float *)malloc(dz->wanted * sizeof(float)))==NULL) {
  2114. sprintf(errstr,"INSUFFICIENT MEMORY for extra float sample buffer 0.\n");
  2115. return(MEMORY_ERROR);
  2116. }
  2117. return(FINISHED);
  2118. }
  2119. /************************************ FRACTAL_SET_SPECENV_FRQS ****************************/
  2120. int fractal_set_specenv_frqs(int arraycnt,dataptr dz)
  2121. {
  2122. int exit_status;
  2123. double bandbot;
  2124. double *interval;
  2125. int m, n, k = 0, cc;
  2126. // PICHWISE_FORMANTS
  2127. if((exit_status = fractal_setup_octaveband_steps(&interval,dz))<0)
  2128. return(exit_status);
  2129. if((exit_status = fractal_setup_low_octave_bands(arraycnt,dz))<0)
  2130. return(exit_status);
  2131. k = 4; // TOP_OF_LOW_OCTAVE_BANDS
  2132. cc = 8; // CHAN_ABOVE_LOW_OCTAVES
  2133. while(cc <= dz->clength) {
  2134. m = 0;
  2135. if((bandbot = dz->chwidth * (double)cc) >= dz->nyquist)
  2136. break;
  2137. for(n=0;n<dz->formant_bands;n++) {
  2138. if(k >= arraycnt) {
  2139. sprintf(errstr,"Formant array too small: fractal_set_specenv_frqs()\n");
  2140. return(PROGRAM_ERROR);
  2141. }
  2142. dz->specenvfrq[k] = (float)(bandbot * interval[m++]);
  2143. dz->specenvpch[k] = (float)log10(dz->specenvfrq[k]);
  2144. dz->specenvtop[k++] = (float)(bandbot * interval[m++]);
  2145. }
  2146. cc *= 2; /* 8-16: 16-32: 32-64 etc as 8vas, then split into bands */
  2147. }
  2148. dz->specenvfrq[k] = (float)dz->nyquist;
  2149. dz->specenvpch[k] = (float)log10(dz->nyquist);
  2150. dz->specenvtop[k] = (float)dz->nyquist;
  2151. dz->specenvamp[k] = (float)0.0;
  2152. k++;
  2153. dz->infile->specenvcnt = k;
  2154. return(FINISHED);
  2155. }
  2156. /************************* SETUP_OCTAVEBAND_STEPS ************************/
  2157. int fractal_setup_octaveband_steps(double **interval,dataptr dz)
  2158. {
  2159. double octave_step;
  2160. int n = 1, m = 0, halfbands_per_octave = dz->formant_bands * 2;
  2161. if((*interval = (double *)malloc(halfbands_per_octave * sizeof(double)))==NULL) {
  2162. sprintf(errstr,"INSUFFICIENT MEMORY establishing interval array for formants.\n");
  2163. return(MEMORY_ERROR);
  2164. }
  2165. while(n < halfbands_per_octave) {
  2166. octave_step = (double)n++/(double)halfbands_per_octave;
  2167. (*interval)[m++] = pow(2.0,octave_step);
  2168. }
  2169. (*interval)[m] = 2.0;
  2170. return(FINISHED);
  2171. }
  2172. /************************ SETUP_LOW_OCTAVE_BANDS ***********************
  2173. *
  2174. * Lowest PVOC channels span larger freq steps and therefore we must
  2175. * group them in octave bands, rather than in anything smaller.
  2176. */
  2177. int fractal_setup_low_octave_bands(int arraycnt,dataptr dz)
  2178. {
  2179. int n;
  2180. if(arraycnt < LOW_OCTAVE_BANDS) {
  2181. sprintf(errstr,"Insufficient array space for low_octave_bands\n");
  2182. return(PROGRAM_ERROR);
  2183. }
  2184. for(n=0;n<LOW_OCTAVE_BANDS;n++) {
  2185. switch(n) {
  2186. case(0):
  2187. dz->specenvfrq[0] = (float)1.0; /* frq whose log is 0 */
  2188. dz->specenvpch[0] = (float)0.0;
  2189. dz->specenvtop[0] = (float)dz->chwidth; /* 8VA wide bands */
  2190. break;
  2191. case(1):
  2192. dz->specenvfrq[1] = (float)(dz->chwidth * 1.5); /* Centre Chs 1-2 */
  2193. dz->specenvpch[1] = (float)log10(dz->specenvfrq[1]);
  2194. dz->specenvtop[1] = (float)(dz->chwidth * 2.0);
  2195. break;
  2196. case(2):
  2197. dz->specenvfrq[2] = (float)(dz->chwidth * 3.0); /* Centre Chs 2-4 */
  2198. dz->specenvpch[2] = (float)log10(dz->specenvfrq[2]);
  2199. dz->specenvtop[2] = (float)(dz->chwidth * 4.0);
  2200. break;
  2201. case(3):
  2202. dz->specenvfrq[3] = (float)(dz->chwidth * 6.0); /* Centre Chs 4-8 */
  2203. dz->specenvpch[3] = (float)log10(dz->specenvfrq[3]);
  2204. dz->specenvtop[3] = (float)(dz->chwidth * 8.0);
  2205. break;
  2206. default:
  2207. sprintf(errstr,"Insufficient low octave band setups in fractal_setup_low_octave_bands()\n");
  2208. return(PROGRAM_ERROR);
  2209. }
  2210. }
  2211. return(FINISHED);
  2212. }
  2213. /**************************** GET_CHANNEL_CORRESPONDING_TO_FRQ ***************************/
  2214. int fractal_get_channel_corresponding_to_frq(int *chan,double thisfrq,dataptr dz)
  2215. {
  2216. if(dz->chwidth <= 0.0) {
  2217. sprintf(errstr,"chwidth not set in fractal_get_channel_corresponding_to_frq()\n");
  2218. return(PROGRAM_ERROR);
  2219. }
  2220. if(thisfrq < 0.0) {
  2221. sprintf(errstr,"-ve frequency in fractal_get_channel_corresponding_to_frq()\n");
  2222. return(PROGRAM_ERROR);
  2223. }
  2224. if(thisfrq > dz->nyquist) {
  2225. sprintf(errstr,"frequency beyond nyquist in fractal_get_channel_corresponding_to_frq()\n");
  2226. return(PROGRAM_ERROR);
  2227. }
  2228. *chan = (int)((fabs(thisfrq) + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  2229. if(*chan >= dz->clength) {
  2230. sprintf(errstr,"chan (%d) beyond clength-1 (%d) returned: fractal_get_channel_corresponding_to_frq()\n",
  2231. *chan,(dz->clength)-1);
  2232. return(PROGRAM_ERROR);
  2233. }
  2234. return(FINISHED);
  2235. }