cascade.c 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <structures.h>
  24. #include <tkglobals.h>
  25. #include <pnames.h>
  26. #include <filetype.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <logic.h>
  30. #include <globcon.h>
  31. #include <cdpmain.h>
  32. #include <math.h>
  33. #include <mixxcon.h>
  34. #include <osbind.h>
  35. #include <standalone.h>
  36. #include <science.h>
  37. #include <ctype.h>
  38. #include <sfsys.h>
  39. #include <string.h>
  40. #include <srates.h>
  41. #ifdef unix
  42. #define round(x) lround((x))
  43. #endif
  44. #ifndef HUGE
  45. #define HUGE 3.40282347e+38F
  46. #endif
  47. #define CASC_SPLICELEN (5) // mS default splicelen
  48. #define MINECHO (0.01) // -40dB, quietest echo heard
  49. #define CASPANCURVE (0.4) // Causes pan to be faster at start
  50. #define ROOT2 (1.4142136)
  51. #define CAS_MAXLEVEL (0.95)
  52. #define alternating is_rectified
  53. #define spreading is_mapping
  54. #define echomax rampbrksize
  55. #define max_shredcnt total_windows
  56. char errstr[2400];
  57. int anal_infiles = 1;
  58. int sloom = 0;
  59. int sloombatch = 0;
  60. const char* cdp_version = "7.0.0";
  61. //CDP LIB REPLACEMENTS
  62. static int setup_cascade_application(dataptr dz);
  63. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  64. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  65. static int setup_cascade_param_ranges_and_defaults(dataptr dz);
  66. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  67. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  68. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  69. static int establish_application(dataptr dz);
  70. static int initialise_vflags(dataptr dz);
  71. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  72. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  73. static int mark_parameter_types(dataptr dz,aplptr ap);
  74. static int assign_file_data_storage(int infilecnt,dataptr dz);
  75. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  76. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  77. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  78. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  79. static int handle_the_special_data(char *str,double *clipmin,dataptr dz);
  80. static void pancalc(double position,double *leftgain,double *rightgain);
  81. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  82. static int create_cascade_sndbufs(int clipmax,dataptr dz);
  83. static int cascade_params_preprocess(int *clipmax,double *clipmin,int *is_shred,int *max_shredno,dataptr dz);
  84. static void initialise_cascade_random_sequence(int seed);
  85. static void do_shredding(int *shredcnt,int *csscnt,int passno,int cliplen,int spliclen,int max_shredno,dataptr dz);
  86. static void permute_chunks(dataptr dz);
  87. static void insert(int n,int t,dataptr dz);
  88. static void prefix(int n,dataptr dz);
  89. static void shuflup(int k,dataptr dz);
  90. static int cascade(double clipmin,int clipmax,int is_shred,int max_shredno,dataptr dz);
  91. /**************************************** MAIN *********************************************/
  92. int main(int argc,char *argv[])
  93. {
  94. int exit_status;
  95. dataptr dz = NULL;
  96. char **cmdline;
  97. int cmdlinecnt, is_shred = 0, max_shredno = 0;
  98. int n, clipmax;
  99. double clipmin = 0.0;
  100. // aplptr ap;
  101. int is_launched = FALSE;
  102. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  103. fprintf(stdout,"%s\n",cdp_version);
  104. fflush(stdout);
  105. return 0;
  106. }
  107. /* CHECK FOR SOUNDLOOM */
  108. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  109. sloom = 0;
  110. sloombatch = 1;
  111. }
  112. if(sflinit("cdp")){
  113. sfperror("cdp: initialisation\n");
  114. return(FAILED);
  115. }
  116. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  117. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  118. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  119. return(FAILED);
  120. }
  121. dz->itemcnt = 0;
  122. if(!sloom) {
  123. if(argc == 1) {
  124. usage1();
  125. return(FAILED);
  126. } else if(argc == 2) {
  127. usage2(argv[1]);
  128. return(FAILED);
  129. }
  130. }
  131. if(!sloom) {
  132. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  133. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  134. return(FAILED);
  135. }
  136. cmdline = argv;
  137. cmdlinecnt = argc;
  138. if((exit_status = get_the_process_no(argv[0],dz))<0) {
  139. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  140. return(FAILED);
  141. }
  142. cmdline++;
  143. cmdlinecnt--;
  144. dz->maxmode = 10;
  145. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  146. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  147. return(exit_status);
  148. }
  149. cmdline++;
  150. cmdlinecnt--;
  151. // setup_particular_application =
  152. if((exit_status = setup_cascade_application(dz))<0) {
  153. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  154. return(FAILED);
  155. }
  156. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  157. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  158. return(FAILED);
  159. }
  160. } else {
  161. //parse_TK_data() =
  162. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  163. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  164. return(exit_status);
  165. }
  166. }
  167. // ap = dz->application;
  168. // parse_infile_and_hone_type() =
  169. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  170. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  171. return(FAILED);
  172. }
  173. // setup_param_ranges_and_defaults() =
  174. if((exit_status = setup_cascade_param_ranges_and_defaults(dz))<0) {
  175. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  176. return(FAILED);
  177. }
  178. // open_first_infile CDP LIB
  179. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  180. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  181. return(FAILED);
  182. }
  183. cmdlinecnt--;
  184. cmdline++;
  185. // handle_extra_infiles() : redundant
  186. // handle_outfile() =
  187. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  188. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  189. return(FAILED);
  190. }
  191. // handle_formants() redundant
  192. // handle_formant_quiksearch() redundant
  193. if((dz->lparray = (int **)malloc(5 * sizeof(int *)))==NULL) { // Arrays for input cut times, and shred-cut times
  194. sprintf(errstr,"INSUFFICIENT MEMORY to create \"int\" arrays.\n"); // and for remembering randomised vals, for use in 2nd pass
  195. return(MEMORY_ERROR); // (to ensure output level does not change).
  196. }
  197. if(dz->mode >= 5) {
  198. if((exit_status = handle_the_special_data(cmdline[0],&clipmin,dz))<0) {
  199. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  200. return(FAILED);
  201. }
  202. cmdlinecnt--;
  203. cmdline++;
  204. }
  205. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  206. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  207. return(FAILED);
  208. }
  209. // check_param_validity_and_consistency() redundant
  210. is_launched = TRUE;
  211. dz->bufcnt = 6;
  212. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  213. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  214. return(MEMORY_ERROR);
  215. }
  216. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  217. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  218. return(MEMORY_ERROR);
  219. }
  220. for(n = 0;n <dz->bufcnt; n++)
  221. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  222. dz->sampbuf[n] = (float *)0;
  223. //param_preprocess()
  224. if((exit_status = cascade_params_preprocess(&clipmax,&clipmin,&is_shred,&max_shredno,dz))<0) {
  225. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  226. return(FAILED);
  227. }
  228. if((exit_status = create_cascade_sndbufs(clipmax,dz))<0) {
  229. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  230. return(FAILED);
  231. }
  232. //spec_process_file =
  233. if((exit_status = cascade(clipmin,clipmax,is_shred,max_shredno,dz))<0) {
  234. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  235. return(FAILED);
  236. }
  237. if((exit_status = complete_output(dz))<0) { // CDP LIB
  238. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  239. return(FAILED);
  240. }
  241. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  242. free(dz);
  243. return(SUCCEEDED);
  244. }
  245. /**********************************************
  246. REPLACED CDP LIB FUNCTIONS
  247. **********************************************/
  248. /****************************** SET_PARAM_DATA *********************************/
  249. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  250. {
  251. ap->special_data = (char)special_data;
  252. ap->param_cnt = (char)paramcnt;
  253. ap->max_param_cnt = (char)maxparamcnt;
  254. if(ap->max_param_cnt>0) {
  255. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  256. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  257. return(MEMORY_ERROR);
  258. }
  259. strcpy(ap->param_list,paramlist);
  260. }
  261. return(FINISHED);
  262. }
  263. /****************************** SET_VFLGS *********************************/
  264. int set_vflgs
  265. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  266. {
  267. ap->option_cnt = (char) optcnt; /*RWD added cast */
  268. if(optcnt) {
  269. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  270. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  271. return(MEMORY_ERROR);
  272. }
  273. strcpy(ap->option_list,optlist);
  274. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  275. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  276. return(MEMORY_ERROR);
  277. }
  278. strcpy(ap->option_flags,optflags);
  279. }
  280. ap->vflag_cnt = (char) vflagcnt;
  281. ap->variant_param_cnt = (char) vparamcnt;
  282. if(vflagcnt) {
  283. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  284. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  285. return(MEMORY_ERROR);
  286. }
  287. strcpy(ap->variant_list,varlist);
  288. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  289. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  290. return(MEMORY_ERROR);
  291. }
  292. strcpy(ap->variant_flags,varflags);
  293. }
  294. return(FINISHED);
  295. }
  296. /***************************** APPLICATION_INIT **************************/
  297. int application_init(dataptr dz)
  298. {
  299. int exit_status;
  300. int storage_cnt;
  301. int tipc, brkcnt;
  302. aplptr ap = dz->application;
  303. if(ap->vflag_cnt>0)
  304. initialise_vflags(dz);
  305. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  306. ap->total_input_param_cnt = (char)tipc;
  307. if(tipc>0) {
  308. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  309. return(exit_status);
  310. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  311. return(exit_status);
  312. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  313. return(exit_status);
  314. }
  315. brkcnt = tipc;
  316. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  317. if(brkcnt>0) {
  318. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  319. return(exit_status);
  320. }
  321. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  322. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  323. return(exit_status);
  324. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  325. return(exit_status);
  326. }
  327. if((exit_status = mark_parameter_types(dz,ap))<0)
  328. return(exit_status);
  329. // establish_infile_constants() replaced by
  330. dz->infilecnt = 1;
  331. //establish_bufptrs_and_extra_buffers():
  332. return(FINISHED);
  333. }
  334. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  335. /* RWD mallo changed to calloc; helps debug verison run as release! */
  336. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  337. {
  338. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  339. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  340. return(MEMORY_ERROR);
  341. }
  342. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  343. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  344. return(MEMORY_ERROR);
  345. }
  346. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  347. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  348. return(MEMORY_ERROR);
  349. }
  350. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  351. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  352. return(MEMORY_ERROR);
  353. }
  354. return(FINISHED);
  355. }
  356. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  357. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  358. {
  359. int n;
  360. for(n=0;n<storage_cnt;n++) {
  361. dz->is_int[n] = (char)0;
  362. dz->no_brk[n] = (char)0;
  363. }
  364. return(FINISHED);
  365. }
  366. /***************************** MARK_PARAMETER_TYPES **************************/
  367. int mark_parameter_types(dataptr dz,aplptr ap)
  368. {
  369. int n, m; /* PARAMS */
  370. for(n=0;n<ap->max_param_cnt;n++) {
  371. switch(ap->param_list[n]) {
  372. case('0'): break; /* dz->is_active[n] = 0 is default */
  373. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  374. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  375. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  376. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  377. default:
  378. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  379. return(PROGRAM_ERROR);
  380. }
  381. } /* OPTIONS */
  382. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  383. switch(ap->option_list[n]) {
  384. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  385. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  386. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  387. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  388. default:
  389. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  390. return(PROGRAM_ERROR);
  391. }
  392. } /* VARIANTS */
  393. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  394. switch(ap->variant_list[n]) {
  395. case('0'): break;
  396. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  397. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  398. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  399. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  400. default:
  401. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  402. return(PROGRAM_ERROR);
  403. }
  404. } /* INTERNAL */
  405. for(n=0,
  406. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  407. switch(ap->internal_param_list[n]) {
  408. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  409. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  410. case('d'): dz->no_brk[m] = (char)1; break;
  411. default:
  412. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  413. return(PROGRAM_ERROR);
  414. }
  415. }
  416. return(FINISHED);
  417. }
  418. /************************ HANDLE_THE_OUTFILE *********************/
  419. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  420. {
  421. int exit_status;
  422. char *filename = (*cmdline)[0];
  423. if(filename[0]=='-' && filename[1]=='f') {
  424. dz->floatsam_output = 1;
  425. dz->true_outfile_stype = SAMP_FLOAT;
  426. filename+= 2;
  427. }
  428. if(!sloom) {
  429. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  430. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  431. return(DATA_ERROR);
  432. }
  433. }
  434. strcpy(dz->outfilename,filename);
  435. switch(dz->mode) {
  436. case(0):
  437. case(5):
  438. dz->outfile->channels = dz->infile->channels;
  439. break;
  440. case(1):
  441. case(2):
  442. case(6):
  443. case(7):
  444. dz->infile->channels = 2; // Mono in, stereo out
  445. dz->outfile->channels = 2;
  446. break;
  447. case(3):
  448. case(4):
  449. case(8):
  450. case(9):
  451. dz->infile->channels = 8; // Mono in, 8-chan out
  452. dz->outfile->channels = 8;
  453. break;
  454. }
  455. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  456. return(exit_status);
  457. switch(dz->mode) {
  458. case(0):
  459. case(5):
  460. break; // input channels = output channels
  461. default:
  462. dz->infile->channels = 1; // Mono in
  463. break;
  464. }
  465. (*cmdline)++;
  466. (*cmdlinecnt)--;
  467. return(FINISHED);
  468. }
  469. /***************************** ESTABLISH_APPLICATION **************************/
  470. int establish_application(dataptr dz)
  471. {
  472. aplptr ap;
  473. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  474. sprintf(errstr,"establish_application()\n");
  475. return(MEMORY_ERROR);
  476. }
  477. ap = dz->application;
  478. memset((char *)ap,0,sizeof(struct applic));
  479. return(FINISHED);
  480. }
  481. /************************* INITIALISE_VFLAGS *************************/
  482. int initialise_vflags(dataptr dz)
  483. {
  484. int n;
  485. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  486. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  487. return(MEMORY_ERROR);
  488. }
  489. for(n=0;n<dz->application->vflag_cnt;n++)
  490. dz->vflag[n] = FALSE;
  491. return FINISHED;
  492. }
  493. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  494. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  495. {
  496. int n;
  497. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  498. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  499. return(MEMORY_ERROR);
  500. }
  501. for(n=0;n<tipc;n++)
  502. ap->default_val[n] = 0.0;
  503. return(FINISHED);
  504. }
  505. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  506. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  507. {
  508. int n;
  509. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  510. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  511. return(MEMORY_ERROR);
  512. }
  513. for(n=0;n<tipc;n++)
  514. dz->is_active[n] = (char)0;
  515. return(FINISHED);
  516. }
  517. /************************* SETUP_CASCADE_APPLICATION *******************/
  518. int setup_cascade_application(dataptr dz)
  519. {
  520. int exit_status;
  521. aplptr ap;
  522. if((exit_status = establish_application(dz))<0) // GLOBAL
  523. return(FAILED);
  524. ap = dz->application;
  525. // SEE parstruct FOR EXPLANATION of next 2 functions
  526. if(dz->mode < 5) {
  527. if((exit_status = set_param_data(ap,0 ,3,3,"DID"))<0)
  528. return(FAILED);
  529. } else {
  530. if((exit_status = set_param_data(ap,CASCLIPS,3,1,"0I0"))<0)
  531. return(FAILED);
  532. }
  533. if((exit_status = set_vflgs(ap,"ersNC",5,"IDiII","aln",3,0,"000"))<0)
  534. return(FAILED);
  535. // set_legal_infile_structure -->
  536. dz->has_otherfile = FALSE;
  537. // assign_process_logic -->
  538. dz->input_data_type = SNDFILES_ONLY;
  539. dz->process_type = UNEQUAL_SNDFILE;
  540. dz->outfiletype = SNDFILE_OUT;
  541. return application_init(dz); //GLOBAL
  542. }
  543. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  544. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  545. {
  546. int exit_status;
  547. infileptr infile_info;
  548. if(!sloom) {
  549. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  550. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  551. return(MEMORY_ERROR);
  552. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  553. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  554. return(PROGRAM_ERROR);
  555. } else if(infile_info->filetype != SNDFILE) {
  556. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  557. return(DATA_ERROR);
  558. } else if(!(dz->mode == 0 || dz->mode == 5) && infile_info->channels != 1) {
  559. sprintf(errstr,"File %s is not of correct type for Mode %d\n",cmdline[0],dz->mode+1);
  560. return(DATA_ERROR);
  561. }
  562. if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  563. sprintf(errstr,"Failed to copy file parsing information\n");
  564. return(PROGRAM_ERROR);
  565. }
  566. free(infile_info);
  567. }
  568. return(FINISHED);
  569. }
  570. /************************* SETUP_CASCADE_PARAM_RANGES_AND_DEFAULTS *******************/
  571. int setup_cascade_param_ranges_and_defaults(dataptr dz)
  572. {
  573. int exit_status;
  574. aplptr ap = dz->application;
  575. // set_param_ranges()
  576. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  577. // NB total_input_param_cnt is > 0 !!!
  578. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  579. return(FAILED);
  580. // get_param_ranges()
  581. if(dz->mode < 5) {
  582. ap->lo[CAS_CLIP] = 0.005;
  583. ap->hi[CAS_CLIP] = 60.0;
  584. ap->default_val[CAS_CLIP] = .5;
  585. ap->lo[CAS_MAXCLIP] = 0;
  586. ap->hi[CAS_MAXCLIP] = 60.0;
  587. }
  588. ap->lo[CAS_ECHO] = 1;
  589. ap->hi[CAS_ECHO] = 64;
  590. ap->default_val[CAS_ECHO] = 8;
  591. ap->default_val[CAS_MAXCLIP] = 0;
  592. ap->lo[CAS_MAXECHO] = 0;
  593. ap->hi[CAS_MAXECHO] = 64;
  594. ap->default_val[CAS_MAXECHO] = 0;
  595. ap->lo[CAS_RAND] = 0;
  596. ap->hi[CAS_RAND] = 1;
  597. ap->default_val[CAS_RAND] = 0;
  598. ap->lo[CAS_SEED] = 0;
  599. ap->hi[CAS_SEED] = 64;
  600. ap->default_val[CAS_SEED] = 1;
  601. ap->lo[CAS_SHREDNO] = 0;
  602. ap->hi[CAS_SHREDNO] = 64;
  603. ap->default_val[CAS_SHREDNO] = 0;
  604. ap->lo[CAS_SHREDCNT] = 0;
  605. ap->hi[CAS_SHREDCNT] = 64;
  606. ap->default_val[CAS_SHREDCNT] = 0;
  607. dz->maxmode = 10;
  608. if(!sloom)
  609. put_default_vals_in_all_params(dz);
  610. return(FINISHED);
  611. }
  612. /********************************* PARSE_SLOOM_DATA *********************************/
  613. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  614. {
  615. int exit_status;
  616. int cnt = 1, infilecnt;
  617. int filesize, insams, inbrksize;
  618. double dummy;
  619. int true_cnt = 0;
  620. // aplptr ap;
  621. while(cnt<=PRE_CMDLINE_DATACNT) {
  622. if(cnt > argc) {
  623. sprintf(errstr,"Insufficient data sent from TK\n");
  624. return(DATA_ERROR);
  625. }
  626. switch(cnt) {
  627. case(1):
  628. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  629. sprintf(errstr,"Cannot read process no. sent from TK\n");
  630. return(DATA_ERROR);
  631. }
  632. break;
  633. case(2):
  634. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  635. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  636. return(DATA_ERROR);
  637. }
  638. if(dz->mode > 0)
  639. dz->mode--;
  640. //setup_particular_application() =
  641. if((exit_status = setup_cascade_application(dz))<0)
  642. return(exit_status);
  643. // ap = dz->application;
  644. break;
  645. case(3):
  646. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  647. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  648. return(DATA_ERROR);
  649. }
  650. if(infilecnt < 1) {
  651. true_cnt = cnt + 1;
  652. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  653. }
  654. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  655. return(exit_status);
  656. break;
  657. case(INPUT_FILETYPE+4):
  658. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  659. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  660. return(DATA_ERROR);
  661. }
  662. break;
  663. case(INPUT_FILESIZE+4):
  664. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  665. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  666. return(DATA_ERROR);
  667. }
  668. dz->insams[0] = filesize;
  669. break;
  670. case(INPUT_INSAMS+4):
  671. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  672. sprintf(errstr,"Cannot read insams sent from TK\n");
  673. return(DATA_ERROR);
  674. }
  675. dz->insams[0] = insams;
  676. break;
  677. case(INPUT_SRATE+4):
  678. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  679. sprintf(errstr,"Cannot read srate sent from TK\n");
  680. return(DATA_ERROR);
  681. }
  682. break;
  683. case(INPUT_CHANNELS+4):
  684. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  685. sprintf(errstr,"Cannot read channels sent from TK\n");
  686. return(DATA_ERROR);
  687. }
  688. break;
  689. case(INPUT_STYPE+4):
  690. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  691. sprintf(errstr,"Cannot read stype sent from TK\n");
  692. return(DATA_ERROR);
  693. }
  694. break;
  695. case(INPUT_ORIGSTYPE+4):
  696. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  697. sprintf(errstr,"Cannot read origstype sent from TK\n");
  698. return(DATA_ERROR);
  699. }
  700. break;
  701. case(INPUT_ORIGRATE+4):
  702. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  703. sprintf(errstr,"Cannot read origrate sent from TK\n");
  704. return(DATA_ERROR);
  705. }
  706. break;
  707. case(INPUT_MLEN+4):
  708. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  709. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  710. return(DATA_ERROR);
  711. }
  712. break;
  713. case(INPUT_DFAC+4):
  714. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  715. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  716. return(DATA_ERROR);
  717. }
  718. break;
  719. case(INPUT_ORIGCHANS+4):
  720. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  721. sprintf(errstr,"Cannot read origchans sent from TK\n");
  722. return(DATA_ERROR);
  723. }
  724. break;
  725. case(INPUT_SPECENVCNT+4):
  726. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  727. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  728. return(DATA_ERROR);
  729. }
  730. dz->specenvcnt = dz->infile->specenvcnt;
  731. break;
  732. case(INPUT_WANTED+4):
  733. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  734. sprintf(errstr,"Cannot read wanted sent from TK\n");
  735. return(DATA_ERROR);
  736. }
  737. break;
  738. case(INPUT_WLENGTH+4):
  739. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  740. sprintf(errstr,"Cannot read wlength sent from TK\n");
  741. return(DATA_ERROR);
  742. }
  743. break;
  744. case(INPUT_OUT_CHANS+4):
  745. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  746. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  747. return(DATA_ERROR);
  748. }
  749. break;
  750. /* RWD these chanegs to samps - tk will have to deal with that! */
  751. case(INPUT_DESCRIPTOR_BYTES+4):
  752. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  753. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  754. return(DATA_ERROR);
  755. }
  756. break;
  757. case(INPUT_IS_TRANSPOS+4):
  758. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  759. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  760. return(DATA_ERROR);
  761. }
  762. break;
  763. case(INPUT_COULD_BE_TRANSPOS+4):
  764. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  765. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  766. return(DATA_ERROR);
  767. }
  768. break;
  769. case(INPUT_COULD_BE_PITCH+4):
  770. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  771. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  772. return(DATA_ERROR);
  773. }
  774. break;
  775. case(INPUT_DIFFERENT_SRATES+4):
  776. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  777. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  778. return(DATA_ERROR);
  779. }
  780. break;
  781. case(INPUT_DUPLICATE_SNDS+4):
  782. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  783. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  784. return(DATA_ERROR);
  785. }
  786. break;
  787. case(INPUT_BRKSIZE+4):
  788. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  789. sprintf(errstr,"Cannot read brksize sent from TK\n");
  790. return(DATA_ERROR);
  791. }
  792. if(inbrksize > 0) {
  793. switch(dz->input_data_type) {
  794. case(WORDLIST_ONLY):
  795. break;
  796. case(PITCH_AND_PITCH):
  797. case(PITCH_AND_TRANSPOS):
  798. case(TRANSPOS_AND_TRANSPOS):
  799. dz->tempsize = inbrksize;
  800. break;
  801. case(BRKFILES_ONLY):
  802. case(UNRANGED_BRKFILE_ONLY):
  803. case(DB_BRKFILES_ONLY):
  804. case(ALL_FILES):
  805. case(ANY_NUMBER_OF_ANY_FILES):
  806. if(dz->extrabrkno < 0) {
  807. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  808. return(DATA_ERROR);
  809. }
  810. if(dz->brksize == NULL) {
  811. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  812. return(PROGRAM_ERROR);
  813. }
  814. dz->brksize[dz->extrabrkno] = inbrksize;
  815. break;
  816. default:
  817. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  818. dz->input_data_type);
  819. return(PROGRAM_ERROR);
  820. }
  821. break;
  822. }
  823. break;
  824. case(INPUT_NUMSIZE+4):
  825. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  826. sprintf(errstr,"Cannot read numsize sent from TK\n");
  827. return(DATA_ERROR);
  828. }
  829. break;
  830. case(INPUT_LINECNT+4):
  831. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  832. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  833. return(DATA_ERROR);
  834. }
  835. break;
  836. case(INPUT_ALL_WORDS+4):
  837. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  838. sprintf(errstr,"Cannot read all_words sent from TK\n");
  839. return(DATA_ERROR);
  840. }
  841. break;
  842. case(INPUT_ARATE+4):
  843. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  844. sprintf(errstr,"Cannot read arate sent from TK\n");
  845. return(DATA_ERROR);
  846. }
  847. break;
  848. case(INPUT_FRAMETIME+4):
  849. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  850. sprintf(errstr,"Cannot read frametime sent from TK\n");
  851. return(DATA_ERROR);
  852. }
  853. dz->frametime = (float)dummy;
  854. break;
  855. case(INPUT_WINDOW_SIZE+4):
  856. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  857. sprintf(errstr,"Cannot read window_size sent from TK\n");
  858. return(DATA_ERROR);
  859. }
  860. break;
  861. case(INPUT_NYQUIST+4):
  862. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  863. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  864. return(DATA_ERROR);
  865. }
  866. break;
  867. case(INPUT_DURATION+4):
  868. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  869. sprintf(errstr,"Cannot read duration sent from TK\n");
  870. return(DATA_ERROR);
  871. }
  872. break;
  873. case(INPUT_MINBRK+4):
  874. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  875. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  876. return(DATA_ERROR);
  877. }
  878. break;
  879. case(INPUT_MAXBRK+4):
  880. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  881. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  882. return(DATA_ERROR);
  883. }
  884. break;
  885. case(INPUT_MINNUM+4):
  886. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  887. sprintf(errstr,"Cannot read minnum sent from TK\n");
  888. return(DATA_ERROR);
  889. }
  890. break;
  891. case(INPUT_MAXNUM+4):
  892. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  893. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  894. return(DATA_ERROR);
  895. }
  896. break;
  897. default:
  898. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  899. return(PROGRAM_ERROR);
  900. }
  901. cnt++;
  902. }
  903. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  904. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  905. return(DATA_ERROR);
  906. }
  907. if(true_cnt)
  908. cnt = true_cnt;
  909. *cmdlinecnt = 0;
  910. while(cnt < argc) {
  911. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  912. return(exit_status);
  913. cnt++;
  914. }
  915. return(FINISHED);
  916. }
  917. /********************************* GET_TK_CMDLINE_WORD *********************************/
  918. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  919. {
  920. if(*cmdlinecnt==0) {
  921. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  922. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  923. return(MEMORY_ERROR);
  924. }
  925. } else {
  926. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  927. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  928. return(MEMORY_ERROR);
  929. }
  930. }
  931. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  932. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  933. return(MEMORY_ERROR);
  934. }
  935. strcpy((*cmdline)[*cmdlinecnt],q);
  936. (*cmdlinecnt)++;
  937. return(FINISHED);
  938. }
  939. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  940. int assign_file_data_storage(int infilecnt,dataptr dz)
  941. {
  942. int exit_status;
  943. int no_sndfile_system_files = FALSE;
  944. dz->infilecnt = infilecnt;
  945. if((exit_status = allocate_filespace(dz))<0)
  946. return(exit_status);
  947. if(no_sndfile_system_files)
  948. dz->infilecnt = 0;
  949. return(FINISHED);
  950. }
  951. /************************* redundant functions: to ensure libs compile OK *******************/
  952. int assign_process_logic(dataptr dz)
  953. {
  954. return(FINISHED);
  955. }
  956. void set_legal_infile_structure(dataptr dz)
  957. {}
  958. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  959. {
  960. return(FINISHED);
  961. }
  962. int setup_internal_arrays_and_array_pointers(dataptr dz)
  963. {
  964. return(FINISHED);
  965. }
  966. int establish_bufptrs_and_extra_buffers(dataptr dz)
  967. {
  968. return(FINISHED);
  969. }
  970. int read_special_data(char *str,dataptr dz)
  971. {
  972. return(FINISHED);
  973. }
  974. int inner_loop
  975. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  976. {
  977. return(FINISHED);
  978. }
  979. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  980. {
  981. return(FINISHED);
  982. }
  983. /******************************** USAGE1 ********************************/
  984. int usage1()
  985. {
  986. usage2("cascade");
  987. return(USAGE_ONLY);
  988. }
  989. /********************************************************************************************/
  990. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  991. {
  992. if(!strcmp(prog_identifier_from_cmdline,"cascade")) dz->process = CASCADE;
  993. else {
  994. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  995. return(USAGE_ONLY);
  996. }
  997. return(FINISHED);
  998. }
  999. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1000. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1001. {
  1002. int n;
  1003. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1004. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1005. return(MEMORY_ERROR);
  1006. }
  1007. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1008. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1009. return(MEMORY_ERROR);
  1010. }
  1011. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1012. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1013. return(MEMORY_ERROR);
  1014. }
  1015. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1016. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1017. return(MEMORY_ERROR);
  1018. }
  1019. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1020. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1021. return(MEMORY_ERROR);
  1022. }
  1023. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1024. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1025. return(MEMORY_ERROR);
  1026. }
  1027. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1028. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1029. return(MEMORY_ERROR);
  1030. }
  1031. for(n=0;n<brkcnt;n++) {
  1032. dz->brk[n] = NULL;
  1033. dz->brkptr[n] = NULL;
  1034. dz->brkinit[n] = 0;
  1035. dz->brksize[n] = 0;
  1036. }
  1037. return(FINISHED);
  1038. }
  1039. /******************************** USAGE2 ********************************/
  1040. int usage2(char *str)
  1041. {
  1042. if(!strcmp(str,"cascade")) {
  1043. fprintf(stdout,
  1044. "USAGE: cascade cascade 1-5 inf outf clipsize echos clipmax [-eechosmax] \n"
  1045. "OR: cascade cascade 6-10 inf outf cuts echos [-eechosmax]\n"
  1046. "\n"
  1047. "AND: [-rrand] [-sseed] [-Nshredno -Cshredcnt -a] [-l] [-n]\n"
  1048. "\n"
  1049. "Successive segments of src are repeat-echoed, and echosets superimposed on src.\n"
  1050. "\n"
  1051. "Modes\n"
  1052. "1,6: N-channels in -> N channels out: Every echo in same N-channels.\n"
  1053. "2,7: Mono (left in output) ->stereo: Echosets pan to right.\n"
  1054. "3,8: Mono (centre in output)->stereo: Echosets pan alternately to L and R.\n"
  1055. "4,9: Mono (ch1 in output) -> 8chan: Every echo steps R, to next channel.\n"
  1056. "5,10: Mono (ch1 in outout) -> 8chan: Echos of 1st echoset step R,next set step L,etc.\n"
  1057. "\n"
  1058. "CLIPSIZE (Modes 1-5) Duration of segments to echo. Time-variable.\n"
  1059. "or (Range .005 to 60 secs)\n"
  1060. "CUTS (Modes 6-10) Textfile of (successive) src cut-times, creating segs to echo.\n"
  1061. "\n"
  1062. "ECHOS Number of echos. Time-variable. (Range 1 to 64)\n"
  1063. "\n"
  1064. "CLIPMAX Max duration of clips (time-variable). \"CLIPSIZE\" now read as minimum.\n"
  1065. " Actual clipsize is a random val between \"clipsize\" and \"clipmax\".\n"
  1066. " If \"clipmax\" is set to zero, it is ignored.\n"
  1067. "\n"
  1068. "ECHOSMAX Max number of echos (time-variable). \"ECHOS\" now read as minimum.\n"
  1069. " Actual number of echos is a random val between \"echos\" and \"echosmax\".\n"
  1070. " If \"echosmax\" is set to zero, it is ignored.\n"
  1071. "\n"
  1072. "RAND Randomise timesteps between echos in echo-set: Range 0-1, time-variable.\n"
  1073. "SEED With same non-zero value, randomised vals are exactly same on new pass.\n"
  1074. "\n"
  1075. "SHREDNO In each echo-stream, cut previous echo into \"shredno\" parts,\n"
  1076. " and random-shuffle parts to make next echo. Range 2-16,time-variable.\n"
  1077. "SHREDCNT No of shreds to do, to create next echo element. Range 1-16,time-variable.\n"
  1078. " BOTH \"shredno\" and \"shredcnt\" must be set for shredding to take place.\n"
  1079. "-a Also shred original clip. Only valid if \"shredno\" & \"shredcnt\" set.\n"
  1080. "\n"
  1081. "-l Echos decay linearly in level (default, log decay - initial decays faster).\n"
  1082. "-n If output low, normalise it. (high output is normalised by default).\n");
  1083. } else
  1084. fprintf(stdout,"Unknown option '%s'\n",str);
  1085. return(USAGE_ONLY);
  1086. }
  1087. int usage3(char *str1,char *str2)
  1088. {
  1089. fprintf(stderr,"Insufficient parameters on command line.\n");
  1090. return(USAGE_ONLY);
  1091. }
  1092. /******************************** CASCADE ********************************/
  1093. int cascade(double clipmin,int clipmax,int is_shred,int max_shredno,dataptr dz)
  1094. {
  1095. int exit_status, clipcnt, inchans, outchans, passno, panright, thischan;
  1096. double thistime, atten, level, splicatten = -1.0, leftgain, rightgain, maxsamp, diff, pan, panfactor, normaliser = 0.0, srate, offset;
  1097. int readsamps = 0, totalsamps = 0, totalabsamps, lastsamptime, ebufpos, obufpos, startobufpos, shredcnt, rcnt, csscnt;
  1098. int outgrps, maxwrite, cliplen, rval, echocnt, samps_written, effective_cliplen, randrange, true_gp_ebufpos, true_gp_obufpos, offsetcnt, maxclips, e, n, m;
  1099. int *cliparray = NULL, *clipstore = dz->lparray[3];
  1100. double *offsets;
  1101. float *ibuf, *echobuf, *obuf, *ovflwbuf;
  1102. int spliclen, splicendstt, minclip;
  1103. maxclips = (int)ceil(dz->duration/clipmin) + 4; // Maximum possible number of clips cut from file (+4 for SAFETY)
  1104. if((offsets = (double *)malloc((maxclips * dz->echomax) * sizeof(double)))==NULL) {
  1105. sprintf(errstr,"INSUFFICIENT MEMORY to create offsets array. (2)\n");
  1106. return(MEMORY_ERROR); // Stores any random offset values, during passno 0, for use in pass 1
  1107. }
  1108. if(is_shred && dz->iparam[CAS_SEED] == 0) // Shredding uses a rand process, which needs to be identical on the 2 passes
  1109. dz->iparam[CAS_SEED] = 2; // SO if SEED has not been set (non-zero val) set a value now (2 : arbitrary)
  1110. dz->tempsize = (dz->insams[0]/dz->infile->channels) * dz->outfile->channels;
  1111. ibuf = dz->sampbuf[0];
  1112. echobuf = dz->sampbuf[3];
  1113. obuf = dz->sampbuf[4];
  1114. ovflwbuf = dz->sampbuf[5];
  1115. inchans = dz->infile->channels;
  1116. outchans = dz->outfile->channels;
  1117. srate = (double)dz->infile->srate;
  1118. spliclen = (int)round(CASC_SPLICELEN * MS_TO_SECS * srate);
  1119. minclip = spliclen * 2 * inchans;
  1120. if(dz->mode >= 5)
  1121. cliparray = dz->lparray[0];
  1122. for(passno = 0; passno < 2; passno++) {
  1123. display_virtual_time(0,dz);
  1124. initialise_cascade_random_sequence(dz->iparam[CAS_SEED]);
  1125. switch(passno) {
  1126. case(0): fprintf(stdout,"INFO: Checking level.\n"); break;
  1127. case(1): fprintf(stdout,"INFO: Generating output.\n"); break;
  1128. }
  1129. fflush(stdout);
  1130. memset((char *)obuf,0,dz->buflen2 * 2 * sizeof(float)); // Empty obuf and ovflwbuf
  1131. sndseekEx(dz->ifd[0],0,0);
  1132. panright = 1; // default to pan to right
  1133. clipcnt = 0;
  1134. thistime = 0.0;
  1135. lastsamptime = 0;
  1136. totalabsamps = 0;
  1137. obufpos = 0;
  1138. maxsamp = 0.0;
  1139. maxwrite = 0;
  1140. offsetcnt = 0;
  1141. true_gp_obufpos = 0; // unrandomised position in obuf, in grp-samples
  1142. dz->total_samps_written = 0;
  1143. shredcnt = 1;
  1144. rcnt = 0; // Count randomised values of echocnt and cliplen
  1145. csscnt = 0; // Count randomised values of chunk scatter
  1146. for(;;) {
  1147. if(dz->mode >= 5) {
  1148. totalsamps = cliparray[clipcnt]; // counted in groups
  1149. cliplen = totalsamps - lastsamptime;
  1150. lastsamptime = totalsamps;
  1151. } else {
  1152. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  1153. return exit_status;
  1154. dz->iparam[CAS_CLIP] = (int)round(dz->param[CAS_CLIP] * dz->infile->srate);
  1155. if(dz->param[CAS_MAXCLIP] == 0.0) {
  1156. cliplen = dz->iparam[CAS_CLIP];
  1157. } else {
  1158. if(passno == 0) {
  1159. dz->iparam[CAS_MAXCLIP] = (int)round(dz->param[CAS_MAXCLIP] * dz->infile->srate);
  1160. diff = dz->iparam[CAS_MAXCLIP] - dz->iparam[CAS_CLIP];
  1161. rval = (int)floor(drand48() * diff);
  1162. cliplen = dz->iparam[CAS_CLIP] + rval;
  1163. clipstore[rcnt++] = cliplen;
  1164. } else
  1165. cliplen = clipstore[rcnt++];
  1166. }
  1167. }
  1168. if(clipcnt > 0) { // After 1st clip, we baktrak by splicelen, to overlap with previous clip.
  1169. totalabsamps -= spliclen * dz->infile->channels; // So totalabssamps (position in infile) baktraks by splicelen
  1170. cliplen += spliclen; // and clip extended by spliclen
  1171. }
  1172. readsamps = cliplen * dz->infile->channels;
  1173. clipcnt++;
  1174. totalabsamps += readsamps;
  1175. if(dz->iparam[CAS_MAXECHO] == 0)
  1176. echocnt = dz->iparam[CAS_ECHO];
  1177. else {
  1178. if(passno == 0) {
  1179. diff = dz->iparam[CAS_MAXECHO] - dz->iparam[CAS_ECHO];
  1180. rval = (int)floor(drand48() * diff);
  1181. echocnt = dz->iparam[CAS_ECHO] + rval;
  1182. clipstore[rcnt++] = (int)echocnt;
  1183. } else
  1184. echocnt = (int)clipstore[rcnt++];
  1185. }
  1186. memset((char *)ibuf,0,dz->buflen * sizeof(float));
  1187. if((exit_status = read_samps(ibuf,dz))<0) // Read samples at appropriate place
  1188. return(exit_status);
  1189. if(dz->ssampsread <= minclip)
  1190. break;
  1191. if(dz->ssampsread < readsamps) { // If insufficient samples to make the specified clip, shorten the clip
  1192. totalabsamps -= readsamps;
  1193. readsamps = dz->ssampsread;
  1194. cliplen = readsamps/dz->infile->channels;
  1195. totalabsamps += readsamps;
  1196. }
  1197. effective_cliplen = cliplen - spliclen;
  1198. randrange = effective_cliplen - 1; // Range for possible random change of echo entry-time, in grp-samples.
  1199. if(dz->vflag[CAS_LINEAR])
  1200. atten = (1.0 - MINECHO)/(double)echocnt;
  1201. else
  1202. atten = pow(MINECHO,1.0/(double)echocnt); // Caluclate attenuation-at-each-echo to produce final echo level of MINECHO
  1203. level = 1.0;
  1204. ebufpos = 0; // Sample position in echobuf
  1205. true_gp_ebufpos = 0; // unrandomised position in echobuf, in grp-samples
  1206. startobufpos = obufpos;
  1207. memset((char *)echobuf,0,dz->buflen2 * sizeof(float)); // Clear echobuf
  1208. splicendstt = cliplen - spliclen; // Start of endsplice, counted in group-samples.
  1209. if(is_shred && dz->vflag[CAS_SHREDSRC]) // If source is to be shredded, do it
  1210. do_shredding(&shredcnt,&csscnt,passno,cliplen,spliclen,max_shredno,dz);
  1211. switch(dz->mode) {
  1212. case(0): // In simple echos (no motion, but possibly multichan : mode 0)
  1213. case(1): // or mono into stereo
  1214. case(2):
  1215. case(5):
  1216. case(6):
  1217. case(7):
  1218. for(e=0;e <= echocnt; e++) { // For original source and all echos
  1219. for(n=0;n < cliplen; n++) { // Copy the input clip to output
  1220. if(n < spliclen) // Splicing start and end when appropriate
  1221. splicatten = (double)n/(double)spliclen;
  1222. else if(n >= splicendstt)
  1223. splicatten = (double)(cliplen - n - 1)/(double)spliclen;
  1224. else
  1225. splicatten = 1.0;
  1226. for(m = 0; m < inchans; m++) {
  1227. echobuf[ebufpos] = (float)(echobuf[ebufpos] + (ibuf[(n * inchans) + m] * level * splicatten));
  1228. ebufpos++;
  1229. }
  1230. }
  1231. if(is_shred)
  1232. do_shredding(&shredcnt,&csscnt,passno,cliplen,spliclen,max_shredno,dz);
  1233. if((dz->param[CAS_RAND] > 0) && (e < echocnt)) {// Last echo must be NOT random-shifted
  1234. true_gp_ebufpos += cliplen; // to ensure complete set of echos fits within alotted buffer space
  1235. if(e < echocnt - 1) {
  1236. if(passno == 0) {
  1237. //HEREH STORE e
  1238. offset = (drand48() * 2.0) - 1.0; // Range -1 to 1
  1239. offsets[offsetcnt++] = offset;
  1240. } else
  1241. offset = offsets[offsetcnt++];
  1242. offset *= dz->param[CAS_RAND]; // Range +- randparam val
  1243. offset *= randrange; // Range +- within size of permissible shift
  1244. ebufpos = true_gp_ebufpos + (int)floor(offset);
  1245. } else
  1246. ebufpos = true_gp_ebufpos; // Last echo always in unrandomised place place
  1247. ebufpos *= inchans; // Change to total (ungrouped) sample count
  1248. }
  1249. ebufpos -= spliclen * inchans; // Baktrak (splices echos together if not time-randomised)
  1250. if(dz->vflag[CAS_LINEAR])
  1251. level -= atten;
  1252. else
  1253. level *= atten; // And attenuate from echo to echo
  1254. }
  1255. ebufpos += spliclen * inchans; // Advance to end of echo-output, ready for outputting data
  1256. break;
  1257. default: // FOR MONO TO MULTICHANNEL
  1258. for(e=0;e <= echocnt; e++) { // For original source and all echos
  1259. for(n=0;n < cliplen; n++) { // Copy the input clip to output
  1260. if(ebufpos < spliclen) // Splicing start and end when appropriate
  1261. splicatten = (double)n/(double)spliclen;
  1262. else if(ebufpos >= splicendstt)
  1263. splicatten = (double)(cliplen - n - 1)/(double)spliclen;
  1264. else
  1265. splicatten = 1.0; // Here source is alwats mono
  1266. echobuf[ebufpos++] = (float)(ibuf[n] * level * splicatten);
  1267. }
  1268. for(n=0; n < ebufpos; n++) { // Copy each echo of the clip into output buffer AT THIS STAGE
  1269. obuf[obufpos] = (float)(obuf[obufpos] + echobuf[n]);
  1270. obufpos += outchans; // advance to next corresponding channel's sample
  1271. }
  1272. maxwrite = max(maxwrite,obufpos); // Check maxwrite at each pass, as obufpos may backtrack (see next lines)
  1273. if(is_shred)
  1274. do_shredding(&shredcnt,&csscnt,passno,cliplen,spliclen,max_shredno,dz);
  1275. if(dz->param[CAS_RAND] > 0) {
  1276. thischan = obufpos % 8;
  1277. true_gp_obufpos += cliplen - spliclen;
  1278. if(e < echocnt - 1) {
  1279. if(passno == 0) {
  1280. //HEREH STORE e
  1281. offset = (drand48() * 2.0) - 1.0; // Range -1 to 1
  1282. offsets[offsetcnt++] = offset;
  1283. } else
  1284. offset = offsets[offsetcnt++];
  1285. offset *= dz->param[CAS_RAND]; // Range +- randparam val
  1286. offset *= randrange; // Range +- within size of permissible shift
  1287. obufpos = true_gp_obufpos + (int)floor(offset);
  1288. } else // penultimate echo fixes final echo to be in unrandomised position
  1289. obufpos = true_gp_obufpos; // Last echo always in unrandomised place place
  1290. obufpos *= outchans; // Change to total (ungrouped) sample count
  1291. obufpos += thischan; // Offset to existing channel
  1292. }
  1293. if(e < echocnt) {
  1294. if(panright > 0)
  1295. obufpos++; // Move to next output chan for next echo
  1296. else
  1297. obufpos--; // Move to previous output chan for next echo
  1298. }
  1299. memset((char *)echobuf,0,dz->buflen2 * sizeof(float));
  1300. if(dz->vflag[CAS_LINEAR])
  1301. level -= atten;
  1302. else
  1303. level *= atten; // And attenuate from echo to echo
  1304. ebufpos = 0; // Reset echobuffer for next echo
  1305. }
  1306. if(dz->alternating) // In alternating modes, swap between clockwise and anticlockwise motion
  1307. panright = -panright;
  1308. outgrps = maxwrite/outchans; // Round up maxwrite to a whole (multichan) set of samples
  1309. if(outgrps * outchans < maxwrite)
  1310. outgrps++;
  1311. maxwrite = outgrps * outchans;
  1312. break;
  1313. }
  1314. // For Mode 0 and stereo-output modes, now write to output buffer
  1315. switch(dz->mode) {
  1316. case(0):
  1317. case(5):
  1318. for(n=0; n < ebufpos; n++) { // Copy echoed clip into output buffer
  1319. obuf[obufpos] = (float)(obuf[obufpos] + echobuf[n]);
  1320. obufpos++;
  1321. }
  1322. maxwrite = max(maxwrite,obufpos);
  1323. outgrps = maxwrite/outchans; // Round up maxwrite to a whole (multichan) set of samples
  1324. if(outgrps * outchans < maxwrite)
  1325. outgrps++;
  1326. maxwrite = outgrps * outchans;
  1327. break;
  1328. case(1): // Mono source --> Stereo
  1329. case(2):
  1330. case(6):
  1331. case(7):
  1332. panfactor = (double)(ebufpos - 1);
  1333. for(n=0; n < ebufpos; n++) { // Copy echoed clip into output buffer, panning left to right
  1334. pan = (double)n/panfactor; // Pan position in range 0 to 1
  1335. pan = pow(pan,CASPANCURVE); // Bias the pan to be faster at start
  1336. if(dz->spreading)
  1337. pan = (pan * 2.0) - 1.0; // Pan position in range -1 to 1 left to right)
  1338. else if(panright < 0)
  1339. pan *= -1.0; // Pan position in range 0 to -1 centre to left)
  1340. else
  1341. ; // Pan position in range 0 to 1 centre to right)
  1342. pancalc(pan,&leftgain,&rightgain);
  1343. obuf[obufpos] = (float)(obuf[obufpos] + (echobuf[n] * leftgain));
  1344. obufpos++;
  1345. obuf[obufpos] = (float)(obuf[obufpos] + (echobuf[n] * rightgain));
  1346. obufpos++;
  1347. }
  1348. maxwrite = max(maxwrite,obufpos);
  1349. outgrps = maxwrite/outchans; // Round up maxwrite to a whole (multichan) set of samples
  1350. if(outgrps * outchans < maxwrite)
  1351. outgrps++;
  1352. maxwrite = outgrps * outchans;
  1353. if(dz->alternating)
  1354. panright = -panright; // Alternating modes : alternate pans to left and right)
  1355. break;
  1356. }
  1357. // MOVE TO WRITE POSITION FOR NEXT SET-OF-ECHOS
  1358. // Move write-position for next set-of-echos, baktraking by a splicelen
  1359. obufpos = startobufpos + ((cliplen - spliclen) * outchans);
  1360. true_gp_obufpos = obufpos/outchans;
  1361. if(obufpos >= dz->buflen2) { // and if beyond end of obuf, do write
  1362. if(passno == 0) {
  1363. for(n=0;n < dz->buflen2;n++)
  1364. maxsamp = max(maxsamp,fabs(obuf[n]));
  1365. } else {
  1366. for(n=0;n < dz->buflen2;n++)
  1367. obuf[n] = (float)(obuf[n] * normaliser);
  1368. if((samps_written = fputfbufEx(obuf,dz->buflen2,dz->ofd))<=0) {
  1369. sprintf(errstr,"Can't write to output soundfile: %s\n",sferrstr());
  1370. return(SYSTEM_ERROR);
  1371. }
  1372. dz->total_samps_written += samps_written;
  1373. } // then copy back any overflow
  1374. dz->process = GREV; // Force correct display of progress_bar in Loom
  1375. display_virtual_time(totalabsamps,dz);
  1376. dz->process = CASCADE;
  1377. memset((char *)obuf,0,dz->buflen2 * sizeof(float));
  1378. memcpy((char *)obuf,(char *)ovflwbuf,dz->buflen2 * sizeof(float));
  1379. memset((char *)ovflwbuf,0,dz->buflen2 * sizeof(float));
  1380. obufpos -= dz->buflen2;
  1381. true_gp_obufpos -= dz->buflen2/outchans;
  1382. maxwrite -= dz->buflen2;
  1383. }
  1384. if(totalabsamps >= dz->insams[0])
  1385. break;
  1386. sndseekEx(dz->ifd[0],totalabsamps,0);
  1387. }
  1388. if(maxwrite > 0) {
  1389. if(passno == 0) {
  1390. for(n=0;n < maxwrite;n++)
  1391. maxsamp = max(maxsamp,fabs(obuf[n]));
  1392. } else {
  1393. for(n=0;n < maxwrite;n++)
  1394. obuf[n] = (float)(obuf[n] * normaliser);
  1395. if((samps_written = fputfbufEx(obuf,maxwrite,dz->ofd))<=0) { // Write remaining samps
  1396. sprintf(errstr,"Can't write to output soundfile: %s\n",sferrstr());
  1397. return(SYSTEM_ERROR);
  1398. }
  1399. dz->total_samps_written += samps_written;
  1400. }
  1401. dz->process = GREV;
  1402. display_virtual_time(totalabsamps,dz);
  1403. dz->process = CASCADE;
  1404. }
  1405. if(passno == 0) {
  1406. if(flteq(maxsamp,0.0)) {
  1407. sprintf(errstr,"No significant signal in output.\n");
  1408. return(PROGRAM_ERROR);
  1409. }
  1410. if(dz->vflag[CAS_UPNORMAL])
  1411. normaliser = CAS_MAXLEVEL/maxsamp;
  1412. else {
  1413. normaliser = 1.0;
  1414. if(maxsamp > CAS_MAXLEVEL)
  1415. normaliser = CAS_MAXLEVEL/maxsamp;
  1416. }
  1417. }
  1418. }
  1419. return FINISHED;
  1420. }
  1421. /******************************** CASCADE_PARAMS_PREPROCESS ********************************/
  1422. int cascade_params_preprocess(int *clipmax,double *clipmin,int *is_shred,int *max_shredno,dataptr dz)
  1423. {
  1424. int exit_status;
  1425. double thisclipmax, thisclipmin = 0.0, thisclipmaxmin, maxecho, this_echomin, this_echomax, this_shredno;
  1426. double effective_clipmin, mincliplen, srate = (double)dz->infile->srate;
  1427. int this_clipmax, n, thiscut, lastclip, spliclen, min_shredcnt, min_shredno, arraysize;
  1428. int *cliparray = NULL;
  1429. if(dz->param[CAS_MAXECHO] == 0)
  1430. dz->brksize[CAS_MAXECHO] = 0;
  1431. if(dz->mode >= 5) {
  1432. dz->param[CAS_MAXCLIP] = 0.0;
  1433. dz->brksize[CAS_MAXCLIP] = 0;
  1434. dz->param[CAS_CLIP] = 0.0;
  1435. dz->brksize[CAS_CLIP] = 0;
  1436. cliparray = dz->lparray[0];
  1437. *clipmax = 0;
  1438. lastclip = 0;
  1439. for(n=0;n < dz->itemcnt;n++) {
  1440. thiscut = cliparray[n] - lastclip;
  1441. *clipmax = max(*clipmax,thiscut);
  1442. lastclip = cliparray[n];
  1443. }
  1444. } else {
  1445. if(dz->param[CAS_MAXCLIP] == 0)
  1446. dz->brksize[CAS_MAXCLIP] = 0;
  1447. if(dz->brksize[CAS_CLIP]) {
  1448. if((exit_status = get_maxvalue_in_brktable(&thisclipmax,CAS_CLIP,dz))<0)
  1449. return exit_status;
  1450. *clipmax = (int)ceil(thisclipmax * srate);
  1451. if((exit_status = get_minvalue_in_brktable(&thisclipmin,CAS_CLIP,dz))<0)
  1452. return exit_status;
  1453. } else {
  1454. thisclipmin = dz->param[CAS_CLIP];
  1455. dz->iparam[CAS_CLIP] = (int)round(dz->param[CAS_CLIP] * srate);
  1456. *clipmax = dz->iparam[CAS_CLIP];
  1457. }
  1458. if(dz->brksize[CAS_MAXCLIP]) {
  1459. if((exit_status = get_minvalue_in_brktable(&thisclipmaxmin,CAS_MAXCLIP,dz))<0)
  1460. return exit_status;
  1461. if(thisclipmaxmin < dz->application->lo[CAS_CLIP]) {
  1462. sprintf(errstr,"Brktable for clipmax contains invalid value(s) (below %lf secs)\n",dz->application->lo[CAS_CLIP]);
  1463. return DATA_ERROR;
  1464. }
  1465. thisclipmin = min(thisclipmin,thisclipmaxmin);
  1466. if((exit_status = get_maxvalue_in_brktable(&thisclipmax,CAS_MAXCLIP,dz))<0)
  1467. return exit_status;
  1468. this_clipmax = (int)ceil(thisclipmax * srate);
  1469. *clipmax = max(*clipmax,this_clipmax);
  1470. } else if (dz->param[CAS_MAXCLIP] > 0) {
  1471. if (dz->param[CAS_MAXCLIP] < dz->application->lo[CAS_CLIP]) {
  1472. sprintf(errstr,"Clipmax value (%lf) invalid (below %lf secs)\n",dz->param[CAS_MAXCLIP],dz->application->lo[CAS_CLIP]);
  1473. return DATA_ERROR;
  1474. }
  1475. thisclipmin = min(thisclipmin,dz->param[CAS_MAXCLIP]);
  1476. dz->iparam[CAS_MAXCLIP] = (int)ceil(dz->param[CAS_MAXCLIP] * srate);// Max Clip duration in grouped-samples
  1477. *clipmax = max(*clipmax,dz->iparam[CAS_MAXCLIP]);
  1478. }
  1479. *clipmin = thisclipmin;
  1480. effective_clipmin = *clipmin - (CASC_SPLICELEN * MS_TO_SECS);
  1481. dz->itemcnt = (int)ceil(dz->duration/effective_clipmin) + 1; // Max possible number of clips
  1482. }
  1483. if(dz->brksize[CAS_ECHO]) {
  1484. if((exit_status = get_maxvalue_in_brktable(&maxecho,CAS_ECHO,dz))<0)
  1485. return exit_status;
  1486. dz->echomax = (int)round(maxecho);
  1487. } else
  1488. dz->echomax = dz->iparam[CAS_ECHO]; // Max no of echos
  1489. if(dz->brksize[CAS_MAXECHO]) {
  1490. if((exit_status = get_minvalue_in_brktable(&this_echomin,CAS_MAXECHO,dz))<0)
  1491. return exit_status;
  1492. if((int)round(this_echomin) < (int)round(dz->application->lo[CAS_ECHO])) {
  1493. sprintf(errstr,"Brktable for echomax contains invalid value (%d) (below %d)\n",(int)round(this_echomin),(int)round(dz->application->lo[CAS_ECHO]));
  1494. return DATA_ERROR;
  1495. }
  1496. if((exit_status = get_maxvalue_in_brktable(&this_echomax,CAS_MAXECHO,dz))<0)
  1497. return exit_status;
  1498. dz->echomax = max(dz->echomax,(int)round(this_echomax));
  1499. } else if (dz->iparam[CAS_MAXECHO] > 0) {
  1500. if ((int)round(dz->iparam[CAS_MAXECHO]) < (int)round(dz->application->lo[CAS_ECHO])) {
  1501. sprintf(errstr,"Echomax value (%d) invalid (below %d)\n",(int)round(dz->iparam[CAS_MAXECHO]),(int)round(dz->application->lo[CAS_ECHO]));
  1502. return DATA_ERROR;
  1503. }
  1504. dz->echomax = max(dz->echomax,dz->iparam[CAS_MAXECHO]); // Max no of echos
  1505. }
  1506. spliclen = (int)round(CASC_SPLICELEN * MS_TO_SECS * srate);
  1507. *clipmax += spliclen;
  1508. if(dz->brksize[CAS_SHREDCNT]) {
  1509. if((exit_status = get_minvalue_in_brktable(&this_shredno,CAS_SHREDNO,dz))<0)
  1510. return exit_status;
  1511. min_shredcnt = (int)round(this_shredno);
  1512. if(min_shredcnt < 1) {
  1513. sprintf(errstr,"Invalid shred count (%d) in shred-count file. (Minimum 1).\n",min_shredcnt);
  1514. return DATA_ERROR;
  1515. }
  1516. if((exit_status = get_maxvalue_in_brktable(&this_shredno,CAS_SHREDNO,dz))<0)
  1517. return exit_status;
  1518. dz->max_shredcnt = (int)round(this_shredno);
  1519. } else {
  1520. min_shredcnt = dz->iparam[CAS_SHREDCNT];
  1521. dz->max_shredcnt = dz->iparam[CAS_SHREDCNT];
  1522. }
  1523. if(dz->brksize[CAS_SHREDNO]) {
  1524. if((exit_status = get_minvalue_in_brktable(&this_shredno,CAS_SHREDNO,dz))<0)
  1525. return exit_status;
  1526. min_shredno = (int)round(this_shredno);
  1527. if(min_shredno < 2) {
  1528. sprintf(errstr,"Invalid shred number (%d) in shred-number file. (Minimum 2).\n",min_shredno);
  1529. return DATA_ERROR;
  1530. }
  1531. if((exit_status = get_maxvalue_in_brktable(&this_shredno,CAS_SHREDNO,dz))<0)
  1532. return exit_status;
  1533. *max_shredno = (int)round(this_shredno);
  1534. } else {
  1535. *max_shredno = dz->iparam[CAS_SHREDNO];
  1536. min_shredno = dz->iparam[CAS_SHREDNO];
  1537. }
  1538. if(((min_shredno == 0) && (min_shredcnt != 0)) || ((min_shredno != 0) && (min_shredcnt == 0))) {
  1539. sprintf(errstr,"SHRED NUMBER and SHRED COUNT must both be set, or must both be zero.\n");
  1540. return DATA_ERROR;
  1541. }
  1542. if((*clipmin/(double)*max_shredno)/3.0 <= dz->application->lo[CAS_CLIP]) { // Shreds into shredno pieces, which can be up to 1/3 as short
  1543. mincliplen = dz->application->lo[CAS_CLIP] * (double)*max_shredno * 3.0;
  1544. sprintf(errstr,"With shred number of (up to) %d, shortest segment must be > %.3lf secs.\n",*max_shredno,mincliplen);
  1545. return DATA_ERROR;
  1546. }
  1547. if(dz->vflag[CAS_SHREDSRC] && (min_shredno == 0 || min_shredcnt == 0)) {
  1548. sprintf(errstr,"To shred the source, both \"shred number\" or \"shred count\" must be given.\n");
  1549. return DATA_ERROR;
  1550. }
  1551. if (min_shredno > 0) {
  1552. *is_shred = 1;
  1553. if((dz->lparray[1] = (int *)malloc((*max_shredno+1) * sizeof(int)))==NULL) {
  1554. sprintf(errstr,"INSUFFICIENT MEMORY to create shred pointers array.\n");
  1555. return(MEMORY_ERROR);
  1556. }
  1557. if((dz->lparray[2] = (int *)malloc((*max_shredno) * sizeof(int)))==NULL) {
  1558. sprintf(errstr,"INSUFFICIENT MEMORY to create shred lengths array.\n");
  1559. return(MEMORY_ERROR);
  1560. }
  1561. arraysize = dz->itemcnt * (dz->echomax + 1 + dz->vflag[CAS_SHREDSRC]) * dz->max_shredcnt + 4; // +4 = SAFETY
  1562. if((dz->iparray = (int **)malloc(arraysize * sizeof(int *)))==NULL) {
  1563. sprintf(errstr,"INSUFFICIENT MEMORY to create shred permutation array. (1)\n");
  1564. return(MEMORY_ERROR);
  1565. }
  1566. for(n = 0; n < arraysize;n++) {
  1567. if((dz->iparray[n] = (int *)malloc((*max_shredno + 1) * sizeof(int)))==NULL) {
  1568. sprintf(errstr,"INSUFFICIENT MEMORY to create shred permutation array. (2)\n");
  1569. return(MEMORY_ERROR);
  1570. }
  1571. }
  1572. }
  1573. if((dz->brksize[CAS_MAXCLIP] || dz->param[CAS_MAXCLIP] > 0) || (dz->brksize[CAS_MAXECHO] || dz->param[CAS_MAXECHO] > 0)) {
  1574. if((dz->lparray[3] = (int *)malloc((dz->itemcnt+1) * 2 * sizeof(int)))==NULL) {
  1575. sprintf(errstr,"INSUFFICIENT MEMORY to create randomised echocnt && cliplen arrays.\n");
  1576. return(MEMORY_ERROR);
  1577. }
  1578. }
  1579. if(*is_shred) {
  1580. // clips echos // shreds-per-echo // shred elements
  1581. arraysize = dz->itemcnt * (dz->echomax + 1 + dz->vflag[CAS_SHREDSRC]) * dz->max_shredcnt * (*max_shredno) + 4;
  1582. if((dz->lparray[4] = (int *)malloc(arraysize * sizeof(int)))==NULL) {
  1583. sprintf(errstr,"INSUFFICIENT MEMORY to create array to store randomised shred values.\n");
  1584. return(MEMORY_ERROR);
  1585. }
  1586. }
  1587. switch(dz->mode) {
  1588. case(2):
  1589. case(7):
  1590. case(4):
  1591. case(9):
  1592. dz->alternating = 1; // stero : pan to right, to left, to right etc 8chan: rotate clock, anticlok, clok etc
  1593. break;
  1594. default:
  1595. dz->alternating = 0;
  1596. break;
  1597. }
  1598. switch(dz->mode) {
  1599. case(1):
  1600. case(6):
  1601. dz->spreading = 1;
  1602. break;
  1603. default:
  1604. dz->spreading = 0;
  1605. break;
  1606. }
  1607. return FINISHED;
  1608. }
  1609. /******************************** CREATE_CASCADE_SNDBUFS ********************************/
  1610. int create_cascade_sndbufs(int clipmax,dataptr dz)
  1611. {
  1612. int bigbufsize, secsize;
  1613. int framesize1 = F_SECSIZE * dz->infile->channels;
  1614. int framesize2 = F_SECSIZE * dz->outfile->channels;
  1615. if(dz->sbufptr == 0 || dz->sampbuf == 0) {
  1616. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  1617. return(PROGRAM_ERROR);
  1618. }
  1619. dz->buflen = clipmax * dz->infile->channels;
  1620. if(dz->buflen < 0) {
  1621. sprintf(errstr,"INSUFFICIENT MEMORY to create input sound buffers. (1)\n");
  1622. return(PROGRAM_ERROR);
  1623. }
  1624. secsize = dz->buflen/framesize1;
  1625. if(secsize * framesize1 != dz->buflen)
  1626. secsize++;
  1627. dz->buflen = secsize * framesize1;
  1628. if(dz->buflen < 0) {
  1629. sprintf(errstr,"INSUFFICIENT MEMORY to create input sound buffers. (2)\n");
  1630. return(PROGRAM_ERROR);
  1631. }
  1632. dz->buflen2 = clipmax * (dz->echomax+1) * dz->outfile->channels;
  1633. if(dz->buflen2 < 0) {
  1634. sprintf(errstr,"INSUFFICIENT MEMORY to create output sound buffers. (1)\n");
  1635. return(PROGRAM_ERROR);
  1636. }
  1637. secsize = dz->buflen2/framesize2;
  1638. if(secsize * framesize2 != dz->buflen2)
  1639. secsize++;
  1640. dz->buflen2 = secsize * framesize2;
  1641. if(dz->buflen2 < 0) {
  1642. sprintf(errstr,"INSUFFICIENT MEMORY to create output sound buffers. (2)\n");
  1643. return(PROGRAM_ERROR);
  1644. }
  1645. bigbufsize = ((3 * dz->buflen) + (3 * dz->buflen2)) * sizeof(float);
  1646. if((dz->bigbuf = (float *)malloc(bigbufsize)) == NULL) {
  1647. sprintf(errstr,"INSUFFICIENT MEMORY to create total sound buffers.\n");
  1648. return(PROGRAM_ERROR);
  1649. }
  1650. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf; // Inbuf
  1651. dz->sbufptr[1] = dz->sampbuf[1] = dz->sampbuf[0] + dz->buflen; // Shredbuf
  1652. dz->sbufptr[2] = dz->sampbuf[2] = dz->sampbuf[1] + dz->buflen; // Shredsplicebuf
  1653. dz->sbufptr[3] = dz->sampbuf[3] = dz->sampbuf[2] + dz->buflen; // Calculation buf for echos
  1654. dz->sbufptr[4] = dz->sampbuf[4] = dz->sampbuf[3] + dz->buflen2; // Outbuf
  1655. dz->sbufptr[5] = dz->sampbuf[5] = dz->sampbuf[4] + dz->buflen2; // Overflowbuf
  1656. dz->sampbuf[6] = dz->sampbuf[6] + dz->buflen2;
  1657. return(FINISHED);
  1658. }
  1659. /****************************** GET_MODE *********************************/
  1660. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1661. {
  1662. char temp[200], *p;
  1663. if(sscanf(str,"%s",temp)!=1) {
  1664. sprintf(errstr,"Cannot read mode of program.\n");
  1665. return(USAGE_ONLY);
  1666. }
  1667. p = temp + strlen(temp) - 1;
  1668. while(p >= temp) {
  1669. if(!isdigit(*p)) {
  1670. fprintf(stderr,"Invalid mode of program entered.\n");
  1671. return(USAGE_ONLY);
  1672. }
  1673. p--;
  1674. }
  1675. if(sscanf(str,"%d",&dz->mode)!=1) {
  1676. fprintf(stderr,"Cannot read mode of program.\n");
  1677. return(USAGE_ONLY);
  1678. }
  1679. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1680. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1681. return(USAGE_ONLY);
  1682. }
  1683. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1684. return(FINISHED);
  1685. }
  1686. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  1687. int handle_the_special_data(char *str,double *clipmin,dataptr dz)
  1688. {
  1689. int n, cnt, firsttime = 1;
  1690. int inlen = dz->insams[0]/dz->infile->channels; // Length of src file, in grouped samples
  1691. FILE *fp;
  1692. char temp[200], *p;
  1693. double dummy = 0, cutlen = 0.0, lasttime, endcut, srate = (double)dz->infile->srate;
  1694. double mincut = 2 * CASC_SPLICELEN * MS_TO_SECS; // Min length of segment to echo > 2 * splicelen
  1695. int mincutgpsamps = (int)ceil(mincut * (double)dz->infile->srate); // and in grouped_samples
  1696. int lastclipcut;
  1697. if((fp = fopen(str,"r"))==NULL) {
  1698. sprintf(errstr,"Cannot open file %s to read clip lengths.\n",str);
  1699. return(DATA_ERROR);
  1700. }
  1701. cnt = 0;
  1702. lasttime = 0;
  1703. firsttime = 1;
  1704. *clipmin = HUGE;
  1705. while(fgets(temp,200,fp)!=NULL) {
  1706. p = temp;
  1707. while(isspace(*p))
  1708. p++;
  1709. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1710. continue;
  1711. while(get_float_from_within_string(&p,&dummy)) {
  1712. cutlen = dummy - lasttime;
  1713. if(cutlen <= mincut) {
  1714. if(firsttime)
  1715. sprintf(errstr,"Invalid clip length between zero and first value (%lf) in file %s (must be greater than %lf seconds)\n",dummy,str,mincut);
  1716. else
  1717. sprintf(errstr,"Invalid clip length (%lf) between times (%lf & %lf) in file %s (must be greater than %lf seconds)\n",cutlen,lasttime,dummy,str,mincut);
  1718. return(DATA_ERROR);
  1719. }
  1720. if(dummy <= dz->duration) // Look for minimum cutsize WITHIN the file to be cut
  1721. *clipmin = min(*clipmin,cutlen);
  1722. lasttime = dummy;
  1723. firsttime = 0;
  1724. cnt++;
  1725. }
  1726. }
  1727. if(cnt < 2) {
  1728. sprintf(errstr,"Must be more than 1 clip time value in file %s.\n",str);
  1729. return(DATA_ERROR);
  1730. }
  1731. dz->itemcnt = cnt;
  1732. endcut = dz->duration - dummy; // If data stops before file end, find remaining file segment (endcut is +ve if last cut before file end)
  1733. if(endcut > mincut) // If endcut is negative, ignore. If <= mincut, gets joined into previous cut, making that larger than any previous minimum
  1734. *clipmin = min(*clipmin,endcut); // If > mincut, treated as a separate cut, which could be smaller than current minimum
  1735. if((dz->lparray[0] = (int *)malloc((dz->itemcnt + 1) * sizeof(int)))==NULL) {
  1736. sprintf(errstr,"INSUFFICIENT MEMORY to create clip lengths array (2).\n");
  1737. return(MEMORY_ERROR);
  1738. }
  1739. cnt = 0;
  1740. fseek(fp,0,0);
  1741. while(fgets(temp,200,fp)!=NULL) {
  1742. p = temp;
  1743. while(isspace(*p))
  1744. p++;
  1745. if(*p == ';' || *p == ENDOFSTR) // Allow comments in file
  1746. continue;
  1747. while(get_float_from_within_string(&p,&dummy))
  1748. dz->lparray[0][cnt++] = (int)round(dummy * srate);
  1749. }
  1750. for(n=0;n < dz->itemcnt;n++) { // Loose any data which is beyond end of infile
  1751. if(dz->lparray[0][n] > inlen) {
  1752. dz->itemcnt = n;
  1753. break;
  1754. }
  1755. }
  1756. if(dz->itemcnt <= 0) {
  1757. sprintf(errstr,"No valid clip times in file %s.\n",str);
  1758. return(MEMORY_ERROR);
  1759. }
  1760. dz->lparray[0][dz->itemcnt] = inlen; // Add end-of-file as last cutpoint
  1761. lastclipcut = dz->lparray[0][dz->itemcnt] - dz->lparray[0][dz->itemcnt - 1];
  1762. if(lastclipcut < mincutgpsamps) // If final clip is too small, eliminate it
  1763. dz->lparray[0][dz->itemcnt-1] = inlen;
  1764. else
  1765. dz->itemcnt++;
  1766. if(dz->itemcnt <= 1) {
  1767. sprintf(errstr,"Less than 2 valid clip times in file %s.\n",str);
  1768. return(MEMORY_ERROR);
  1769. }
  1770. return FINISHED;
  1771. }
  1772. /************************************ PANCALC *******************************/
  1773. void pancalc(double position,double *leftgain,double *rightgain)
  1774. {
  1775. int dirflag;
  1776. double temp;
  1777. double relpos;
  1778. double reldist, invsquare;
  1779. if(position < 0.0)
  1780. dirflag = -1; /* signal to left */
  1781. else
  1782. dirflag = 1; /* signal to right */
  1783. if(position < 0)
  1784. relpos = -position;
  1785. else
  1786. relpos = position;
  1787. if(relpos <= 1.0){ /* between the speakers */
  1788. temp = 1.0 + (relpos * relpos);
  1789. reldist = ROOT2 / sqrt(temp);
  1790. temp = (position + 1.0) / 2.0;
  1791. *rightgain = temp * reldist;
  1792. *leftgain = (1.0 - temp ) * reldist;
  1793. } else { /* outside the speakers */
  1794. temp = (relpos * relpos) + 1.0;
  1795. reldist = sqrt(temp) / ROOT2; /* relative distance to source */
  1796. invsquare = 1.0 / (reldist * reldist);
  1797. if(dirflag < 0) { /* SIGNAL_TO_LEFT */
  1798. *leftgain = invsquare;
  1799. *rightgain = 0.0;
  1800. } else { /* SIGNAL_TO_RIGHT */
  1801. *rightgain = invsquare;
  1802. *leftgain = 0;
  1803. }
  1804. }
  1805. }
  1806. /***************************** INITIALISE_CASCADE_RANDOM_SEQUENCE ***************************/
  1807. void initialise_cascade_random_sequence(int seed)
  1808. {
  1809. if(seed > 0)
  1810. srand((int)seed);
  1811. else
  1812. initrand48();
  1813. }
  1814. /************************** DO_SHREDDING *******************************/
  1815. void do_shredding(int *shredcnt,int *csscnt,int passno,int cliplen,int spliclen,int max_shredno,dataptr dz)
  1816. {
  1817. double this_scatter, val, newval;
  1818. int n, m, i, k, j, inchans = dz->infile->channels;
  1819. int chunkscat;
  1820. int *chunkptr = dz->lparray[1], *chunklen = dz->lparray[2], *chunkscatstore = dz->lparray[4], shbufpos;
  1821. int total_len, chnk_len;
  1822. int rawlen = (int)round((double)cliplen/(double)dz->iparam[CAS_SHREDNO]);
  1823. float *ibuf = dz->sampbuf[0], *shredbuf = dz->sampbuf[1], *shredsplicebuf = dz->sampbuf[2], *old_addr;
  1824. int *permm = dz->iparray[0];
  1825. for(i = 0; i < dz->iparam[CAS_SHREDCNT]; i++) { // For the number of shreds required
  1826. total_len = 0;
  1827. chunkptr[0] = 0;
  1828. for(n=1;n<dz->iparam[CAS_SHREDNO];n++) {
  1829. if(passno == 0) {
  1830. this_scatter = 1.0 + (((drand48() * 2.0) - 1.0)/3.0); // Range 2/3 to 4/3
  1831. chunkscat = (int)(this_scatter * (double)rawlen);
  1832. chunkscatstore[(*csscnt)++] = chunkscat;
  1833. } else
  1834. chunkscat = chunkscatstore[(*csscnt)++];
  1835. chunkptr[n] = total_len + chunkscat; // Randomised position of each chunk-boundary
  1836. total_len += rawlen; // Unrandomised position of each chunk-boundary
  1837. }
  1838. chunkptr[n] = cliplen;
  1839. for(n=0;n<dz->iparam[CAS_SHREDNO];n++)
  1840. chunklen[n] = chunkptr[n+1] - chunkptr[n]; // Find lengths of all chunks
  1841. (*shredcnt)++;
  1842. if(passno == 0) {
  1843. permute_chunks(dz); // Permute order of chunks
  1844. for(n=0;n < max_shredno;n++)
  1845. dz->iparray[*shredcnt][n] = permm[n];
  1846. } else {
  1847. for(n=0;n < max_shredno;n++)
  1848. permm[n] = dz->iparray[*shredcnt][n];
  1849. }
  1850. memset((char *)shredbuf,0,dz->buflen * sizeof(float));
  1851. memset((char *)shredsplicebuf,0,dz->buflen * sizeof(float));
  1852. shbufpos = 0;
  1853. for(j=0;j<dz->iparam[CAS_SHREDNO];j++) { // For each permuted shred-element
  1854. old_addr = &(ibuf[chunkptr[permm[j]] * inchans]); // Address of (permuted) chunk
  1855. chnk_len = chunklen[permm[j]]; // Length of (permuted) chunk (in grouped-samples)
  1856. // Copy into splicebuf
  1857. memcpy((char *)shredsplicebuf,(char *)old_addr,(chnk_len * inchans) * sizeof(float));
  1858. for(n=0, m = chnk_len - 1;n < spliclen;n++,m--) { // Splice both ends
  1859. val = (double)n/(double)spliclen;
  1860. for(k=0;k < inchans;k++) {
  1861. newval = shredsplicebuf[(n * inchans) + k];
  1862. newval *= val;
  1863. shredsplicebuf[(n * inchans) + k] = (float)newval;
  1864. newval = shredsplicebuf[(m * inchans) + k];
  1865. newval *= val;
  1866. shredsplicebuf[(m * inchans) + k] = (float)newval;
  1867. }
  1868. }
  1869. for(n=0;n < chnk_len * inchans;n++) // Copy each chunk into shredbuf
  1870. shredbuf[shbufpos++] = shredsplicebuf[n];
  1871. memset((char *)shredsplicebuf,0,dz->buflen * sizeof(float));
  1872. } // Once all chunks assembled
  1873. memset((char *)ibuf,0,dz->buflen * sizeof(float)); // Copy shredded source into source buf
  1874. memcpy((char *)ibuf,(char *)shredbuf,(cliplen * inchans) * sizeof(float));
  1875. }
  1876. }
  1877. /*************************** PERMUTE_CHUNKS ***************************/
  1878. void permute_chunks(dataptr dz)
  1879. {
  1880. int n, t;
  1881. for(n=0;n<dz->iparam[CAS_SHREDNO];n++) {
  1882. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  1883. if(t==n)
  1884. prefix(n,dz);
  1885. else
  1886. insert(n,t,dz);
  1887. }
  1888. }
  1889. /****************************** INSERT ****************************/
  1890. void insert(int n,int t,dataptr dz)
  1891. {
  1892. shuflup(t+1,dz);
  1893. dz->iparray[0][t+1] = n;
  1894. }
  1895. /****************************** PREFIX ****************************/
  1896. void prefix(int n,dataptr dz)
  1897. {
  1898. shuflup(0,dz);
  1899. dz->iparray[0][0] = n;
  1900. }
  1901. /****************************** SHUFLUP ****************************/
  1902. void shuflup(int k,dataptr dz)
  1903. {
  1904. int n;
  1905. for(n = dz->iparam[CAS_SHREDNO] - 1; n > k; n--)
  1906. dz->iparray[0][n] = dz->iparray[0][n-1];
  1907. }