splinter.c 101 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253
  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. // _cdprogs\splinter splinter 1 testfrac.wav testsplint2.wav 0.710884 240 16 16 10 10 -e0 -s1 -p1 -f6000 -r0 -v0
  22. //CRASHES ..... seems to be the waveset count that crashes it
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <structures.h>
  26. #include <tkglobals.h>
  27. #include <pnames.h>
  28. #include <filetype.h>
  29. #include <processno.h>
  30. #include <modeno.h>
  31. #include <logic.h>
  32. #include <globcon.h>
  33. #include <cdpmain.h>
  34. #include <math.h>
  35. #include <mixxcon.h>
  36. #include <osbind.h>
  37. #include <standalone.h>
  38. #include <science.h>
  39. #include <ctype.h>
  40. #include <sfsys.h>
  41. #include <string.h>
  42. #include <srates.h>
  43. #ifdef unix
  44. #define round(x) lround((x))
  45. #endif
  46. char errstr[2400];
  47. #define QCYCLEMIN 2 // Minimum size of a shrunk quartercycle
  48. #define SPLENVWIN 20 // Windowsize, in mS, for extracting envelope, used to normalise output, if "-i" flag set.
  49. #define SPLMAXSPL 10 // Max duration of selected waveset-group = 10 seconds
  50. #define SPLSPLICE 2 // Splicelen in mS
  51. #define quartercyclecnt is_mapping // number of values marking the zero-crossings, maxima and minima of wavesetgroup
  52. #define envwindowsize rampbrksize // sample-size of window used for normalising envelope
  53. #define wavesetgrplen total_windows // Length of original wavesetgroup (samples)
  54. #define target wlength // Position of wavesetgroup in infile (samples)
  55. #define splintoffset wanted // Length of splinter-set prior to wavesetgroup
  56. #define arraysize itemcnt
  57. #define wmaxmpos extra_word
  58. #define splicelen ringsize
  59. #define enddur all_words
  60. #define minlen numsize
  61. int anal_infiles = 1;
  62. int sloom = 0;
  63. int sloombatch = 0;
  64. const char* cdp_version = "6.1.0";
  65. //CDP LIB REPLACEMENTS
  66. static int check_splinter_param_validity_and_consistency(dataptr dz);
  67. static int setup_splinter_application(dataptr dz);
  68. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  69. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  70. static int setup_splinter_param_ranges_and_defaults(dataptr dz);
  71. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  72. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  73. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  74. static int establish_application(dataptr dz);
  75. static int initialise_vflags(dataptr dz);
  76. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  77. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  78. static int mark_parameter_types(dataptr dz,aplptr ap);
  79. static int assign_file_data_storage(int infilecnt,dataptr dz);
  80. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  81. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  82. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  83. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  84. static int splinter_param_preprocess(int *initial_phase,dataptr dz);
  85. static int create_splinter_sndbufs1(dataptr dz);
  86. static int generate_envelope_array_storage(dataptr dz);
  87. static int create_splinter_sndbufs2(dataptr dz);
  88. static int find_wavesets(int *initial_phase,dataptr dz);
  89. static int store_wavesets(int initial_phase,dataptr dz);
  90. static int generate_shrinkage_set(dataptr dz);
  91. static int generate_timing_set(dataptr dz);
  92. static int shrink_waveset(double shrink,int *splinterlen,dataptr dz);
  93. static int normalise_buffer(int windowing_end,dataptr dz);
  94. static int create_temp_sndbuf(dataptr dz);
  95. static int splinter(dataptr dz);
  96. /**************************************** MAIN *********************************************/
  97. int main(int argc,char *argv[])
  98. {
  99. int exit_status, initial_phase = 0;
  100. dataptr dz = NULL;
  101. char **cmdline;
  102. int cmdlinecnt;
  103. int n;
  104. // aplptr ap;
  105. int is_launched = FALSE;
  106. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  107. fprintf(stdout,"%s\n",cdp_version);
  108. fflush(stdout);
  109. return 0;
  110. }
  111. /* CHECK FOR SOUNDLOOM */
  112. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  113. sloom = 0;
  114. sloombatch = 1;
  115. }
  116. if(sflinit("cdp")){
  117. sfperror("cdp: initialisation\n");
  118. return(FAILED);
  119. }
  120. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  121. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  122. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  123. return(FAILED);
  124. }
  125. if(!sloom) {
  126. if(argc == 1) {
  127. usage1();
  128. return(FAILED);
  129. } else if(argc == 2) {
  130. usage2(argv[1]);
  131. return(FAILED);
  132. }
  133. }
  134. if(!sloom) {
  135. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  136. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  137. return(FAILED);
  138. }
  139. cmdline = argv;
  140. cmdlinecnt = argc;
  141. if((get_the_process_no(argv[0],dz))<0)
  142. return(FAILED);
  143. cmdline++;
  144. cmdlinecnt--;
  145. dz->maxmode = 4;
  146. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  147. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  148. return(exit_status);
  149. }
  150. cmdline++;
  151. cmdlinecnt--;
  152. // setup_particular_application =
  153. if((exit_status = setup_splinter_application(dz))<0) {
  154. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  155. return(FAILED);
  156. }
  157. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  158. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  159. return(FAILED);
  160. }
  161. } else {
  162. //parse_TK_data() =
  163. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  164. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  165. return(exit_status);
  166. }
  167. }
  168. // ap = dz->application;
  169. // parse_infile_and_hone_type() =
  170. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  171. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  172. return(FAILED);
  173. }
  174. // setup_param_ranges_and_defaults() =
  175. if((exit_status = setup_splinter_param_ranges_and_defaults(dz))<0) {
  176. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  177. return(FAILED);
  178. }
  179. // open_first_infile CDP LIB
  180. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  181. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  182. return(FAILED);
  183. }
  184. cmdlinecnt--;
  185. cmdline++;
  186. // handle_extra_infiles() : redundant
  187. // handle_outfile() =
  188. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  189. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  190. return(FAILED);
  191. }
  192. // handle_formants() redundant
  193. // handle_formant_quiksearch() redundant
  194. // handle_special_data() redundant
  195. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  196. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  197. return(FAILED);
  198. }
  199. // check_param_validity_and_consistency....
  200. if((exit_status = check_splinter_param_validity_and_consistency(dz))<0) {
  201. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  202. return(FAILED);
  203. }
  204. is_launched = TRUE;
  205. dz->bufcnt = 5;
  206. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  207. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  208. return(MEMORY_ERROR);
  209. }
  210. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  211. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  212. return(MEMORY_ERROR);
  213. }
  214. for(n = 0;n <dz->bufcnt; n++)
  215. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  216. dz->sampbuf[n] = (float *)0;
  217. //param_preprocess() ...
  218. if((exit_status = splinter_param_preprocess(&initial_phase,dz))<0) {
  219. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  220. return(FAILED);
  221. } //spec_process_file =
  222. if((exit_status = create_splinter_sndbufs1(dz))<0) {
  223. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  224. return(FAILED);
  225. }
  226. if((exit_status = generate_envelope_array_storage(dz))<0) {
  227. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  228. return(FAILED);
  229. }
  230. if((exit_status = create_splinter_sndbufs2(dz))<0) {
  231. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  232. return(FAILED);
  233. }
  234. if((exit_status = store_wavesets(initial_phase,dz))<0) {
  235. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  236. return(FAILED);
  237. }
  238. if((exit_status = splinter(dz))<0) {
  239. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  240. return(FAILED);
  241. }
  242. if((exit_status = complete_output(dz))<0) { // CDP LIB
  243. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  244. return(FAILED);
  245. }
  246. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  247. free(dz);
  248. return(SUCCEEDED);
  249. }
  250. /**********************************************
  251. REPLACED CDP LIB FUNCTIONS
  252. **********************************************/
  253. /****************************** SET_PARAM_DATA *********************************/
  254. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  255. {
  256. ap->special_data = (char)special_data;
  257. ap->param_cnt = (char)paramcnt;
  258. ap->max_param_cnt = (char)maxparamcnt;
  259. if(ap->max_param_cnt>0) {
  260. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  261. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  262. return(MEMORY_ERROR);
  263. }
  264. strcpy(ap->param_list,paramlist);
  265. }
  266. return(FINISHED);
  267. }
  268. /****************************** SET_VFLGS *********************************/
  269. int set_vflgs
  270. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  271. {
  272. ap->option_cnt = (char) optcnt; /*RWD added cast */
  273. if(optcnt) {
  274. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  275. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  276. return(MEMORY_ERROR);
  277. }
  278. strcpy(ap->option_list,optlist);
  279. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  280. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  281. return(MEMORY_ERROR);
  282. }
  283. strcpy(ap->option_flags,optflags);
  284. }
  285. ap->vflag_cnt = (char) vflagcnt;
  286. ap->variant_param_cnt = (char) vparamcnt;
  287. if(vflagcnt) {
  288. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  289. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  290. return(MEMORY_ERROR);
  291. }
  292. strcpy(ap->variant_list,varlist);
  293. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  294. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  295. return(MEMORY_ERROR);
  296. }
  297. strcpy(ap->variant_flags,varflags);
  298. }
  299. return(FINISHED);
  300. }
  301. /***************************** APPLICATION_INIT **************************/
  302. int application_init(dataptr dz)
  303. {
  304. int exit_status;
  305. int storage_cnt;
  306. int tipc, brkcnt;
  307. aplptr ap = dz->application;
  308. if(ap->vflag_cnt>0)
  309. initialise_vflags(dz);
  310. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  311. ap->total_input_param_cnt = (char)tipc;
  312. if(tipc>0) {
  313. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  314. return(exit_status);
  315. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  316. return(exit_status);
  317. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  318. return(exit_status);
  319. }
  320. brkcnt = tipc;
  321. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  322. if(brkcnt>0) {
  323. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  324. return(exit_status);
  325. }
  326. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  327. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  328. return(exit_status);
  329. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  330. return(exit_status);
  331. }
  332. if((exit_status = mark_parameter_types(dz,ap))<0)
  333. return(exit_status);
  334. // establish_infile_constants() replaced by
  335. dz->infilecnt = 1;
  336. //establish_bufptrs_and_extra_buffers():
  337. return(FINISHED);
  338. }
  339. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  340. /* RWD mallo changed to calloc; helps debug verison run as release! */
  341. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  342. {
  343. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  344. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  345. return(MEMORY_ERROR);
  346. }
  347. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  348. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  349. return(MEMORY_ERROR);
  350. }
  351. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  352. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  353. return(MEMORY_ERROR);
  354. }
  355. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  356. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  357. return(MEMORY_ERROR);
  358. }
  359. return(FINISHED);
  360. }
  361. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  362. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  363. {
  364. int n;
  365. for(n=0;n<storage_cnt;n++) {
  366. dz->is_int[n] = (char)0;
  367. dz->no_brk[n] = (char)0;
  368. }
  369. return(FINISHED);
  370. }
  371. /***************************** MARK_PARAMETER_TYPES **************************/
  372. int mark_parameter_types(dataptr dz,aplptr ap)
  373. {
  374. int n, m; /* PARAMS */
  375. for(n=0;n<ap->max_param_cnt;n++) {
  376. switch(ap->param_list[n]) {
  377. case('0'): break; /* dz->is_active[n] = 0 is default */
  378. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  379. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  380. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  381. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  382. default:
  383. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  384. return(PROGRAM_ERROR);
  385. }
  386. } /* OPTIONS */
  387. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  388. switch(ap->option_list[n]) {
  389. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  390. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  391. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  392. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  393. default:
  394. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  395. return(PROGRAM_ERROR);
  396. }
  397. } /* VARIANTS */
  398. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  399. switch(ap->variant_list[n]) {
  400. case('0'): break;
  401. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  402. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  403. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  404. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  405. default:
  406. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  407. return(PROGRAM_ERROR);
  408. }
  409. } /* INTERNAL */
  410. for(n=0,
  411. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  412. switch(ap->internal_param_list[n]) {
  413. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  414. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  415. case('d'): dz->no_brk[m] = (char)1; break;
  416. default:
  417. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  418. return(PROGRAM_ERROR);
  419. }
  420. }
  421. return(FINISHED);
  422. }
  423. /************************ HANDLE_THE_OUTFILE *********************/
  424. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  425. {
  426. int exit_status;
  427. char *filename = (*cmdline)[0];
  428. if(filename[0]=='-' && filename[1]=='f') {
  429. dz->floatsam_output = 1;
  430. dz->true_outfile_stype = SAMP_FLOAT;
  431. filename+= 2;
  432. }
  433. if(!sloom) {
  434. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  435. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  436. return(DATA_ERROR);
  437. }
  438. }
  439. strcpy(dz->outfilename,filename);
  440. if((exit_status = create_sized_outfile(filename,dz))<0)
  441. return(exit_status);
  442. (*cmdline)++;
  443. (*cmdlinecnt)--;
  444. return(FINISHED);
  445. }
  446. /***************************** ESTABLISH_APPLICATION **************************/
  447. int establish_application(dataptr dz)
  448. {
  449. aplptr ap;
  450. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  451. sprintf(errstr,"establish_application()\n");
  452. return(MEMORY_ERROR);
  453. }
  454. ap = dz->application;
  455. memset((char *)ap,0,sizeof(struct applic));
  456. return(FINISHED);
  457. }
  458. /************************* INITIALISE_VFLAGS *************************/
  459. int initialise_vflags(dataptr dz)
  460. {
  461. int n;
  462. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  463. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  464. return(MEMORY_ERROR);
  465. }
  466. for(n=0;n<dz->application->vflag_cnt;n++)
  467. dz->vflag[n] = FALSE;
  468. return FINISHED;
  469. }
  470. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  471. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  472. {
  473. int n;
  474. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  475. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  476. return(MEMORY_ERROR);
  477. }
  478. for(n=0;n<tipc;n++)
  479. ap->default_val[n] = 0.0;
  480. return(FINISHED);
  481. }
  482. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  483. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  484. {
  485. int n;
  486. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  487. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  488. return(MEMORY_ERROR);
  489. }
  490. for(n=0;n<tipc;n++)
  491. dz->is_active[n] = (char)0;
  492. return(FINISHED);
  493. }
  494. /************************* SETUP_SPLINTER_APPLICATION *******************/
  495. int setup_splinter_application(dataptr dz)
  496. {
  497. int exit_status;
  498. aplptr ap;
  499. if((exit_status = establish_application(dz))<0) // GLOBAL
  500. return(FAILED);
  501. ap = dz->application;
  502. // SEE parstruct FOR EXPLANATION of next 2 functions
  503. if((exit_status = set_param_data(ap,0 ,6,6,"diiidd"))<0)
  504. return(FAILED);
  505. if(dz->mode <= 1)
  506. exit_status = set_vflgs(ap,"espfrv",6,"idddDD","iI",2,0,"00");
  507. else
  508. exit_status = set_vflgs(ap,"espdrv",6,"idddDD","iI",2,0,"00");
  509. if(exit_status<0)
  510. return(FAILED);
  511. // set_legal_infile_structure -->
  512. dz->has_otherfile = FALSE;
  513. // assign_process_logic -->
  514. dz->input_data_type = SNDFILES_ONLY;
  515. dz->process_type = UNEQUAL_SNDFILE;
  516. dz->outfiletype = SNDFILE_OUT;
  517. return application_init(dz); //GLOBAL
  518. }
  519. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  520. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  521. {
  522. int exit_status;
  523. infileptr infile_info;
  524. if(!sloom) {
  525. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  526. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  527. return(MEMORY_ERROR);
  528. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  529. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  530. return(PROGRAM_ERROR);
  531. } else if(infile_info->filetype != SNDFILE) {
  532. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  533. return(DATA_ERROR);
  534. } else if(infile_info->channels != 1) {
  535. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  536. return(DATA_ERROR);
  537. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  538. sprintf(errstr,"Failed to copy file parsing information\n");
  539. return(PROGRAM_ERROR);
  540. }
  541. free(infile_info);
  542. }
  543. return(FINISHED);
  544. }
  545. /************************* SETUP_SPLINTER_PARAM_RANGES_AND_DEFAULTS *******************/
  546. int setup_splinter_param_ranges_and_defaults(dataptr dz)
  547. {
  548. int exit_status;
  549. aplptr ap = dz->application;
  550. // set_param_ranges()
  551. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  552. // NB total_input_param_cnt is > 0 !!!
  553. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  554. return(FAILED);
  555. // get_param_ranges()
  556. ap->lo[SPL_TIME] = 0.0;
  557. ap->hi[SPL_TIME] = dz->duration;
  558. ap->default_val[SPL_TIME] = 0.0;
  559. ap->lo[SPL_WCNT] = 0;
  560. ap->hi[SPL_WCNT] = 256;
  561. ap->default_val[SPL_WCNT] = 1;
  562. ap->lo[SPL_SHRCNT] = 2;
  563. ap->hi[SPL_SHRCNT] = 256;
  564. ap->default_val[SPL_SHRCNT] = SHRCNT_DFLT;
  565. ap->lo[SPL_OCNT] = 0;
  566. ap->hi[SPL_OCNT] = 256;
  567. ap->default_val[SPL_OCNT] = OCNT_DFLT;
  568. ap->lo[SPL_PULS1] = 0;
  569. ap->hi[SPL_PULS1] = 50;
  570. ap->default_val[SPL_PULS1] = PULS_DFLT;
  571. ap->lo[SPL_PULS2] = 0;
  572. ap->hi[SPL_PULS2] = 50;
  573. ap->default_val[SPL_PULS2] = PULS_DFLT;
  574. ap->lo[SPL_ECNT] = 0;
  575. ap->hi[SPL_ECNT] = 10000;
  576. ap->default_val[SPL_ECNT] = 0;
  577. ap->lo[SPL_SCURVE] = 0.1;
  578. ap->hi[SPL_SCURVE] = 10.0;
  579. ap->default_val[SPL_SCURVE] = 1;
  580. ap->lo[SPL_PCURVE] = 0.1;
  581. ap->hi[SPL_PCURVE] = 10.0;
  582. ap->default_val[SPL_PCURVE] = 1;
  583. if(dz->mode <= 1) {
  584. ap->lo[SPL_FRQ] = 1000.0;
  585. ap->hi[SPL_FRQ] = dz->nyquist/2.0;
  586. ap->default_val[SPL_FRQ] = FREQ_DFLT;
  587. } else {
  588. ap->lo[SPL_DUR] = 5.0;
  589. ap->hi[SPL_DUR] = 50.0;
  590. ap->default_val[SPL_DUR] = 5.0;
  591. }
  592. ap->lo[SPL_RND] = 0.0;
  593. ap->hi[SPL_RND] = 1.0;
  594. ap->default_val[SPL_RND] = 0;
  595. ap->lo[SPL_SHRND] = 0.0;
  596. ap->hi[SPL_SHRND] = 1.0;
  597. ap->default_val[SPL_SHRND] = 0;
  598. dz->maxmode = 4;
  599. if(!sloom)
  600. put_default_vals_in_all_params(dz);
  601. return(FINISHED);
  602. }
  603. /********************************* PARSE_SLOOM_DATA *********************************/
  604. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  605. {
  606. int exit_status;
  607. int cnt = 1, infilecnt;
  608. int filesize, insams, inbrksize;
  609. double dummy;
  610. int true_cnt = 0;
  611. // aplptr ap;
  612. while(cnt<=PRE_CMDLINE_DATACNT) {
  613. if(cnt > argc) {
  614. sprintf(errstr,"Insufficient data sent from TK\n");
  615. return(DATA_ERROR);
  616. }
  617. switch(cnt) {
  618. case(1):
  619. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  620. sprintf(errstr,"Cannot read process no. sent from TK\n");
  621. return(DATA_ERROR);
  622. }
  623. break;
  624. case(2):
  625. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  626. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  627. return(DATA_ERROR);
  628. }
  629. if(dz->mode > 0)
  630. dz->mode--;
  631. //setup_particular_application() =
  632. if((exit_status = setup_splinter_application(dz))<0)
  633. return(exit_status);
  634. // ap = dz->application;
  635. break;
  636. case(3):
  637. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  638. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  639. return(DATA_ERROR);
  640. }
  641. if(infilecnt < 1) {
  642. true_cnt = cnt + 1;
  643. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  644. }
  645. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  646. return(exit_status);
  647. break;
  648. case(INPUT_FILETYPE+4):
  649. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  650. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  651. return(DATA_ERROR);
  652. }
  653. break;
  654. case(INPUT_FILESIZE+4):
  655. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  656. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  657. return(DATA_ERROR);
  658. }
  659. dz->insams[0] = filesize;
  660. break;
  661. case(INPUT_INSAMS+4):
  662. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  663. sprintf(errstr,"Cannot read insams sent from TK\n");
  664. return(DATA_ERROR);
  665. }
  666. dz->insams[0] = insams;
  667. break;
  668. case(INPUT_SRATE+4):
  669. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  670. sprintf(errstr,"Cannot read srate sent from TK\n");
  671. return(DATA_ERROR);
  672. }
  673. break;
  674. case(INPUT_CHANNELS+4):
  675. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  676. sprintf(errstr,"Cannot read channels sent from TK\n");
  677. return(DATA_ERROR);
  678. }
  679. break;
  680. case(INPUT_STYPE+4):
  681. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  682. sprintf(errstr,"Cannot read stype sent from TK\n");
  683. return(DATA_ERROR);
  684. }
  685. break;
  686. case(INPUT_ORIGSTYPE+4):
  687. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  688. sprintf(errstr,"Cannot read origstype sent from TK\n");
  689. return(DATA_ERROR);
  690. }
  691. break;
  692. case(INPUT_ORIGRATE+4):
  693. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  694. sprintf(errstr,"Cannot read origrate sent from TK\n");
  695. return(DATA_ERROR);
  696. }
  697. break;
  698. case(INPUT_MLEN+4):
  699. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  700. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  701. return(DATA_ERROR);
  702. }
  703. break;
  704. case(INPUT_DFAC+4):
  705. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  706. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  707. return(DATA_ERROR);
  708. }
  709. break;
  710. case(INPUT_ORIGCHANS+4):
  711. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  712. sprintf(errstr,"Cannot read origchans sent from TK\n");
  713. return(DATA_ERROR);
  714. }
  715. break;
  716. case(INPUT_SPECENVCNT+4):
  717. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  718. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  719. return(DATA_ERROR);
  720. }
  721. dz->specenvcnt = dz->infile->specenvcnt;
  722. break;
  723. case(INPUT_WANTED+4):
  724. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  725. sprintf(errstr,"Cannot read wanted sent from TK\n");
  726. return(DATA_ERROR);
  727. }
  728. break;
  729. case(INPUT_WLENGTH+4):
  730. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  731. sprintf(errstr,"Cannot read wlength sent from TK\n");
  732. return(DATA_ERROR);
  733. }
  734. break;
  735. case(INPUT_OUT_CHANS+4):
  736. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  737. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  738. return(DATA_ERROR);
  739. }
  740. break;
  741. /* RWD these chanegs to samps - tk will have to deal with that! */
  742. case(INPUT_DESCRIPTOR_BYTES+4):
  743. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  744. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  745. return(DATA_ERROR);
  746. }
  747. break;
  748. case(INPUT_IS_TRANSPOS+4):
  749. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  750. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  751. return(DATA_ERROR);
  752. }
  753. break;
  754. case(INPUT_COULD_BE_TRANSPOS+4):
  755. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  756. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  757. return(DATA_ERROR);
  758. }
  759. break;
  760. case(INPUT_COULD_BE_PITCH+4):
  761. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  762. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  763. return(DATA_ERROR);
  764. }
  765. break;
  766. case(INPUT_DIFFERENT_SRATES+4):
  767. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  768. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  769. return(DATA_ERROR);
  770. }
  771. break;
  772. case(INPUT_DUPLICATE_SNDS+4):
  773. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  774. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  775. return(DATA_ERROR);
  776. }
  777. break;
  778. case(INPUT_BRKSIZE+4):
  779. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  780. sprintf(errstr,"Cannot read brksize sent from TK\n");
  781. return(DATA_ERROR);
  782. }
  783. if(inbrksize > 0) {
  784. switch(dz->input_data_type) {
  785. case(WORDLIST_ONLY):
  786. break;
  787. case(PITCH_AND_PITCH):
  788. case(PITCH_AND_TRANSPOS):
  789. case(TRANSPOS_AND_TRANSPOS):
  790. dz->tempsize = inbrksize;
  791. break;
  792. case(BRKFILES_ONLY):
  793. case(UNRANGED_BRKFILE_ONLY):
  794. case(DB_BRKFILES_ONLY):
  795. case(ALL_FILES):
  796. case(ANY_NUMBER_OF_ANY_FILES):
  797. if(dz->extrabrkno < 0) {
  798. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  799. return(DATA_ERROR);
  800. }
  801. if(dz->brksize == NULL) {
  802. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  803. return(PROGRAM_ERROR);
  804. }
  805. dz->brksize[dz->extrabrkno] = inbrksize;
  806. break;
  807. default:
  808. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  809. dz->input_data_type);
  810. return(PROGRAM_ERROR);
  811. }
  812. break;
  813. }
  814. break;
  815. case(INPUT_NUMSIZE+4):
  816. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  817. sprintf(errstr,"Cannot read numsize sent from TK\n");
  818. return(DATA_ERROR);
  819. }
  820. break;
  821. case(INPUT_LINECNT+4):
  822. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  823. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  824. return(DATA_ERROR);
  825. }
  826. break;
  827. case(INPUT_ALL_WORDS+4):
  828. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  829. sprintf(errstr,"Cannot read all_words sent from TK\n");
  830. return(DATA_ERROR);
  831. }
  832. break;
  833. case(INPUT_ARATE+4):
  834. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  835. sprintf(errstr,"Cannot read arate sent from TK\n");
  836. return(DATA_ERROR);
  837. }
  838. break;
  839. case(INPUT_FRAMETIME+4):
  840. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  841. sprintf(errstr,"Cannot read frametime sent from TK\n");
  842. return(DATA_ERROR);
  843. }
  844. dz->frametime = (float)dummy;
  845. break;
  846. case(INPUT_WINDOW_SIZE+4):
  847. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  848. sprintf(errstr,"Cannot read window_size sent from TK\n");
  849. return(DATA_ERROR);
  850. }
  851. break;
  852. case(INPUT_NYQUIST+4):
  853. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  854. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  855. return(DATA_ERROR);
  856. }
  857. break;
  858. case(INPUT_DURATION+4):
  859. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  860. sprintf(errstr,"Cannot read duration sent from TK\n");
  861. return(DATA_ERROR);
  862. }
  863. break;
  864. case(INPUT_MINBRK+4):
  865. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  866. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  867. return(DATA_ERROR);
  868. }
  869. break;
  870. case(INPUT_MAXBRK+4):
  871. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  872. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  873. return(DATA_ERROR);
  874. }
  875. break;
  876. case(INPUT_MINNUM+4):
  877. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  878. sprintf(errstr,"Cannot read minnum sent from TK\n");
  879. return(DATA_ERROR);
  880. }
  881. break;
  882. case(INPUT_MAXNUM+4):
  883. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  884. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  885. return(DATA_ERROR);
  886. }
  887. break;
  888. default:
  889. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  890. return(PROGRAM_ERROR);
  891. }
  892. cnt++;
  893. }
  894. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  895. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  896. return(DATA_ERROR);
  897. }
  898. if(true_cnt)
  899. cnt = true_cnt;
  900. *cmdlinecnt = 0;
  901. while(cnt < argc) {
  902. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  903. return(exit_status);
  904. cnt++;
  905. }
  906. return(FINISHED);
  907. }
  908. /********************************* GET_TK_CMDLINE_WORD *********************************/
  909. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  910. {
  911. if(*cmdlinecnt==0) {
  912. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  913. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  914. return(MEMORY_ERROR);
  915. }
  916. } else {
  917. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  918. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  919. return(MEMORY_ERROR);
  920. }
  921. }
  922. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  923. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  924. return(MEMORY_ERROR);
  925. }
  926. strcpy((*cmdline)[*cmdlinecnt],q);
  927. (*cmdlinecnt)++;
  928. return(FINISHED);
  929. }
  930. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  931. int assign_file_data_storage(int infilecnt,dataptr dz)
  932. {
  933. int exit_status;
  934. int no_sndfile_system_files = FALSE;
  935. dz->infilecnt = infilecnt;
  936. if((exit_status = allocate_filespace(dz))<0)
  937. return(exit_status);
  938. if(no_sndfile_system_files)
  939. dz->infilecnt = 0;
  940. return(FINISHED);
  941. }
  942. /************************* redundant functions: to ensure libs compile OK *******************/
  943. int assign_process_logic(dataptr dz)
  944. {
  945. return(FINISHED);
  946. }
  947. void set_legal_infile_structure(dataptr dz)
  948. {}
  949. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  950. {
  951. return(FINISHED);
  952. }
  953. int setup_internal_arrays_and_array_pointers(dataptr dz)
  954. {
  955. return(FINISHED);
  956. }
  957. int establish_bufptrs_and_extra_buffers(dataptr dz)
  958. {
  959. return(FINISHED);
  960. }
  961. int read_special_data(char *str,dataptr dz)
  962. {
  963. return(FINISHED);
  964. }
  965. int inner_loop
  966. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  967. {
  968. return(FINISHED);
  969. }
  970. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  971. {
  972. return(FINISHED);
  973. }
  974. /******************************** USAGE1 ********************************/
  975. int usage1(void)
  976. {
  977. usage2("splinter");
  978. return(USAGE_ONLY);
  979. }
  980. /**************************** CHECK_SPLINTER_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  981. int check_splinter_param_validity_and_consistency(dataptr dz)
  982. {
  983. if(dz->param[SPL_PULS1] > 0.0 && dz->param[SPL_PULS1] < 0.1) {
  984. fprintf(stderr,"Pulse frq where splinters join the original sound, cannot be less than 0.1.\n");
  985. return DATA_ERROR;
  986. }
  987. if(dz->param[SPL_PULS2] > 0.0 && dz->param[SPL_PULS2] < 0.1) {
  988. if(dz->mode == 0 || dz->mode == 2)
  989. fprintf(stderr,"Pulse frq where splintering begins, cannot be less than 0.1.\n");
  990. else
  991. fprintf(stderr,"Pulse frq where splintering ends, cannot be less than 0.1.\n");
  992. return DATA_ERROR;
  993. }
  994. return FINISHED;
  995. }
  996. /**************************** SPLINTER_PARAM_PREPROCESS *****************************/
  997. int splinter_param_preprocess(int *initial_phase,dataptr dz)
  998. {
  999. int exit_status;
  1000. // double *shrinkage;
  1001. if((dz->iparray = (int **)malloc(sizeof(int *)))==NULL) {
  1002. sprintf(errstr,"INSUFFICIENT MEMORY to envelope peak-position array.\n");
  1003. return(MEMORY_ERROR);
  1004. }
  1005. if((dz->lparray = (int **)malloc(sizeof(int *)))==NULL) {
  1006. sprintf(errstr,"INSUFFICIENT MEMORY to create minina/maxima store (0).\n");
  1007. return(MEMORY_ERROR);
  1008. }
  1009. if((dz->lparray[0] = (int *)malloc(dz->iparam[SPL_WCNT] * 4 * sizeof(int)))==NULL) {
  1010. sprintf(errstr,"INSUFFICIENT MEMORY to create minina/maxima store.\n");
  1011. return(MEMORY_ERROR); // Arrays stores sample position max(or min) in each half-waveset, and end-samples of half-waveset
  1012. }
  1013. if((dz->parray = (double **)malloc(3 * sizeof(double *)))==NULL) {
  1014. sprintf(errstr,"INSUFFICIENT MEMORY to create splintering arrays.\n");
  1015. return(MEMORY_ERROR);
  1016. }
  1017. if((dz->parray[0] = (double *)malloc(dz->iparam[SPL_SHRCNT] * sizeof(double)))==NULL) {
  1018. sprintf(errstr,"INSUFFICIENT MEMORY to create shrinkage data array.\n");
  1019. return(MEMORY_ERROR); // Arrays stores shrink factor dor successive shrunk waveset-groups
  1020. }
  1021. // shrinkage = dz->parray[0];
  1022. if((dz->parray[1] = (double *)malloc((dz->iparam[SPL_SHRCNT] + dz->iparam[SPL_OCNT] + 1) * sizeof(double)))==NULL) {
  1023. sprintf(errstr,"INSUFFICIENT MEMORY to create splinter timing array.\n");
  1024. return(MEMORY_ERROR); // Arrays stores timings of successive pulses
  1025. }
  1026. if((exit_status = create_temp_sndbuf(dz))<0) // Find and store the the required waveset-group
  1027. return exit_status;
  1028. if((exit_status = find_wavesets(initial_phase,dz))<0) // Find and store the the required waveset-group
  1029. return exit_status;
  1030. free(dz->bigbuf);
  1031. if((exit_status = generate_shrinkage_set(dz))<0) // Generate the sequence of wavesetgroup-shrinkages
  1032. return exit_status;
  1033. if((exit_status = generate_timing_set(dz))<0) // Generate onset times for the shrinking wavesetgroups
  1034. return exit_status;
  1035. dz->splicelen = (int)round(SPLSPLICE * MS_TO_SECS * dz->infile->srate);
  1036. return FINISHED;
  1037. }
  1038. /**************************** GENERATE_ENVELOPE_ARRAY_STORAGE *************************************
  1039. *
  1040. * Buflen (so far) is a multiple of F_SECSIZE (256) .
  1041. * So this algorithm will, in the last resort, always find 256 or its divisors !!
  1042. */
  1043. int generate_envelope_array_storage(dataptr dz)
  1044. {
  1045. double srate = (double)dz->infile->srate;
  1046. int ewcnt = 0, orig_envwindowsize = 0, hifound = 0, lofound = 0;
  1047. dz->envwindowsize = (int)round(SPLENVWIN * MS_TO_SECS * srate); // Envelope window-length, in samples
  1048. ewcnt = dz->buflen/dz->envwindowsize; // Number of windows that will fit inside buffer
  1049. if(ewcnt * dz->envwindowsize != dz->buflen) { // If window is not an exact divisor of buflen
  1050. // adjust envelope length to be an exact divisor of buflen
  1051. orig_envwindowsize = dz->envwindowsize;
  1052. hifound = 0;
  1053. while(!hifound) { // Enlarge the window until windows fit exactly into buffer
  1054. dz->envwindowsize++;
  1055. ewcnt = dz->buflen/dz->envwindowsize;
  1056. if(dz->envwindowsize * ewcnt == dz->buflen) {
  1057. hifound = 1;
  1058. }
  1059. }
  1060. hifound = dz->envwindowsize; // set "hifound" to size of this (larger) window
  1061. dz->envwindowsize = orig_envwindowsize;
  1062. lofound = 0;
  1063. while(!lofound) { // Shrink the window until windows fit exactly into buffer
  1064. dz->envwindowsize--;
  1065. ewcnt = dz->buflen/dz->envwindowsize;
  1066. if(dz->envwindowsize * ewcnt == dz->buflen) {
  1067. lofound = 1;
  1068. break;
  1069. }
  1070. }
  1071. lofound = dz->envwindowsize; // set "lofound" to size of this (smaller) window
  1072. if(hifound - orig_envwindowsize > orig_envwindowsize - lofound)
  1073. dz->envwindowsize = lofound; // use windowsize nearest to original size
  1074. else
  1075. dz->envwindowsize = hifound;
  1076. }
  1077. dz->arraysize = (int)ceil(dz->buflen/dz->envwindowsize) + 64; // 64=SAFETY (but 2 of these are needed for the bracketing envelope segments
  1078. if((dz->parray[2] = (double *)malloc(dz->arraysize * sizeof(double)))==NULL) {
  1079. sprintf(errstr,"INSUFFICIENT MEMORY to create enveloping array.\n");
  1080. return(MEMORY_ERROR);
  1081. }
  1082. if((dz->iparray[0] = (int *)malloc(dz->arraysize * sizeof(int)))==NULL) {
  1083. sprintf(errstr,"INSUFFICIENT MEMORY to create enveloping peak-position array.\n");
  1084. return(MEMORY_ERROR);
  1085. }
  1086. return FINISHED;
  1087. }
  1088. /************************** GET_THE_PROCESS_NO **********************************/
  1089. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1090. {
  1091. if(!strcmp(prog_identifier_from_cmdline,"splinter")) dz->process = SPLINTER;
  1092. else {
  1093. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1094. return(USAGE_ONLY);
  1095. }
  1096. return(FINISHED);
  1097. }
  1098. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1099. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1100. {
  1101. int n;
  1102. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1103. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1104. return(MEMORY_ERROR);
  1105. }
  1106. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1107. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1108. return(MEMORY_ERROR);
  1109. }
  1110. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1111. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1112. return(MEMORY_ERROR);
  1113. }
  1114. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1115. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1116. return(MEMORY_ERROR);
  1117. }
  1118. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1119. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1120. return(MEMORY_ERROR);
  1121. }
  1122. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1123. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1124. return(MEMORY_ERROR);
  1125. }
  1126. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1127. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1128. return(MEMORY_ERROR);
  1129. }
  1130. for(n=0;n<brkcnt;n++) {
  1131. dz->brk[n] = NULL;
  1132. dz->brkptr[n] = NULL;
  1133. dz->brkinit[n] = 0;
  1134. dz->brksize[n] = 0;
  1135. }
  1136. return(FINISHED);
  1137. }
  1138. /******************************** USAGE2 ********************************/
  1139. int usage2(char *str)
  1140. {
  1141. if(!strcmp(str,"splinter")) {
  1142. fprintf(stderr,
  1143. "USAGE:\n"
  1144. "splinter splinter 1-4 infile outfile target wcnt shrcnt ocnt p1 p2\n"
  1145. " [-eecnt] [-sscv] [-ppcv] [-ffrq | -ddur] [-rrand] [-vshrand] [-i] [-I]\n"
  1146. "\n"
  1147. "Creates splinters by repeating & shrinking selected waveset-group in sound.\n"
  1148. "Either splinters repeat before merging with orig snd at time-in-src specified.\n"
  1149. "OR original sound plays up to selected time, then splinters,\n"
  1150. "\n"
  1151. "Mode 1+3: Splinters lead into original sound. Mode 1 splinters change pitch.\n"
  1152. "Mode 2+4: Splinters emerge from original sound. Mode 2 splinters change pitch.\n"
  1153. "\n"
  1154. "TARGET Time in src immediately before desired waveset-group.\n"
  1155. " Waveset group selected should not be longer than 1 minute.\n"
  1156. "WCNT Number of wavesets to use to create splinter group.\n"
  1157. "SHRCNT Number of waveset-group repets over which shrinkage takes place.\n"
  1158. "OCNT Number of max-shrunken splinters beyond shrink.\n"
  1159. "P1 Pulse-speed of waveset repetitions (Hz) at originating waveset.\n"
  1160. "P2 Pulse-speed of shrunken wavesets (Hz) SHRCNT+OCNT splinters away.\n"
  1161. "ECNT Number of additional regular pulses beyond SHRCNT+OCNT.\n"
  1162. "\n"
  1163. "SCV Shrinkage curve: 1 = linear:\n"
  1164. " >1 contracts more rapidly near originating waveset; <1 less rapidly.\n"
  1165. "PCV Pulse-speed curve: 1 = linear:\n"
  1166. " >1 accels more rapidly near originating waveset; <1 less rapidly.\n"
  1167. "\n"
  1168. "FRQ Modes1+2: approx Frq (1/wavelen) of max-shrunk splinters (dflt c6000Hz).\n"
  1169. " Resultant wavelen must be > average wavesetlen in wavesets chosen\n"
  1170. " and less than nyquist/2.\n"
  1171. "DUR Modes3+4: approx Duration (mS) of max-shrunk splinters.\n"
  1172. "\n"
  1173. "RAND Randomisation of pulse timing. Time-variable parameter.\n"
  1174. "SHRAND Randomisation of pulse shrinkage. Time-variable parameter.\n"
  1175. "-i Mix all source into output. (Default: use source only where no splinters)\n"
  1176. "-I Mix none of source into output.\n"
  1177. "\n"
  1178. "If P1 set to zero, Pulse-speed 1 determined by duration of selected waveset-group.\n"
  1179. "If P2 set to zero, Pulse-speed 2 same as Pulse-speed 1.\n");
  1180. } else
  1181. fprintf(stdout,"Unknown option '%s'\n",str);
  1182. return(USAGE_ONLY);
  1183. }
  1184. int usage3(char *str1,char *str2)
  1185. {
  1186. fprintf(stderr,"Insufficient parameters on command line.\n");
  1187. return(USAGE_ONLY);
  1188. }
  1189. /******************************** SPLINTER ********************************/
  1190. int splinter(dataptr dz)
  1191. {
  1192. int exit_status;
  1193. int samps_to_read, obufpos = 0, startobufpos, lastobufpos, thisobufpos = 0, ibufpos = 0, sampstep = 0, envend, maxwrite, ovflw;
  1194. int subtarget, splinterlen = 0, k, n, m, eventscnt, samps_to_write, rndstep,initialobufpos, advance;
  1195. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1], *ovflwbuf = dz->sampbuf[2], *shrbuf = dz->sampbuf[4];
  1196. double srate = (double)dz->infile->srate, shrink = 1.0, last_shrink, initialshrink, thisshrink, finalshrink;
  1197. double *shrinkage = dz->parray[0], *timeset = dz->parray[1], shrinkstep = 0, dur, time, thistime, rnd;
  1198. sndseekEx(dz->ifd[0],0,0);
  1199. dz->total_samps_read = 0;
  1200. memset((char *)ibuf,0,dz->buflen * sizeof(float));
  1201. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1202. if(dz->mode == 0 || dz->mode == 2) { // MODE 0 or 2: attack-type
  1203. // IN ALL CASE we read to dz->target + dz->wavesetgrplen in infile and write (whatever part required) into outfile
  1204. if(dz->vflag[0]) { // If we're mixing-in the original source
  1205. if((exit_status = read_samps(ibuf,dz))<0) // Read the infile : NB bufsize calcd to accept all of infile up to target + wavesetgrplen
  1206. return(exit_status);
  1207. samps_to_read = dz->target + dz->wavesetgrplen;
  1208. if(dz->target >= dz->splintoffset) { // IF infile start is BEFORE OR AT start of splinters, then
  1209. // the read will be up to (and beyond) the wavesetgroup (buffersize calcd thus)
  1210. memcpy((char *)obuf,(char *)ibuf,samps_to_read * sizeof(float));
  1211. obufpos = dz->target - dz->splintoffset; // Set obuf pointer to start of splinters
  1212. } else { // Infile starts AFTER start of splinters
  1213. obufpos = dz->splintoffset - dz->target; // Find appropriate place in obuf to copy this to, and copy it
  1214. memcpy((char *)(obuf+obufpos),(char *)ibuf,samps_to_read * sizeof(float));
  1215. obufpos = 0;
  1216. }
  1217. ibufpos = samps_to_read;
  1218. } else { // Not mixing in INBUF
  1219. sndseekEx(dz->ifd[0],dz->target,0); // Seek to wavesetgrp start
  1220. dz->total_samps_read = dz->target;
  1221. if((exit_status = read_samps(ibuf,dz))<0) // Read the infile
  1222. return(exit_status);
  1223. obufpos = dz->splintoffset; // Write to obuf at place where wavesetgrp will be in output
  1224. samps_to_read = dz->wavesetgrplen; // Copy the wavesetgrp into obuf
  1225. memcpy((char *)(obuf+obufpos),(char *)ibuf,samps_to_read * sizeof(float));
  1226. obufpos = 0;
  1227. ibufpos = samps_to_read;
  1228. }
  1229. initialshrink = shrinkage[0]; // Get maximal shrink
  1230. if((exit_status = shrink_waveset(initialshrink,&splinterlen,dz))<0)//and shrink waveset
  1231. return exit_status;
  1232. if(dz->param[SPL_PULS2] <= 0.0) { // Get goal timestep
  1233. if(dz->param[SPL_PULS1] <= 0.0) // ... in samples
  1234. sampstep = dz->wavesetgrplen;
  1235. else {
  1236. dur = 1.0/dz->param[SPL_PULS1];
  1237. sampstep = (int)ceil(dur * srate);
  1238. }
  1239. } else {
  1240. dur = 1.0/dz->param[SPL_PULS2];
  1241. sampstep = (int)round(dur * srate);
  1242. }
  1243. // If shrinakge can be randomised ..
  1244. if((dz->brksize[SPL_SHRND]) || (dz->param[SPL_SHRND] > 0.0))
  1245. shrinkstep = shrinkage[1] - initialshrink;
  1246. // IF THERE'S A PREQUEL
  1247. thisobufpos = obufpos;
  1248. if(dz->iparam[SPL_ECNT] > 0) {
  1249. for(n=0;n <dz->iparam[SPL_ECNT]; n++) {
  1250. obufpos = thisobufpos;
  1251. if(n > 0 && n < dz->iparam[SPL_ECNT] - 1) {
  1252. if(dz->brksize[SPL_RND]) {
  1253. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1254. if((exit_status = read_value_from_brktable(thistime,SPL_RND,dz))<0)
  1255. return exit_status;
  1256. }
  1257. if(dz->param[SPL_RND] > 0.0) {
  1258. rnd = ((drand48() * 2.0) - 1.0)/2.0; // range +1/2, -1/2
  1259. rnd *= dz->param[SPL_RND];
  1260. rndstep = (int)round(rnd * sampstep);
  1261. obufpos += rndstep;
  1262. } // If no randomisation of shrink, shrunk-waveset remains in original state
  1263. if(dz->brksize[SPL_SHRND]) { // But if shrink is randomised, find current randomisation
  1264. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1265. if((exit_status = read_value_from_brktable(thistime,SPL_SHRND,dz))<0)
  1266. return exit_status;
  1267. }
  1268. if(dz->param[SPL_SHRND] > 0.0) { // If randomised > 0
  1269. rnd = drand48() * dz->param[SPL_SHRND]; // range 0 to SPL_SHRND
  1270. shrink = initialshrink + (shrinkstep * rnd);// Possibly expand-or-contract shrinkage
  1271. if((exit_status = shrink_waveset(shrink,&splinterlen,dz))<0)//and shrink waveset
  1272. return exit_status;
  1273. } else if(dz->brksize[SPL_SHRND]) { // If varying randomisation, but currently zero
  1274. if((exit_status = shrink_waveset(initialshrink,&splinterlen,dz))<0)
  1275. return exit_status; // still need to reshrink waveset (in case shrink-size changed previously)
  1276. }
  1277. }
  1278. for(m=0;m<splinterlen;m++) {
  1279. obuf[obufpos] = (float)(obuf[obufpos] + shrbuf[m]);
  1280. if(++obufpos >= dz->buflen) {
  1281. sprintf(errstr,"Buffer should be long enough to contain all prequel splinters. (1)\n");
  1282. return PROGRAM_ERROR;
  1283. }
  1284. }
  1285. lastobufpos = thisobufpos;
  1286. thisobufpos += sampstep;
  1287. if(thisobufpos >= dz->buflen) {
  1288. sprintf(errstr,"Buffer should be long enough to contain all prequel splinters. (2)\n");
  1289. return PROGRAM_ERROR;
  1290. }
  1291. }
  1292. }
  1293. // TIMESET ITSELF
  1294. eventscnt = dz->iparam[SPL_SHRCNT] + dz->iparam[SPL_OCNT];
  1295. startobufpos = obufpos;
  1296. lastobufpos = startobufpos;
  1297. for(n=0,k = -dz->iparam[SPL_OCNT];n<eventscnt;n++,k++) { // For all timed events
  1298. time = timeset[n];
  1299. sampstep = (int)round(time * srate);
  1300. thisobufpos = startobufpos + sampstep; // Find time beyond starttime, in samples, at which to write next splinter
  1301. advance = thisobufpos - lastobufpos;
  1302. obufpos = thisobufpos;
  1303. if(n > 0 && n < eventscnt - 1) {
  1304. if(dz->brksize[SPL_RND]) {
  1305. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1306. if((exit_status = read_value_from_brktable(thistime,SPL_RND,dz))<0)
  1307. return exit_status;
  1308. }
  1309. if(dz->param[SPL_RND] > 0.0) {
  1310. rnd = ((drand48() * 2.0) - 1.0)/2.0; // range +1/2, -1/2
  1311. rnd *= dz->param[SPL_RND];
  1312. rndstep = (int)round(rnd * advance);
  1313. obufpos += rndstep;
  1314. }
  1315. }
  1316. if(obufpos >= dz->buflen) {
  1317. sprintf(errstr,"Buffer should be long enough to contain all time-sequence splinters. (1)\n");
  1318. return PROGRAM_ERROR;
  1319. }
  1320. if(k > 0) { // If splinter-shrink starting to change
  1321. shrink = shrinkage[k]; // Get next shrink value
  1322. if(n < eventscnt - 1) { // If not at last of shrunk events
  1323. if(dz->brksize[SPL_SHRND]) { // possibly randomise shrinking
  1324. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1325. if((exit_status = read_value_from_brktable(thistime,SPL_RND,dz))<0)
  1326. return exit_status;
  1327. }
  1328. if(dz->param[SPL_SHRND] > 0.0) { // If shrink to be randomised
  1329. shrinkstep = shrinkage[k+1] - shrink; // do it (shrinkkage[k+1] exists if n < eventscnt - 1)
  1330. rnd = drand48() * dz->param[SPL_SHRND]; // range 0 to SPL_SHRND
  1331. shrink += (shrinkstep * rnd); // Possibly expand-or-contract shrinkage
  1332. }
  1333. }
  1334. if((exit_status = shrink_waveset(shrink,&splinterlen,dz))<0)
  1335. return exit_status; // and re-shrink waveset
  1336. }
  1337. for(m=0;m<splinterlen;m++) { // Add this splinter into the obuf
  1338. obuf[obufpos] = (float)(obuf[obufpos] + shrbuf[m]);
  1339. if(++obufpos >= dz->buflen) {
  1340. sprintf(errstr,"Buffer should be long enough to contain all time-sequence splinters. (2)\n");
  1341. return PROGRAM_ERROR;
  1342. }
  1343. }
  1344. lastobufpos = thisobufpos;
  1345. } // Set obufpos at end of target wavesetgrp in obuf
  1346. envend = max(dz->splintoffset,dz->target) + dz->wavesetgrplen;
  1347. envend = max(envend,dz->buflen);
  1348. if((exit_status = normalise_buffer(envend,dz))<0)
  1349. return exit_status;
  1350. // WRITE REMAINDER OF INFILE
  1351. if(!dz->vflag[1]) {
  1352. while(dz->ssampsread > 0) {
  1353. while(ibufpos < dz->ssampsread) {
  1354. obuf[obufpos++] = ibuf[ibufpos++];
  1355. if(obufpos >= dz->buflen) {
  1356. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1357. return(exit_status);
  1358. obufpos = 0;
  1359. }
  1360. }
  1361. if((exit_status = read_samps(ibuf,dz))<0)
  1362. return(exit_status);
  1363. ibufpos = 0;
  1364. }
  1365. }
  1366. } else { // MODE 1 or 3: post-event splinter
  1367. // IN ALL CASES we read to dz->target - dz->envwindowsize in infile and write all this to output
  1368. subtarget = dz->target - dz->envwindowsize; // subtarget is 1 envelope-windowlen before target (which is start of target wavesetgroup)
  1369. if(!dz->vflag[1]) {
  1370. while(dz->total_samps_read < subtarget) { // Read all of src, up to the subtarget
  1371. if((exit_status = read_samps(ibuf,dz))<0)
  1372. return(exit_status);
  1373. if(dz->total_samps_read <= subtarget) {
  1374. if((exit_status = write_samps(ibuf,dz->buflen,dz))<0)
  1375. return(exit_status);
  1376. } else {
  1377. samps_to_write = subtarget % dz->buflen; // and write it directly to the output
  1378. if((exit_status = write_samps(ibuf,samps_to_write,dz))<0)
  1379. return(exit_status);
  1380. }
  1381. }
  1382. }
  1383. memset((char *)ibuf,0,dz->buflen * sizeof(float));
  1384. sndseekEx(dz->ifd[0],subtarget,0); // Seek to the subtarget
  1385. dz->total_samps_read = subtarget;
  1386. if((exit_status = read_samps(ibuf,dz))<0) // should read whole of remainder of sound, if buffers set up correctly!!!
  1387. return(exit_status);
  1388. if(dz->total_samps_read != dz->insams[0]) {
  1389. sprintf(errstr,"Error in buffersize to accomodate all of end of source. total samps read = %d filesize = %d\n",dz->total_samps_read,dz->insams[0]);
  1390. return PROGRAM_ERROR;
  1391. }
  1392. if(dz->vflag[0]) // If source remnant to be mixed into output, read all of it
  1393. samps_to_read = dz->ssampsread;
  1394. else // If not, read up to the target waveset and to the end of it.
  1395. samps_to_read = dz->envwindowsize + dz->wavesetgrplen;
  1396. memcpy((char *)obuf,(char *)ibuf,samps_to_read * sizeof(float));
  1397. maxwrite = samps_to_read;
  1398. obufpos = dz->envwindowsize; // Set obufpos to START OF WAVESET GROUP (splinters are timed from this point)
  1399. eventscnt = dz->iparam[SPL_SHRCNT]+dz->iparam[SPL_OCNT];// Number of events in the rit of pulses
  1400. last_shrink = 0;
  1401. initialobufpos = obufpos;
  1402. lastobufpos = obufpos;
  1403. for(n=0;n < eventscnt; n++) { // Generate splinters and every time in the timing set: (wavesetgroup time assumed to be zero)
  1404. k = min(n,dz->iparam[SPL_SHRCNT]-1); // Step through sequence of shrinks as far as dz->iparam[SPL_SHRCNT], where shrink is (and remains at) max.
  1405. shrink = shrinkage[k]; // Get shrink for this splinter.
  1406. sampstep = (int)round(timeset[n] * srate); // Time step to next splinter, in samples
  1407. thisobufpos = initialobufpos + sampstep; // Advance in outbuf to next splinter start position
  1408. obufpos = thisobufpos;
  1409. advance = thisobufpos - lastobufpos;
  1410. if(n > 0 && n < eventscnt - 1) {
  1411. if(dz->brksize[SPL_RND]) {
  1412. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1413. if((exit_status = read_value_from_brktable(thistime,SPL_RND,dz))<0)
  1414. return exit_status;
  1415. }
  1416. if(dz->param[SPL_RND] > 0.0) {
  1417. rnd = ((drand48() * 2.0) - 1.0)/2.0; // range +1/2, -1/2
  1418. rnd *= dz->param[SPL_RND];
  1419. rndstep = (int)round(rnd * advance);
  1420. obufpos += rndstep;
  1421. }
  1422. }
  1423. if(obufpos >= dz->buflen) {
  1424. sprintf(errstr,"ERROR: Buffer should be long enough to accomodate all of post-target output.(1)\n");
  1425. return PROGRAM_ERROR;
  1426. }
  1427. thisshrink = shrink;
  1428. if(shrink != last_shrink) { // If shrink has changed, shrink the waveset
  1429. if(k < dz->iparam[SPL_SHRCNT]-1) // Before last shrunk-waveset
  1430. shrinkstep = shrinkage[k+1] - shrink; // Get change in shrink to next waveset
  1431. // (last step is retained)
  1432. if(dz->brksize[SPL_SHRND]) { // Possibly randomise the shrink value
  1433. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1434. if((exit_status = read_value_from_brktable(thistime,SPL_SHRND,dz))<0)
  1435. return exit_status;
  1436. }
  1437. if(dz->param[SPL_SHRND] > 0.0) {
  1438. rnd = drand48() * dz->param[SPL_SHRND]; // range 0 to SPL_SHRND
  1439. thisshrink += shrinkstep * rnd; // Possibly expand-or-contract shrinkage
  1440. }
  1441. if((exit_status = shrink_waveset(thisshrink,&splinterlen,dz))<0)
  1442. return exit_status;
  1443. // If the (unrandomised) shrnik is not changing
  1444. } else { // use the shrunk splinter generated at last pass
  1445. // UNLESS it's randomised
  1446. if(n > 0 && n < eventscnt - 1) {
  1447. if(dz->brksize[SPL_SHRND]) {
  1448. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1449. if((exit_status = read_value_from_brktable(thistime,SPL_SHRND,dz))<0)
  1450. return exit_status;
  1451. }
  1452. if(dz->param[SPL_SHRND] > 0.0) {
  1453. rnd = drand48() * dz->param[SPL_SHRND]; // range 0 to SPL_SHRND
  1454. thisshrink += shrinkstep * rnd; // Possibly expand-or-contract shrinkage
  1455. if((exit_status = shrink_waveset(thisshrink,&splinterlen,dz))<0)
  1456. return exit_status;
  1457. } else if(dz->brksize[SPL_SHRND]) { // IF SHRND varies, but currently 0, still remake splinter, at unrandomised len
  1458. if((exit_status = shrink_waveset(shrink,&splinterlen,dz))<0)
  1459. return exit_status;
  1460. }
  1461. }
  1462. }
  1463. last_shrink = shrink; // Remember the (unrandomised) shrink value just used.
  1464. if(obufpos + splinterlen >= dz->buflen) {
  1465. sprintf(errstr,"ERROR: Buffer should be long enough to accomodate all of post-target output. (2)\n");
  1466. return PROGRAM_ERROR;
  1467. }
  1468. for(m = 0; m < splinterlen; m++) { // Add the shrunk splinter to the output
  1469. obuf[obufpos] = (float)(obuf[obufpos] + shrbuf[m]);
  1470. obufpos++;
  1471. }
  1472. lastobufpos = thisobufpos;
  1473. }
  1474. maxwrite = max(maxwrite,obufpos); // maxwrite = end of insams, obufpos = end of shrink-sequence
  1475. if((exit_status = normalise_buffer(maxwrite,dz))<0)
  1476. return exit_status;
  1477. sampstep = dz->enddur;
  1478. finalshrink = shrink;
  1479. // Once all timed set of splinters have been written...
  1480. for(n = 0; n < dz->iparam[SPL_ECNT]; n++) { // If there's any extension (splinters repeating at regular pulse)
  1481. thisobufpos = lastobufpos + sampstep; // Advance (regular sampstep set previously), and check for overflow
  1482. obufpos = thisobufpos;
  1483. if(dz->brksize[SPL_RND]) { // Possibly randomise timing
  1484. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1485. if((exit_status = read_value_from_brktable(thistime,SPL_RND,dz))<0)
  1486. return exit_status;
  1487. }
  1488. if(dz->param[SPL_RND] > 0.0) {
  1489. rnd = ((drand48() * 2.0) - 1.0)/2.0; // range +1/2, -1/2
  1490. rnd *= dz->param[SPL_RND];
  1491. rndstep = (int)round(rnd * sampstep);
  1492. obufpos += rndstep;
  1493. }
  1494. if((ovflw = obufpos - dz->buflen) > 0) {
  1495. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1496. return(exit_status);
  1497. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1498. memcpy((char *)obuf,(char *)ovflwbuf,dz->buflen2 * sizeof(float));
  1499. memset((char *)ovflwbuf,0,dz->buflen2 * sizeof(float));
  1500. obufpos -= dz->buflen;
  1501. thisobufpos -= dz->buflen;
  1502. }
  1503. shrink = finalshrink;
  1504. if(dz->brksize[SPL_SHRND]) { // Possibly randomise shrinkage
  1505. thistime = (double)(dz->total_samps_written + obufpos)/srate;
  1506. if((exit_status = read_value_from_brktable(thistime,SPL_SHRND,dz))<0)
  1507. return exit_status;
  1508. }
  1509. if(dz->param[SPL_SHRND] > 0.0) {
  1510. rnd = drand48() * dz->param[SPL_SHRND]; // range 0 to SPL_SHRND
  1511. shrink = finalshrink + (shrinkstep * rnd); // Possibly expand-or-contract shrinkage
  1512. if((exit_status = shrink_waveset(shrink,&splinterlen,dz))<0)//and shrink waveset
  1513. return exit_status;
  1514. } else if(dz->brksize[SPL_SHRND]) { // Varying randomisation of shrinkage, but currently 0
  1515. if((exit_status = shrink_waveset(finalshrink,&splinterlen,dz))<0)//and shrink waveset
  1516. return exit_status;
  1517. }
  1518. for(m = 0; m < splinterlen; m++) { // Add copy of final splinter to output
  1519. obuf[obufpos] = (float)(obuf[obufpos] + shrbuf[m]);
  1520. obufpos++;
  1521. }
  1522. lastobufpos = thisobufpos;
  1523. }
  1524. }
  1525. if(obufpos > 0) { // Write any samples remaining in obuf.
  1526. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1527. return(exit_status);
  1528. }
  1529. return FINISHED;
  1530. }
  1531. /****************************** GET_MODE *********************************/
  1532. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1533. {
  1534. char temp[200], *p;
  1535. if(sscanf(str,"%s",temp)!=1) {
  1536. sprintf(errstr,"Cannot read mode of program.\n");
  1537. return(USAGE_ONLY);
  1538. }
  1539. p = temp + strlen(temp) - 1;
  1540. while(p >= temp) {
  1541. if(!isdigit(*p)) {
  1542. fprintf(stderr,"Invalid mode of program entered.\n");
  1543. return(USAGE_ONLY);
  1544. }
  1545. p--;
  1546. }
  1547. if(sscanf(str,"%d",&dz->mode)!=1) {
  1548. fprintf(stderr,"Cannot read mode of program.\n");
  1549. return(USAGE_ONLY);
  1550. }
  1551. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1552. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1553. return(USAGE_ONLY);
  1554. }
  1555. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1556. return(FINISHED);
  1557. }
  1558. /******************************** CREATE_TEMP_SNDBUF ********************************/
  1559. int create_temp_sndbuf(dataptr dz)
  1560. {
  1561. int bigbufsize, secsize;
  1562. int framesize = F_SECSIZE;
  1563. if(dz->sbufptr == 0 || dz->sampbuf == 0) {
  1564. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  1565. return(PROGRAM_ERROR);
  1566. }
  1567. bigbufsize = (int)(size_t)Malloc(-1); // Ensure no very tiny buffs (e.g. if attack very near start of sound)
  1568. dz->buflen = bigbufsize/sizeof(float);
  1569. secsize = dz->buflen/framesize;
  1570. if(secsize * framesize != dz->buflen)
  1571. secsize++;
  1572. dz->buflen = secsize * framesize; // Ensure bufsize is multiple of F_SECSIZE (256) .. ness for dz->envwindowsize calcs
  1573. if(dz->buflen < 0) {
  1574. sprintf(errstr,"INSUFFICIENT MEMORY to create temporary sound buffer (1).\n");
  1575. return(PROGRAM_ERROR);
  1576. }
  1577. bigbufsize = dz->buflen * sizeof(float);
  1578. if((dz->bigbuf = (float *)malloc(bigbufsize)) == NULL) {
  1579. sprintf(errstr,"INSUFFICIENT MEMORY to create temporary sound buffer (2).\n");
  1580. return(PROGRAM_ERROR);
  1581. }
  1582. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf; // Inbuf
  1583. return(FINISHED);
  1584. }
  1585. /******************************** CREATE_SPLINTER_SNDBUFS1 ********************************/
  1586. int create_splinter_sndbufs1(dataptr dz)
  1587. {
  1588. int bigbufsize, secsize;
  1589. int framesize = F_SECSIZE;
  1590. if(dz->sbufptr == 0 || dz->sampbuf == 0) {
  1591. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  1592. return(PROGRAM_ERROR);
  1593. }
  1594. if(dz->mode == 0 || dz->mode == 2) { // Pre-splinter Allow for src pre-splintering to be mixed with splintered material inside a single buffer
  1595. dz->buflen = dz->target; // Input buffer must contain infile up to wavesetgroup
  1596. dz->buflen = max(dz->buflen,dz->splintoffset); // But also, all the pre-splinters
  1597. dz->buflen += dz->wavesetgrplen; // And the target wavesetgroup
  1598. } else { // Post-splinter Allow for src post-splintering to be mixed with splintered material inside a single buffer
  1599. dz->buflen = dz->insams[0] - dz->target; // Input buffer large enough to accomodate all of post-wavesetgroup infile
  1600. dz->buflen = max(dz->buflen,dz->splintoffset); // And also all post wavesetgroup splinters
  1601. }
  1602. bigbufsize = (int)(size_t)Malloc(-1); // Ensure no very tiny buffs (e.g. if attack very near start of sound)
  1603. dz->buflen = max((unsigned int)dz->buflen,bigbufsize/sizeof(float));
  1604. secsize = dz->buflen/framesize;
  1605. if(secsize * framesize != dz->buflen)
  1606. secsize++;
  1607. dz->buflen = secsize * framesize; // Ensure bufsize is multiple of F_SECSIZE (256) .. ness for dz->envwindowsize calcs
  1608. if(dz->buflen < 0) {
  1609. sprintf(errstr,"INSUFFICIENT MEMORY to create output sound buffer.\n");
  1610. return(PROGRAM_ERROR);
  1611. }
  1612. return(FINISHED);
  1613. }
  1614. /******************************** CREATE_SPLINTER_SNDBUFS2 ********************************/
  1615. int create_splinter_sndbufs2(dataptr dz)
  1616. {
  1617. int bigbufsize, secsize;
  1618. int framesize = F_SECSIZE;
  1619. dz->buflen += dz->envwindowsize * 2; // Allow for 2 bracketing envelope windows
  1620. secsize = dz->buflen/framesize;
  1621. if(secsize * framesize != dz->buflen)
  1622. secsize++;
  1623. dz->buflen = secsize * framesize; // Ensure bufsize is multiple of F_SECSIZE (256)
  1624. if(dz->buflen < 0) {
  1625. sprintf(errstr,"INSUFFICIENT MEMORY to create output sound buffer with eveloping brackets.\n");
  1626. return(PROGRAM_ERROR);
  1627. }
  1628. dz->buflen2 = dz->wavesetgrplen + 64; // Size of pre-shrunk wavesetgroup + SAFETY
  1629. secsize = dz->buflen2/framesize;
  1630. if(secsize * framesize != dz->buflen2)
  1631. secsize++;
  1632. dz->buflen2 = secsize * framesize;
  1633. if(dz->buflen2 < 0) {
  1634. sprintf(errstr,"INSUFFICIENT MEMORY to create wavesetgroup-storage buffer.\n");
  1635. return(PROGRAM_ERROR);
  1636. }
  1637. bigbufsize = ((dz->buflen * 2) + (dz->buflen2 * 3)) * sizeof(float);
  1638. if((dz->bigbuf = (float *)malloc(bigbufsize)) == NULL) {
  1639. sprintf(errstr,"INSUFFICIENT MEMORY to create total sound buffers.\n");
  1640. return(PROGRAM_ERROR);
  1641. }
  1642. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf; // Inbuf
  1643. dz->sbufptr[1] = dz->sampbuf[1] = dz->sampbuf[0] + dz->buflen; // Outbuf
  1644. dz->sbufptr[2] = dz->sampbuf[2] = dz->sampbuf[1] + dz->buflen; // Ovflwbuf
  1645. dz->sbufptr[3] = dz->sampbuf[3] = dz->sampbuf[2] + dz->buflen2; // Waveset store
  1646. dz->sbufptr[4] = dz->sampbuf[4] = dz->sampbuf[3] + dz->buflen2; // Shrunk-waveset store
  1647. dz->sampbuf[5] = dz->sampbuf[4] + dz->buflen2;
  1648. return(FINISHED);
  1649. }
  1650. /******************************** FIND_AND_STORE_WAVESETS ********************************/
  1651. int find_wavesets(int *initial_phase,dataptr dz)
  1652. {
  1653. int exit_status, changephase = 0, halfcyclecnt = 0, phase;
  1654. int sampskip, secsize, ibufpos = 0, splsamps, endsample;
  1655. double spltime = dz->param[SPL_TIME], srate = (double)dz->infile->srate;
  1656. float *ibuf = dz->sampbuf[0];
  1657. splsamps = (int)floor(spltime * srate); // Find how far to skip into infile to find required waveset(s)
  1658. secsize = dz->target/F_SECSIZE;
  1659. sampskip = secsize * F_SECSIZE; // curtail to previous secsize boundary
  1660. sndseekEx(dz->ifd[0],sampskip,0); // Skip into infile to (just before) time of wavesetgrp given by user
  1661. dz->total_samps_read = sampskip;
  1662. if((exit_status = read_samps(ibuf,dz))<0) // Read infile
  1663. return(exit_status);
  1664. ibufpos = splsamps - sampskip; // Position ibuf pointer to samptime given by user, then search forward for wavesetgrp start
  1665. if(ibuf[ibufpos] == 0.0) { // Advance to first non-zero sample
  1666. while(ibuf[ibufpos] == 0.0) {
  1667. ibufpos++;
  1668. if(ibufpos >= dz->ssampsread) {
  1669. sampskip += dz->ssampsread;
  1670. if((exit_status = read_samps(ibuf,dz))<0)
  1671. return(exit_status);
  1672. if(dz->ssampsread == 0) {
  1673. sprintf(errstr,"No wavesets found after time %lf\n",dz->param[SPL_TIME]);
  1674. return DATA_ERROR;
  1675. } else
  1676. ibufpos = 0;
  1677. }
  1678. }
  1679. if(ibuf[ibufpos] > 0.0) // then note the phase (+ve going or -ve going)
  1680. phase = 1;
  1681. else
  1682. phase = -1;
  1683. } else if(ibuf[0] > 0.0) { // Or if the signal already +ve
  1684. while(ibuf[ibufpos] >= 0.0) { // advance to where signal changes phase (to -ve)
  1685. ibufpos++; // and set the phase value.
  1686. if(ibufpos >= dz->ssampsread) {
  1687. sampskip += dz->ssampsread;
  1688. if((exit_status = read_samps(ibuf,dz))<0)
  1689. return(exit_status);
  1690. if(dz->ssampsread == 0) {
  1691. sprintf(errstr,"No wavesets found after time %lf\n",dz->param[SPL_TIME]);
  1692. return DATA_ERROR;
  1693. } else
  1694. ibufpos = 0;
  1695. }
  1696. }
  1697. phase = -1;
  1698. } else { // Or if the signal already -ve
  1699. while(ibuf[ibufpos] <= 0.0) { // advance to where signal changes phase (to +ve)
  1700. ibufpos++; // and set the phase value.
  1701. if(ibufpos >= dz->ssampsread) {
  1702. sampskip += dz->ssampsread;
  1703. if((exit_status = read_samps(ibuf,dz))<0)
  1704. return(exit_status);
  1705. if(dz->ssampsread == 0) {
  1706. sprintf(errstr,"No wavesets found after time %lf\n",dz->param[SPL_TIME]);
  1707. return DATA_ERROR;
  1708. } else
  1709. ibufpos = 0;
  1710. }
  1711. }
  1712. phase = 1;
  1713. }
  1714. dz->target = sampskip + dz->total_samps_read - dz->ssampsread + ibufpos;
  1715. // dz->target = sampskip + ibufpos; // Position of target wavesetgrp in infile
  1716. *initial_phase = phase;
  1717. while(ibufpos < dz->ssampsread) {
  1718. if(++ibufpos >= dz->ssampsread) { // Advance in inbuf
  1719. if((exit_status = read_samps(ibuf,dz))<0)
  1720. return(exit_status);
  1721. if(dz->ssampsread == 0) {
  1722. sprintf(errstr,"Insufficient wavesets found after time %lf\n",dz->param[SPL_TIME]);
  1723. return DATA_ERROR;
  1724. } else
  1725. ibufpos = 0;
  1726. }
  1727. switch(phase) {
  1728. case(1):
  1729. if(ibuf[ibufpos] < 0.0) // If phase changes (signal crosses zero) flag a phase-change
  1730. changephase = 1;
  1731. break;
  1732. case(-1):
  1733. if(ibuf[ibufpos] > 0.0)
  1734. changephase = 1;
  1735. break;
  1736. }
  1737. if(changephase) { // If phasechange is flagged
  1738. halfcyclecnt++; // Count the completed half-cycle
  1739. phase = -phase; // Change the phase
  1740. changephase = 0;
  1741. }
  1742. if(halfcyclecnt >= 2 * dz->iparam[SPL_WCNT]) // When enough half-cycles are counted, break
  1743. break;
  1744. }
  1745. dz->quartercyclecnt = halfcyclecnt * 2; // No of quaretercycles in wavesetgroup
  1746. endsample = dz->total_samps_read - dz->ssampsread + ibufpos;
  1747. dz->wavesetgrplen = endsample - dz->target;
  1748. return FINISHED;
  1749. }
  1750. /******************************** STORE_WAVESETS ********************************/
  1751. int store_wavesets(int initial_phase,dataptr dz)
  1752. {
  1753. int exit_status, changephase = 0, halfcyclecnt = 0, phase;
  1754. int ibufpos = 0, wbufpos = 0, maxminstorecnt = 0, maxpos, maxmaxpos = 0;
  1755. double maxmin, maxmaxmin;
  1756. float *ibuf = dz->sampbuf[0], *wbuf = dz->sampbuf[3];
  1757. int *maxminstore = dz->lparray[0];
  1758. maxmin = 0.0; // Initialise the max(min) value and position
  1759. maxpos = 0;
  1760. sndseekEx(dz->ifd[0],dz->target,0);
  1761. if((exit_status = read_samps(ibuf,dz))<0)
  1762. return(exit_status);
  1763. ibufpos = 0;
  1764. wbufpos = 0;
  1765. wbuf[wbufpos++] = 0.0;
  1766. phase = initial_phase;
  1767. maxmaxmin = 0.0;
  1768. maxmaxpos = 0;
  1769. while(ibufpos < dz->ssampsread) {
  1770. wbuf[wbufpos] = ibuf[ibufpos]; // Store wavesets in waveset-store
  1771. if(fabs(wbuf[wbufpos]) > maxmin) { // Check for max(min) sample in the cycle
  1772. maxpos = wbufpos; // noting its new position and value, if it changes
  1773. maxmin = fabs(wbuf[maxpos]);
  1774. }
  1775. if(++ibufpos >= dz->ssampsread) { // Advance in inbuf
  1776. if((exit_status = read_samps(ibuf,dz))<0)
  1777. return(exit_status);
  1778. ibufpos = 0;
  1779. }
  1780. if(++wbufpos >= dz->buflen2) { // Advance in waveset-store buffer, checking for overflow
  1781. sprintf(errstr,"Waveset group exceeds %d seconds in length.\n",SPLMAXSPL);
  1782. return DATA_ERROR;
  1783. }
  1784. switch(phase) {
  1785. case(1):
  1786. if(ibuf[ibufpos] < 0.0) // If phase changes (signal crosses zero) flag a phase-change
  1787. changephase = 1;
  1788. break;
  1789. case(-1):
  1790. if(ibuf[ibufpos] > 0.0)
  1791. changephase = 1;
  1792. break;
  1793. }
  1794. if(changephase) { // If phasechange is flagged
  1795. if(maxmin > maxmaxmin) {
  1796. maxmaxmin = maxmin;
  1797. maxmaxpos = maxpos;
  1798. }
  1799. maxminstore[maxminstorecnt++] = maxpos; // Store position of min(max) in completed half-cycle
  1800. maxmin = 0.0; // and re-initialise maxmin for next cycle
  1801. maxminstore[maxminstorecnt++] = wbufpos; // Store end of completed half-cycle
  1802. halfcyclecnt++; // Count the completed half-cycle
  1803. phase = -phase; // Change the phase
  1804. changephase = 0;
  1805. }
  1806. if(halfcyclecnt >= 2 * dz->iparam[SPL_WCNT]) // When enough half-cycles are stored, break
  1807. break;
  1808. }
  1809. dz->wmaxmpos = maxmaxpos;
  1810. return FINISHED;
  1811. }
  1812. /******************************** SHRINK_WAVESET ********************************/
  1813. int shrink_waveset(double shrink,int *splinterlen,dataptr dz)
  1814. {
  1815. //HEREH Shrinkage not working correctly ... output too short
  1816. float *wbuf = dz->sampbuf[3], *shrbuf = dz->sampbuf[4];
  1817. int *maxminstore = dz->lparray[0];
  1818. int thispos, nextpos, samplen, n, m, thissamp, nextsamp;
  1819. double dpos, incr, thisval, valdiff, frac, val, splval;
  1820. int maxmincnt = 0, shrbufpos = 0, incrsteps;
  1821. int prelen, postlen, preshrunk, startsamp, postshrunk, endsamp;
  1822. memset((char *)shrbuf,0,dz->buflen2 * sizeof(float));
  1823. thispos = 0;
  1824. switch(dz->mode) {
  1825. case(0):
  1826. case(1):
  1827. while(maxmincnt < dz->quartercyclecnt) {
  1828. nextpos = maxminstore[maxmincnt]; // Find end of next quartercycle
  1829. samplen = nextpos - thispos; // Find sample-length of quartercycled
  1830. if(samplen <= QCYCLEMIN) { // Don't try to shrink any quarter-cycle that is only 1 or 2 samples int
  1831. incr = 1.0;
  1832. incrsteps = samplen;
  1833. } else {
  1834. incrsteps = (int)round((double)samplen * shrink); // Approx how many sampling steps to cover this quarter-cycle
  1835. incrsteps = max(QCYCLEMIN,incrsteps); // Don't shrink any quartercycle to less than QCYCLEMIN samples
  1836. incr = (double)samplen/(double)incrsteps; // Readjust sampling step so its equally spaced over the quarter-cycle
  1837. }
  1838. dpos = (double)thispos;
  1839. shrbuf[shrbufpos++] = wbuf[thispos]; // Retain the start of the quarter-cycle, and the min(max)
  1840. for(n = 1;n < incrsteps;n++) {
  1841. dpos += incr; // Shrink quartercycle by interpolation
  1842. thissamp = (int)floor(dpos);
  1843. nextsamp = thissamp + 1;
  1844. thisval = wbuf[thissamp];
  1845. valdiff = wbuf[nextsamp] - thisval;
  1846. frac = dpos - (double)thissamp;
  1847. val = thisval + (valdiff * frac);
  1848. shrbuf[shrbufpos] = (float)val;
  1849. shrbufpos++;
  1850. }
  1851. thispos = nextpos;
  1852. maxmincnt++;
  1853. }
  1854. break;
  1855. case(2):
  1856. case(3):
  1857. prelen = dz->wmaxmpos;
  1858. if(prelen > dz->splicelen)
  1859. preshrunk = (int)round(prelen * shrink);
  1860. else
  1861. preshrunk = prelen;
  1862. startsamp = prelen - preshrunk;
  1863. postlen = dz->wavesetgrplen - dz->wmaxmpos;
  1864. if(postlen > dz->splicelen)
  1865. postshrunk = (int)round(postlen * shrink);
  1866. else
  1867. postshrunk = postlen;
  1868. endsamp = dz->wmaxmpos + postshrunk;
  1869. for(n = startsamp; n < endsamp;n++)
  1870. shrbuf[shrbufpos++] = wbuf[n];
  1871. if(prelen > dz->splicelen) {
  1872. for(n = 0; n < dz->splicelen;n++) {
  1873. splval = ((double)n/(double)dz->splicelen);
  1874. shrbuf[n] = (float)(shrbuf[n] * splval);
  1875. }
  1876. }
  1877. if(postlen > dz->splicelen) {
  1878. for(n = 0,m = shrbufpos-1; n < dz->splicelen;n++,m--) {
  1879. splval = ((double)n/(double)dz->splicelen);
  1880. shrbuf[m] = (float)(shrbuf[m] * splval);
  1881. }
  1882. }
  1883. break;
  1884. }
  1885. *splinterlen = shrbufpos; // Store size of shrunk waveset
  1886. return FINISHED;
  1887. }
  1888. /******************************** GENERATE_SHRINKAGE_SET ********************************/
  1889. int generate_shrinkage_set(dataptr dz)
  1890. {
  1891. int n, m, kk;
  1892. double *shrinkage = dz->parray[0], shrinkcnt = dz->iparam[SPL_SHRCNT];
  1893. double temp, srate = (double)dz->infile->srate;
  1894. int shrinkdiff;
  1895. if(dz->mode <= 1) {
  1896. dz->minlen = (int)ceil(srate/dz->param[SPL_FRQ]); // maximally-shrunk-waveset wavelen, in samples
  1897. dz->minlen *= dz->iparam[SPL_WCNT]; // multiplied by number of wavesets in group
  1898. if(dz->minlen >= dz->wavesetgrplen) {
  1899. temp = ((double)dz->minlen/(double)dz->wavesetgrplen) * dz->param[SPL_FRQ];
  1900. sprintf(errstr,"Targeted-wavesets frq (c. %.2lf) >= goal frq (%.2lf): Cannot shrink.\n",temp,dz->param[SPL_FRQ]);
  1901. return DATA_ERROR;
  1902. }
  1903. } else
  1904. dz->minlen = (int)round(dz->param[SPL_DUR]*MS_TO_SECS*srate);//maximally-shrunk-envent length, in samples
  1905. shrinkdiff = dz->wavesetgrplen - dz->minlen; // Total amount of samples lost in max shortening
  1906. for(n=0,m=1; m < dz->iparam[SPL_SHRCNT];n++,m++) {
  1907. shrinkage[n] = (double)m/(double)shrinkcnt; // Values >0 to <1 e.g. for 4 shrinks we get [1/4 1/2 3/4]
  1908. if(!flteq(dz->param[SPL_SCURVE],1.0)) // Ditto but warped, e.g. with warp 2 [1/16 1/4 9/16]
  1909. shrinkage[n] = pow(shrinkage[n],dz->param[SPL_SCURVE]);
  1910. }
  1911. shrinkage[n] = 1;
  1912. for(n=0; n < dz->iparam[SPL_SHRCNT];n++) {
  1913. shrinkage[n] *= (double)shrinkdiff; // Amount of samples lost at each step (small to large vals)
  1914. shrinkage[n] = (double)dz->wavesetgrplen - shrinkage[n]; // Number of samples remaining at each step(large to small vals)
  1915. shrinkage[n] = shrinkage[n]/(double)dz->wavesetgrplen; // Shrinkage at each step (large to small vals = less shrinking to more shrinking)
  1916. }
  1917. if(dz->mode == 0 || dz->mode == 2) {
  1918. kk = dz->iparam[SPL_SHRCNT]/2;
  1919. for(n = 0, m = dz->iparam[SPL_SHRCNT]-1; n < kk; n++, m--) { // Reverse shrinkage sequence for mode 0
  1920. temp = shrinkage[n];
  1921. shrinkage[n] = shrinkage[m];
  1922. shrinkage[m] = temp;
  1923. }
  1924. }
  1925. return FINISHED;
  1926. }
  1927. /******************************** GENERATE_TIMING_SET ********************************/
  1928. int generate_timing_set(dataptr dz)
  1929. {
  1930. double *timeset = dz->parray[1];
  1931. double dur1, dur2, durdiff, sum, temp, startdur, maxstep, srate = (double)dz->infile->srate;
  1932. int eventscnt, n, m, kk, isshrand = 0;
  1933. int extrasamps = 0, lastdur, minlength;
  1934. eventscnt = dz->iparam[SPL_SHRCNT] + dz->iparam[SPL_OCNT]; // Number of events in the rit/accel of pulses
  1935. if(dz->param[SPL_PULS1] == 0)
  1936. dur1 = (double)dz->wavesetgrplen/srate;
  1937. else
  1938. dur1 = 1.0/dz->param[SPL_PULS1]; // Pulse-rate of wavesets where they join original source
  1939. if(dz->param[SPL_PULS2] == 0)
  1940. dur2 = dur1; // Goal duration
  1941. else
  1942. dur2 = 1.0/dz->param[SPL_PULS2]; // Pulse-rate of wavesets where they start/end
  1943. durdiff = dur2 - dur1; // Difference in duration
  1944. for(n=0,m=1; m < eventscnt;n++,m++) {
  1945. timeset[n] = (double)m/(double)eventscnt; // Values >0 to 1 e.g. for 4 steps [1/4 1/2 3/4 ]
  1946. if(!flteq(dz->param[SPL_PCURVE],1.0)) // Ditto but warped e.g. by factor 2 [1/16 1/4 9/16]
  1947. timeset[n] = pow(timeset[n],dz->param[SPL_PCURVE]);
  1948. }
  1949. timeset[n] = 1;
  1950. for(n=0; n < eventscnt;n++) {
  1951. timeset[n] *= (double)durdiff; // Succesive increments in event separation
  1952. timeset[n] += dur1; // Succesive event separations
  1953. }
  1954. if(dz->mode == 0 || dz->mode == 2) { // If this is an attack (pulses before event)
  1955. kk = eventscnt/2; // reverse sequence of durations. NB for kk 6/2 = 3 but 5/2 = 2 so ...
  1956. for(n = 0, m = eventscnt-1; n < kk; n++, m--) { // If eventscnt even, all end events swapped with all start events
  1957. temp = timeset[n]; // e.g. 6 events a:b:c:d:e:f --- swap 6/2 = 3 pairs a/f b/e c/d --> f:e:d:c:b:a
  1958. timeset[n] = timeset[m]; // If eventscnt odd, middle event not swapped, remains where it is
  1959. timeset[m] = temp; // e.g. 5 events a:b:c:d:e ----- swap 5/2 = 2 pairs a/e b/d --> e:d:c:b:a
  1960. }
  1961. }
  1962. if(dz->mode == 0 || dz->mode == 2) { //Splinters BEFORE wavesetgroup
  1963. startdur = timeset[0]; // Remember duration of first step between splinters
  1964. sum = 0.0;
  1965. for(n=0; n < eventscnt;n++) { // Progressively sum event-separations to get relative times
  1966. temp = timeset[n]; // time[0] gets zero
  1967. timeset[n] = sum; // time[1] gets separation[0]
  1968. sum += temp; // time[2] gets separation[0] + separation[1]
  1969. } // time[3] gets separation[0] + separation[1] + separation[2] etc.
  1970. // sum ends up as sum of all event-separations, so
  1971. dz->splintoffset = (int)round(sum * srate); // "splintoffset" gets time where wavesetgroup starts
  1972. if(dz->iparam[SPL_ECNT] > 0) { // If there's an extension (extra regular pulsed splinters before timeset begins)
  1973. extrasamps = (int)round(startdur * srate); // Add their duration to "splintoffset"
  1974. extrasamps *= dz->iparam[SPL_ECNT];
  1975. dz->splintoffset += extrasamps; // This is distance from splinter start to wavesetgrp, in output
  1976. }
  1977. } else {
  1978. dz->enddur = (int)round(dur2 * srate); // Find duration of last step between splinters
  1979. sum = 0.0;
  1980. maxstep = 0.0;
  1981. for(n=0; n < eventscnt;n++) { // Progressively sum event-separations to get relative times
  1982. maxstep = max(maxstep,timeset[n]);
  1983. sum += timeset[n]; // so time[0] gets separation[0] ... i.e. it is separation[0] AFTER the src-wavesetgroup
  1984. timeset[n] = sum; // time[1] gets separation[0] + separation[1]
  1985. } // time[2] gets separation[0] + separation[1] + separation[2] etc.
  1986. dz->splintoffset = (int)ceil(sum * srate); // "splintoffset" gets time where last splinter of sequence starts
  1987. dz->splintoffset += (int)ceil(maxstep * srate); // This is AT LEAST length of last splinter in sequence
  1988. dz->splintoffset += (int)ceil(maxstep * srate); // This allows for posssible randomisation
  1989. lastdur = dz->enddur;
  1990. if(dz->brksize[SPL_RND] || dz->param[SPL_RND] > 0.0) // Allow for maximal (random) contraction of step between events
  1991. lastdur = (int)floor(dz->enddur * 0.5);
  1992. if(dz->brksize[SPL_SHRND] || dz->param[SPL_SHRND] > 0.0) { // Allow for maximal (random) expansion of pulse-size
  1993. minlength = (int)ceil(dz->minlen * 1.5);
  1994. isshrand = 1;
  1995. }
  1996. else
  1997. minlength = dz->minlen;
  1998. if(lastdur <= minlength) {
  1999. if(dz->mode == 1) {
  2000. if(isshrand)
  2001. sprintf(errstr,"Final pulse-rate may cause randomised-length of max-shrunk pulses to overlap. Reduce rate or increase pulse frq.\n");
  2002. else
  2003. sprintf(errstr,"Final pulse-rate causes max-shrunk pulses to overlap. Reduce rate or increase pulse frq.\n");
  2004. } else {
  2005. if(isshrand)
  2006. sprintf(errstr,"Final pulse-rate may cause randomised-length of max-shrunk pulses to overlap. Reduce rate or reduce pulse duration.\n");
  2007. else
  2008. sprintf(errstr,"Final pulse-rate causes max-shrunk pulses to overlap. Reduce rate or reduce pulse duration.\n");
  2009. }
  2010. return DATA_ERROR;
  2011. }
  2012. }
  2013. return FINISHED;
  2014. }
  2015. /******************************** NORMALISE_BUFFER ********************************/
  2016. int normalise_buffer(int windowing_end,dataptr dz)
  2017. {
  2018. double *env = dz->parray[2], maxsamp, thiseval, nexteval, diff, eval;
  2019. float *obuf = dz->sampbuf[1];
  2020. int *loc = dz->iparray[0];
  2021. int e, n, m, k, envsize, maxloc, windowstart, thispos, goalpos, samppos, gap;
  2022. int needs_enveloping = 0, ethis, enext, done;
  2023. int halfwindow = dz->envwindowsize/2;
  2024. do { // For all the normalisable samples, advance by windowlen blocks
  2025. for(n = 0,e = 0; n < windowing_end; n+=dz->envwindowsize,e++) {
  2026. maxsamp = 0.0;
  2027. maxloc = 0;
  2028. for(m=0,k=n;m < dz->envwindowsize;m++,k++) { // In each window, find the maxsamp
  2029. if(fabs(obuf[k]) > maxsamp) {
  2030. maxsamp = fabs(obuf[k]);
  2031. maxloc = m;
  2032. }
  2033. }
  2034. if(e >= dz->arraysize) {
  2035. sprintf(errstr,"envelope arraysize exceeded.\n");
  2036. return PROGRAM_ERROR;
  2037. }
  2038. env[e] = maxsamp; // And store the envelope val
  2039. loc[e] = maxloc; // And position of maximum
  2040. }
  2041. envsize = e;
  2042. env[e] = 0.0; // wrap-around point at end
  2043. loc[e] = halfwindow;
  2044. needs_enveloping = 0;
  2045. for(e = 0;e <= envsize;e++) { // Check where signal exceeds max (0.95)
  2046. if(env[e] > 0.95) { // and force (re-)envelope to reduce level here
  2047. env[e] = 0.95/env[e];
  2048. needs_enveloping = 1; // AND note the re-envelopeing is necessary
  2049. } else // otherwise leave envelope level at 1.0 (no change)
  2050. env[e] = 1.0;
  2051. }
  2052. if(needs_enveloping) { // If enveloping required
  2053. ethis = -1; // Interpolate the re-envelope vals, in order to envelope the src, in situ
  2054. enext = 0;
  2055. done = 0;
  2056. for(windowstart = 0; windowstart < windowing_end; windowstart+=dz->envwindowsize) {
  2057. ethis++;
  2058. enext++;
  2059. thiseval = env[ethis];
  2060. nexteval = env[enext];
  2061. if(thiseval < 1.0 && nexteval == 1.0) {
  2062. thispos = windowstart + loc[ethis]; // Interp from maximum in this-window to middle of non-normalised next-window
  2063. goalpos = windowstart + dz->envwindowsize + halfwindow;
  2064. } else if(thiseval == 1.0 && nexteval < 1.0) {
  2065. thispos = windowstart + halfwindow; // Interp from middle of non-normalised this-window to maximum in next
  2066. goalpos = windowstart + dz->envwindowsize + loc[enext];
  2067. } else if(thiseval < 1.0 && nexteval < 1.0) {
  2068. thispos = windowstart + loc[ethis]; // Interp from max in this window to max in next
  2069. goalpos = windowstart + dz->envwindowsize + loc[enext];
  2070. } else { // (thiseval == 1.0 && nexteval == 1.0) do nothing
  2071. continue;
  2072. }
  2073. samppos = thispos;
  2074. gap = goalpos - thispos;
  2075. diff = nexteval - thiseval;
  2076. for(m=0;m < gap;m++,samppos++) {
  2077. if(samppos >= dz->buflen) {
  2078. done = 1;
  2079. break;
  2080. }
  2081. eval = (double)m/(double)gap;
  2082. eval *= diff;
  2083. eval += thiseval;
  2084. obuf[samppos] = (float)(obuf[samppos] * eval);
  2085. }
  2086. if(done)
  2087. break;
  2088. }
  2089. }
  2090. } while(needs_enveloping); // Do this recursively until nothing is too loud
  2091. return FINISHED;
  2092. }