splinter.c 83 KB

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