mchshred.c 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955
  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. /* MCHSHRED --
  22. *
  23. * Do a shred, scattering the fragments at random over multichan space
  24. *
  25. * (mode 1) mono --> outchans
  26. * (mode 2) inchans to equal-outchans
  27. * in mode 2 MSHR_OUTCHANS is internal, and equals dz->infile->channels
  28. MODE 1
  29. if((exit_status = set_param_data(ap,0 ,4,4,"iidd"))<0)
  30. return(FAILED);
  31. MODE 2
  32. if((exit_status = set_param_data(ap,0 ,4,3,"0idd"))<0)
  33. return(FAILED);
  34. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  35. return(FAILED);
  36. MODE 1
  37. exit_status = set_internalparam_data("iiiiiiiiiiiii",ap); break;
  38. MODE 2
  39. exit_status = set_internalparam_data("iiiiiiiiiiiiii",ap); break;
  40. */
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <structures.h>
  44. #include <tkglobals.h>
  45. #include <pnames.h>
  46. #include <filetype.h>
  47. #include <processno.h>
  48. #include <modeno.h>
  49. #include <logic.h>
  50. #include <globcon.h>
  51. #include <cdpmain.h>
  52. #include <math.h>
  53. #include <mixxcon.h>
  54. #include <osbind.h>
  55. #include <standalone.h>
  56. #include <ctype.h>
  57. #include <sfsys.h>
  58. #include <string.h>
  59. #include <srates.h>
  60. //#include <memory.h>
  61. //#include <string.h>
  62. //#ifdef unix
  63. #define round(x) lround((x))
  64. //#endif
  65. #ifndef HUGE
  66. #define HUGE 3.40282347e+38F
  67. #endif
  68. char errstr[2400];
  69. int anal_infiles = 1;
  70. int sloom = 0;
  71. int sloombatch = 0;
  72. /* RWD 1-23: temp fix for param alloc errors */
  73. const char* cdp_version = "7.1.1";
  74. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  75. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  76. static int setup_mchshred_application(dataptr dz);
  77. static int setup_mchshred_param_ranges_and_defaults(dataptr dz);
  78. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  79. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  80. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  81. static int open_the_outfile(dataptr dz);
  82. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  83. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  84. static int establish_application(dataptr dz);
  85. static int initialise_vflags(dataptr dz);
  86. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  87. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  88. static int mark_parameter_types(dataptr dz,aplptr ap);
  89. static int assign_file_data_storage(int infilecnt,dataptr dz);
  90. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  91. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  92. static void do_endsplice(float *i,int chans,dataptr dz);
  93. static void do_bufend_splices(int current_buf,dataptr dz);
  94. static void ptr_sort(int end,dataptr dz);
  95. static void do_startsplice(float *i,int chans,dataptr dz);
  96. static void permute_chunks(dataptr dz);
  97. static void insert(int n,int t,dataptr dz);
  98. static void prefix(int n,dataptr dz);
  99. static void shuflup(int k,dataptr dz);
  100. static void heavy_scat(dataptr dz);
  101. static void normal_scat(dataptr dz);
  102. static int get_basis_lengths(int *work_len,dataptr dz);
  103. static int shred(int shredno,int current_buf,int work_len,dataptr dz);
  104. static int mchshred_process(dataptr dz);
  105. static int create_mchshred_buffers(dataptr dz);
  106. static int mchshred_pconsistency(dataptr dz);
  107. static void permute_chans(int outchans,dataptr dz);
  108. static void insertch(int n,int t,int outchans,dataptr dz);
  109. static void prefixch(int n,int outchans,dataptr dz);
  110. static void shuflupch(int k,int outchans,dataptr dz);
  111. static void rotate(float *splicbuf,int len,int *permch,float *rot,int outchans);
  112. /**************************************** MAIN *********************************************/
  113. int main(int argc,char *argv[])
  114. {
  115. int exit_status;
  116. dataptr dz = NULL;
  117. char **cmdline;
  118. int cmdlinecnt;
  119. int n;
  120. // aplptr ap;
  121. int is_launched = FALSE;
  122. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  123. fprintf(stdout,"%s\n",cdp_version);
  124. fflush(stdout);
  125. return 0;
  126. }
  127. /* CHECK FOR SOUNDLOOM */
  128. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  129. sloom = 0;
  130. sloombatch = 1;
  131. }
  132. if(sflinit("cdp")){
  133. sfperror("cdp: initialisation\n");
  134. return(FAILED);
  135. }
  136. /* SET UP THE PRINCIPAL DATASTRUCTURE */
  137. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  138. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  139. return(FAILED);
  140. }
  141. if(!sloom) {
  142. if(argc == 1) {
  143. usage1();
  144. return(FAILED);
  145. } else if(argc == 2) {
  146. usage2(argv[1]);
  147. return(FAILED);
  148. }
  149. }
  150. if(!sloom) {
  151. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  152. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  153. return(FAILED);
  154. }
  155. cmdline = argv;
  156. cmdlinecnt = argc;
  157. if((get_the_process_no(argv[0],dz))<0)
  158. return(FAILED);
  159. cmdline++;
  160. cmdlinecnt--;
  161. dz->maxmode = 2;
  162. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  163. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  164. return(exit_status);
  165. }
  166. cmdline++;
  167. cmdlinecnt--;
  168. // setup_particular_application =
  169. if((exit_status = setup_mchshred_application(dz))<0) {
  170. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  171. return(FAILED);
  172. }
  173. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  174. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  175. return(FAILED);
  176. }
  177. } else {
  178. //parse_TK_data() =
  179. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  180. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  181. return(exit_status);
  182. }
  183. }
  184. // ap = dz->application;
  185. // parse_infile_and_hone_type() =
  186. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  187. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  188. return(FAILED);
  189. }
  190. // setup_param_ranges_and_defaults() =
  191. if((exit_status = setup_mchshred_param_ranges_and_defaults(dz))<0) {
  192. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  193. return(FAILED);
  194. }
  195. // open_first_infile CDP LIB
  196. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  197. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  198. return(FAILED);
  199. }
  200. cmdlinecnt--;
  201. cmdline++;
  202. // handle_extra_infiles() : redundant
  203. // handle_outfile() =
  204. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  205. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  206. return(FAILED);
  207. }
  208. // handle_formants() redundant
  209. // handle_formant_quiksearch() redundant
  210. // handle_special_data() redundant
  211. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  212. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  213. return(FAILED);
  214. }
  215. // check_param_validity_and_consistency....
  216. if((exit_status = mchshred_pconsistency(dz))<0) {
  217. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  218. return(FAILED);
  219. }
  220. is_launched = TRUE;
  221. dz->bufcnt = 3;
  222. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  223. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  224. return(MEMORY_ERROR);
  225. }
  226. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  227. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  228. return(MEMORY_ERROR);
  229. }
  230. for(n = 0;n <dz->bufcnt; n++)
  231. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  232. dz->sampbuf[n] = (float *)0;
  233. // create_sndbufs()....
  234. if((exit_status = create_mchshred_buffers(dz))<0) {
  235. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  236. return(FAILED);
  237. }
  238. if((exit_status = open_the_outfile(dz))<0) {
  239. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  240. return(FAILED);
  241. }
  242. //param_preprocess() redundant
  243. //spec_process_file =
  244. if((exit_status = mchshred_process(dz))<0) {
  245. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  246. return(FAILED);
  247. }
  248. if((exit_status = complete_output(dz))<0) { // CDP LIB
  249. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  250. return(FAILED);
  251. }
  252. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  253. free(dz);
  254. return(SUCCEEDED);
  255. }
  256. /**********************************************
  257. REPLACED CDP LIB FUNCTIONS
  258. **********************************************/
  259. /****************************** SET_PARAM_DATA *********************************/
  260. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  261. {
  262. ap->special_data = (char)special_data;
  263. ap->param_cnt = (char)paramcnt;
  264. ap->max_param_cnt = (char)maxparamcnt;
  265. if(ap->max_param_cnt>0) {
  266. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  267. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  268. return(MEMORY_ERROR);
  269. }
  270. strcpy(ap->param_list,paramlist);
  271. }
  272. return(FINISHED);
  273. }
  274. /****************************** SET_VFLGS *********************************/
  275. int set_vflgs
  276. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  277. {
  278. ap->option_cnt = (char) optcnt; /*RWD added cast */
  279. if(optcnt) {
  280. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  281. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  282. return(MEMORY_ERROR);
  283. }
  284. strcpy(ap->option_list,optlist);
  285. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  286. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  287. return(MEMORY_ERROR);
  288. }
  289. strcpy(ap->option_flags,optflags);
  290. }
  291. ap->vflag_cnt = (char) vflagcnt;
  292. ap->variant_param_cnt = (char) vparamcnt;
  293. if(vflagcnt) {
  294. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  295. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  296. return(MEMORY_ERROR);
  297. }
  298. strcpy(ap->variant_list,varlist);
  299. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  300. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  301. return(MEMORY_ERROR);
  302. }
  303. strcpy(ap->variant_flags,varflags);
  304. }
  305. return(FINISHED);
  306. }
  307. /***************************** APPLICATION_INIT **************************/
  308. int application_init(dataptr dz)
  309. {
  310. int exit_status;
  311. int storage_cnt;
  312. int tipc, brkcnt;
  313. aplptr ap = dz->application;
  314. if(ap->vflag_cnt>0)
  315. initialise_vflags(dz);
  316. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  317. ap->total_input_param_cnt = (char)tipc;
  318. if(tipc>0) {
  319. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  320. return(exit_status);
  321. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  322. return(exit_status);
  323. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  324. return(exit_status);
  325. }
  326. brkcnt = tipc;
  327. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  328. if(brkcnt>0) {
  329. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  330. return(exit_status);
  331. }
  332. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  333. /* RWD 2023: debugging: TODO: why is storage_cnt wrong? */
  334. storage_cnt *= 8;
  335. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  336. return(exit_status);
  337. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  338. return(exit_status);
  339. }
  340. if((exit_status = mark_parameter_types(dz,ap))<0)
  341. return(exit_status);
  342. // establish_infile_constants() replaced by
  343. dz->infilecnt = 1;
  344. //establish_bufptrs_and_extra_buffers():
  345. if((exit_status = setup_internal_arrays_and_array_pointers(dz))<0)
  346. return(exit_status);
  347. return(FINISHED);
  348. }
  349. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  350. /* RWD malloc changed to calloc; helps debug version run as release! */
  351. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  352. {
  353. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  354. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  355. return(MEMORY_ERROR);
  356. }
  357. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  358. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  359. return(MEMORY_ERROR);
  360. }
  361. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  362. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  363. return(MEMORY_ERROR);
  364. }
  365. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  366. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  367. return(MEMORY_ERROR);
  368. }
  369. return(FINISHED);
  370. }
  371. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  372. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  373. {
  374. int n;
  375. for(n=0;n<storage_cnt;n++) {
  376. dz->is_int[n] = (char)0;
  377. dz->no_brk[n] = (char)0;
  378. }
  379. return(FINISHED);
  380. }
  381. /***************************** MARK_PARAMETER_TYPES **************************/
  382. int mark_parameter_types(dataptr dz,aplptr ap)
  383. {
  384. int n, m; /* PARAMS */
  385. for(n=0;n<ap->max_param_cnt;n++) {
  386. switch(ap->param_list[n]) {
  387. case('0'): break; /* dz->is_active[n] = 0 is default */
  388. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  389. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  390. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  391. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  392. default:
  393. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  394. return(PROGRAM_ERROR);
  395. }
  396. } /* OPTIONS */
  397. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  398. switch(ap->option_list[n]) {
  399. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  400. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  401. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  402. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  403. default:
  404. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  405. return(PROGRAM_ERROR);
  406. }
  407. } /* VARIANTS */
  408. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  409. switch(ap->variant_list[n]) {
  410. case('0'): break;
  411. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  412. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  413. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  414. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  415. default:
  416. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  417. return(PROGRAM_ERROR);
  418. }
  419. } /* INTERNAL */
  420. for(n=0,
  421. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  422. switch(ap->internal_param_list[n]) {
  423. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  424. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  425. case('d'): dz->no_brk[m] = (char)1; break;
  426. default:
  427. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  428. return(PROGRAM_ERROR);
  429. }
  430. }
  431. return(FINISHED);
  432. }
  433. /************************ HANDLE_THE_OUTFILE *********************/
  434. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  435. {
  436. char *filename = (*cmdline)[0];
  437. if(filename[0]=='-' && filename[1]=='f') {
  438. dz->floatsam_output = 1;
  439. dz->true_outfile_stype = SAMP_FLOAT;
  440. filename+= 2;
  441. }
  442. if(!sloom) {
  443. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  444. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  445. return(DATA_ERROR);
  446. }
  447. }
  448. strcpy(dz->outfilename,filename);
  449. (*cmdline)++;
  450. (*cmdlinecnt)--;
  451. return(FINISHED);
  452. }
  453. /************************ OPEN_THE_OUTFILE *********************/
  454. int open_the_outfile(dataptr dz)
  455. {
  456. int exit_status;
  457. if(dz->mode == 0) {
  458. dz->infile->channels = dz->iparam[MSHR_OUTCHANS];
  459. dz->outfile->channels = dz->iparam[MSHR_OUTCHANS];
  460. }
  461. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  462. return(exit_status);
  463. if(dz->mode == 0)
  464. dz->infile->channels = 1;
  465. return(FINISHED);
  466. }
  467. /***************************** ESTABLISH_APPLICATION **************************/
  468. int establish_application(dataptr dz)
  469. {
  470. aplptr ap;
  471. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  472. sprintf(errstr,"establish_application()\n");
  473. return(MEMORY_ERROR);
  474. }
  475. ap = dz->application;
  476. memset((char *)ap,0,sizeof(struct applic));
  477. return(FINISHED);
  478. }
  479. /************************* INITIALISE_VFLAGS *************************/
  480. int initialise_vflags(dataptr dz)
  481. {
  482. int n;
  483. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  484. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  485. return(MEMORY_ERROR);
  486. }
  487. for(n=0;n<dz->application->vflag_cnt;n++)
  488. dz->vflag[n] = FALSE;
  489. return FINISHED;
  490. }
  491. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  492. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  493. {
  494. int n;
  495. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  496. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  497. return(MEMORY_ERROR);
  498. }
  499. for(n=0;n<tipc;n++)
  500. ap->default_val[n] = 0.0;
  501. return(FINISHED);
  502. }
  503. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  504. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  505. {
  506. int n;
  507. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  508. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  509. return(MEMORY_ERROR);
  510. }
  511. for(n=0;n<tipc;n++)
  512. dz->is_active[n] = (char)0;
  513. return(FINISHED);
  514. }
  515. /************************* SETUP_MCHSHRED_APPLICATION *******************/
  516. int setup_mchshred_application(dataptr dz)
  517. {
  518. int exit_status;
  519. aplptr ap;
  520. if((exit_status = establish_application(dz))<0) // GLOBAL
  521. return(FAILED);
  522. ap = dz->application;
  523. // SEE parstruct FOR EXPLANATION of next 2 functions
  524. switch(dz->mode) {
  525. case(0):
  526. exit_status = set_param_data(ap,0 ,4,4,"iddi");
  527. break;
  528. case(1):
  529. exit_status = set_param_data(ap,0 ,4,3,"idd0");
  530. break;
  531. }
  532. if(exit_status <0)
  533. return(FAILED);
  534. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  535. return(FAILED);
  536. // set_legal_infile_structure -->
  537. dz->has_otherfile = FALSE;
  538. // assign_process_logic -->
  539. dz->input_data_type = SNDFILES_ONLY;
  540. dz->process_type = UNEQUAL_SNDFILE;
  541. dz->outfiletype = SNDFILE_OUT;
  542. return application_init(dz); //GLOBAL
  543. }
  544. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  545. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  546. {
  547. int exit_status;
  548. infileptr infile_info;
  549. if(!sloom) {
  550. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  551. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  552. return(MEMORY_ERROR);
  553. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  554. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  555. return(PROGRAM_ERROR);
  556. } else if(infile_info->filetype != SNDFILE) {
  557. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  558. return(DATA_ERROR);
  559. } else if((infile_info->channels == 1 && dz->mode != 0) || (infile_info->channels != 1 && dz->mode != 1)) {
  560. sprintf(errstr,"File %s does not have correct number of channels for this mode\n",cmdline[0]);
  561. return(DATA_ERROR);
  562. } else 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_MCHSHRED_PARAM_RANGES_AND_DEFAULTS *******************/
  571. int setup_mchshred_param_ranges_and_defaults(dataptr dz)
  572. {
  573. int exit_status;
  574. aplptr ap = dz->application;
  575. // set_param_ranges()
  576. double duration = (double)(dz->insams[0]/dz->infile->channels)/(double)(dz->infile->srate);
  577. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  578. // NB total_input_param_cnt is > 0 !!!
  579. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  580. return(FAILED);
  581. // get_param_ranges()
  582. ap->lo[0] = 1.0;
  583. ap->hi[0] = (double)MSHR_MAX;
  584. ap->default_val[0] = 1;
  585. ap->lo[1] = (double)((MSHR_SPLICELEN * 3)/(double)dz->infile->srate);
  586. ap->hi[1] = (duration/2.0)-FLTERR;
  587. ap->default_val[1] = max((duration/8.0),((double)(MSHR_SPLICELEN * 3)/(double)dz->infile->srate));
  588. ap->lo[2] = 0.0;
  589. ap->hi[2] = (double)MSHR_MAX_SCATTER;
  590. ap->default_val[2] = 1.0;
  591. ap->lo[3] = 2;
  592. ap->hi[3] = 16;
  593. ap->default_val[3] = 8;
  594. if(!sloom)
  595. put_default_vals_in_all_params(dz);
  596. return(FINISHED);
  597. }
  598. /********************************* PARSE_SLOOM_DATA *********************************/
  599. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  600. {
  601. int exit_status;
  602. int cnt = 1, infilecnt;
  603. int filesize, insams, inbrksize;
  604. double dummy;
  605. int true_cnt = 0;
  606. // aplptr ap;
  607. while(cnt<=PRE_CMDLINE_DATACNT) {
  608. if(cnt > argc) {
  609. sprintf(errstr,"Insufficient data sent from TK\n");
  610. return(DATA_ERROR);
  611. }
  612. switch(cnt) {
  613. case(1):
  614. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  615. sprintf(errstr,"Cannot read process no. sent from TK\n");
  616. return(DATA_ERROR);
  617. }
  618. break;
  619. case(2):
  620. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  621. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  622. return(DATA_ERROR);
  623. }
  624. if(dz->mode > 0)
  625. dz->mode--;
  626. //setup_particular_application()=
  627. if((exit_status = setup_mchshred_application(dz))<0)
  628. return(exit_status);
  629. // ap = dz->application;
  630. break;
  631. case(3):
  632. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  633. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  634. return(DATA_ERROR);
  635. }
  636. if(infilecnt < 1) {
  637. true_cnt = cnt + 1;
  638. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  639. }
  640. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  641. return(exit_status);
  642. break;
  643. case(INPUT_FILETYPE+4):
  644. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  645. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  646. return(DATA_ERROR);
  647. }
  648. break;
  649. case(INPUT_FILESIZE+4):
  650. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  651. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  652. return(DATA_ERROR);
  653. }
  654. dz->insams[0] = filesize;
  655. break;
  656. case(INPUT_INSAMS+4):
  657. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  658. sprintf(errstr,"Cannot read insams sent from TK\n");
  659. return(DATA_ERROR);
  660. }
  661. dz->insams[0] = insams;
  662. break;
  663. case(INPUT_SRATE+4):
  664. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  665. sprintf(errstr,"Cannot read srate sent from TK\n");
  666. return(DATA_ERROR);
  667. }
  668. break;
  669. case(INPUT_CHANNELS+4):
  670. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  671. sprintf(errstr,"Cannot read channels sent from TK\n");
  672. return(DATA_ERROR);
  673. }
  674. break;
  675. case(INPUT_STYPE+4):
  676. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  677. sprintf(errstr,"Cannot read stype sent from TK\n");
  678. return(DATA_ERROR);
  679. }
  680. break;
  681. case(INPUT_ORIGSTYPE+4):
  682. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  683. sprintf(errstr,"Cannot read origstype sent from TK\n");
  684. return(DATA_ERROR);
  685. }
  686. break;
  687. case(INPUT_ORIGRATE+4):
  688. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  689. sprintf(errstr,"Cannot read origrate sent from TK\n");
  690. return(DATA_ERROR);
  691. }
  692. break;
  693. case(INPUT_MLEN+4):
  694. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  695. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  696. return(DATA_ERROR);
  697. }
  698. break;
  699. case(INPUT_DFAC+4):
  700. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  701. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  702. return(DATA_ERROR);
  703. }
  704. break;
  705. case(INPUT_ORIGCHANS+4):
  706. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  707. sprintf(errstr,"Cannot read origchans sent from TK\n");
  708. return(DATA_ERROR);
  709. }
  710. break;
  711. case(INPUT_SPECENVCNT+4):
  712. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  713. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  714. return(DATA_ERROR);
  715. }
  716. dz->specenvcnt = dz->infile->specenvcnt;
  717. break;
  718. case(INPUT_WANTED+4):
  719. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  720. sprintf(errstr,"Cannot read wanted sent from TK\n");
  721. return(DATA_ERROR);
  722. }
  723. break;
  724. case(INPUT_WLENGTH+4):
  725. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  726. sprintf(errstr,"Cannot read wlength sent from TK\n");
  727. return(DATA_ERROR);
  728. }
  729. break;
  730. case(INPUT_OUT_CHANS+4):
  731. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  732. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  733. return(DATA_ERROR);
  734. }
  735. break;
  736. /* RWD these changes to samps - tk will have to deal with that! */
  737. case(INPUT_DESCRIPTOR_BYTES+4):
  738. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  739. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  740. return(DATA_ERROR);
  741. }
  742. break;
  743. case(INPUT_IS_TRANSPOS+4):
  744. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  745. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  746. return(DATA_ERROR);
  747. }
  748. break;
  749. case(INPUT_COULD_BE_TRANSPOS+4):
  750. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  751. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  752. return(DATA_ERROR);
  753. }
  754. break;
  755. case(INPUT_COULD_BE_PITCH+4):
  756. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  757. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  758. return(DATA_ERROR);
  759. }
  760. break;
  761. case(INPUT_DIFFERENT_SRATES+4):
  762. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  763. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  764. return(DATA_ERROR);
  765. }
  766. break;
  767. case(INPUT_DUPLICATE_SNDS+4):
  768. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  769. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  770. return(DATA_ERROR);
  771. }
  772. break;
  773. case(INPUT_BRKSIZE+4):
  774. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  775. sprintf(errstr,"Cannot read brksize sent from TK\n");
  776. return(DATA_ERROR);
  777. }
  778. if(inbrksize > 0) {
  779. switch(dz->input_data_type) {
  780. case(WORDLIST_ONLY):
  781. break;
  782. case(PITCH_AND_PITCH):
  783. case(PITCH_AND_TRANSPOS):
  784. case(TRANSPOS_AND_TRANSPOS):
  785. dz->tempsize = inbrksize;
  786. break;
  787. case(BRKFILES_ONLY):
  788. case(UNRANGED_BRKFILE_ONLY):
  789. case(DB_BRKFILES_ONLY):
  790. case(ALL_FILES):
  791. case(ANY_NUMBER_OF_ANY_FILES):
  792. if(dz->extrabrkno < 0) {
  793. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  794. return(DATA_ERROR);
  795. }
  796. if(dz->brksize == NULL) {
  797. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  798. return(PROGRAM_ERROR);
  799. }
  800. dz->brksize[dz->extrabrkno] = inbrksize;
  801. break;
  802. default:
  803. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  804. dz->input_data_type);
  805. return(PROGRAM_ERROR);
  806. }
  807. break;
  808. }
  809. break;
  810. case(INPUT_NUMSIZE+4):
  811. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  812. sprintf(errstr,"Cannot read numsize sent from TK\n");
  813. return(DATA_ERROR);
  814. }
  815. break;
  816. case(INPUT_LINECNT+4):
  817. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  818. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  819. return(DATA_ERROR);
  820. }
  821. break;
  822. case(INPUT_ALL_WORDS+4):
  823. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  824. sprintf(errstr,"Cannot read all_words sent from TK\n");
  825. return(DATA_ERROR);
  826. }
  827. break;
  828. case(INPUT_ARATE+4):
  829. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  830. sprintf(errstr,"Cannot read arate sent from TK\n");
  831. return(DATA_ERROR);
  832. }
  833. break;
  834. case(INPUT_FRAMETIME+4):
  835. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  836. sprintf(errstr,"Cannot read frametime sent from TK\n");
  837. return(DATA_ERROR);
  838. }
  839. dz->frametime = (float)dummy;
  840. break;
  841. case(INPUT_WINDOW_SIZE+4):
  842. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  843. sprintf(errstr,"Cannot read window_size sent from TK\n");
  844. return(DATA_ERROR);
  845. }
  846. break;
  847. case(INPUT_NYQUIST+4):
  848. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  849. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  850. return(DATA_ERROR);
  851. }
  852. break;
  853. case(INPUT_DURATION+4):
  854. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  855. sprintf(errstr,"Cannot read duration sent from TK\n");
  856. return(DATA_ERROR);
  857. }
  858. break;
  859. case(INPUT_MINBRK+4):
  860. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  861. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  862. return(DATA_ERROR);
  863. }
  864. break;
  865. case(INPUT_MAXBRK+4):
  866. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  867. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  868. return(DATA_ERROR);
  869. }
  870. break;
  871. case(INPUT_MINNUM+4):
  872. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  873. sprintf(errstr,"Cannot read minnum sent from TK\n");
  874. return(DATA_ERROR);
  875. }
  876. break;
  877. case(INPUT_MAXNUM+4):
  878. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  879. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  880. return(DATA_ERROR);
  881. }
  882. break;
  883. default:
  884. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  885. return(PROGRAM_ERROR);
  886. }
  887. cnt++;
  888. }
  889. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  890. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  891. return(DATA_ERROR);
  892. }
  893. if(true_cnt)
  894. cnt = true_cnt;
  895. *cmdlinecnt = 0;
  896. while(cnt < argc) {
  897. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  898. return(exit_status);
  899. cnt++;
  900. }
  901. return(FINISHED);
  902. }
  903. /********************************* GET_TK_CMDLINE_WORD *********************************/
  904. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  905. {
  906. if(*cmdlinecnt==0) {
  907. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  908. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  909. return(MEMORY_ERROR);
  910. }
  911. } else {
  912. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  913. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  914. return(MEMORY_ERROR);
  915. }
  916. }
  917. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  918. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  919. return(MEMORY_ERROR);
  920. }
  921. strcpy((*cmdline)[*cmdlinecnt],q);
  922. (*cmdlinecnt)++;
  923. return(FINISHED);
  924. }
  925. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  926. int assign_file_data_storage(int infilecnt,dataptr dz)
  927. {
  928. int exit_status;
  929. int no_sndfile_system_files = FALSE;
  930. dz->infilecnt = infilecnt;
  931. if((exit_status = allocate_filespace(dz))<0)
  932. return(exit_status);
  933. if(no_sndfile_system_files)
  934. dz->infilecnt = 0;
  935. return(FINISHED);
  936. }
  937. /************************* redundant functions: to ensure libs compile OK *******************/
  938. int assign_process_logic(dataptr dz)
  939. {
  940. return(FINISHED);
  941. }
  942. void set_legal_infile_structure(dataptr dz)
  943. {}
  944. int establish_bufptrs_and_extra_buffers(dataptr dz)
  945. {
  946. return(FINISHED);
  947. }
  948. int read_special_data(char *str,dataptr dz)
  949. {
  950. return(FINISHED);
  951. }
  952. int inner_loop
  953. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  954. {
  955. return(FINISHED);
  956. }
  957. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  958. {
  959. return(FINISHED);
  960. }
  961. /******************************** USAGE1 ********************************/
  962. int usage1(void)
  963. {
  964. usage2("shred");
  965. return(USAGE_ONLY);
  966. }
  967. /******************************** DBTOLEVEL ***********************/
  968. double dbtolevel(double val)
  969. {
  970. int isneg = 0;
  971. if(flteq(val,0.0))
  972. return(1.0);
  973. if(val < 0.0) {
  974. val = -val;
  975. isneg = 1;
  976. }
  977. val /= 20.0;
  978. val = pow(10.0,val);
  979. if(isneg)
  980. val = 1.0/val;
  981. return(val);
  982. }
  983. /********************************************************************************************/
  984. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  985. {
  986. if(!strcmp(prog_identifier_from_cmdline,"shred")) dz->process = MCHSHRED;
  987. else {
  988. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  989. return(USAGE_ONLY);
  990. }
  991. return(FINISHED);
  992. }
  993. /****************************** GET_MODE *********************************/
  994. int get_the_mode_from_cmdline(char *str,dataptr dz)
  995. {
  996. if(sscanf(str,"%d",&dz->mode)!=1) {
  997. sprintf(errstr,"Cannot read mode of program.\n");
  998. return(USAGE_ONLY);
  999. }
  1000. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1001. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1002. return(USAGE_ONLY);
  1003. }
  1004. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1005. return(FINISHED);
  1006. }
  1007. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1008. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1009. {
  1010. int n;
  1011. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1012. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1013. return(MEMORY_ERROR);
  1014. }
  1015. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1016. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1017. return(MEMORY_ERROR);
  1018. }
  1019. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1020. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1021. return(MEMORY_ERROR);
  1022. }
  1023. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1024. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1025. return(MEMORY_ERROR);
  1026. }
  1027. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1028. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1029. return(MEMORY_ERROR);
  1030. }
  1031. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1032. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1033. return(MEMORY_ERROR);
  1034. }
  1035. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1036. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1037. return(MEMORY_ERROR);
  1038. }
  1039. for(n=0;n<brkcnt;n++) {
  1040. dz->brk[n] = NULL;
  1041. dz->brkptr[n] = NULL;
  1042. dz->brkinit[n] = 0;
  1043. dz->brksize[n] = 0;
  1044. }
  1045. return(FINISHED);
  1046. }
  1047. /******************************** USAGE2 ********************************/
  1048. int usage2(char *str)
  1049. {
  1050. if(!strcmp(str,"shred")) {
  1051. fprintf(stderr,
  1052. "USAGE:\n"
  1053. "mchshred shred 1 infile outfile repeats chunklen scatter outchans \n"
  1054. "mchshred shred 2 infile outfile repeats chunklen scatter\n"
  1055. "\n"
  1056. "Sound is cut into random segments, which are then reassembled\n"
  1057. "in random order, within the original duration.\n"
  1058. "Further shreds, shred the previously shredded output.\n"
  1059. "\n"
  1060. "The shredding process distributes the output segments over\n"
  1061. " a randopm permutation of the output channels.\n"
  1062. "\n"
  1063. "REPEATS no. of repeats of shredding process.\n"
  1064. "CHUNKLEN average length of chunks to cut & permute.\n"
  1065. "SCATTER randomisation of cuts (0 to K): default 1.\n"
  1066. " where K = total no. of chunks (snd-duration/chunklen).\n"
  1067. " If scatter = 0, reorders without shredding.\n"
  1068. "OUTCHAN Mode 1 shreds a mono input to a multichannel output.\n"
  1069. " with 'outchan' channels.\n"
  1070. " Mode 2 shreds an already multichannel file.\n"
  1071. "\n");
  1072. } else
  1073. fprintf(stdout,"Unknown option '%s'\n",str);
  1074. return(USAGE_ONLY);
  1075. }
  1076. int usage3(char *str1,char *str2)
  1077. {
  1078. fprintf(stderr,"Insufficient parameters on command line.\n");
  1079. return(USAGE_ONLY);
  1080. }
  1081. /***************************** MCHSHRED_PCONSISTENCY *************************/
  1082. int mchshred_pconsistency(dataptr dz)
  1083. {
  1084. int chans = dz->infile->channels;
  1085. double duration = (double)(dz->insams[0]/chans)/(double)dz->infile->srate;
  1086. initrand48();
  1087. dz->iparam[MSHR_CHCNT] = round(duration/dz->param[MSHR_CHLEN]);
  1088. if(dz->param[MSHR_SCAT] > (double)dz->iparam[MSHR_CHCNT]) {
  1089. sprintf(errstr,"Scatter value cannot be greater than infileduration/chunklength.\n");
  1090. return(DATA_ERROR);
  1091. }
  1092. if(dz->param[MSHR_SCAT] > 1.0)
  1093. dz->iparam[MSHR_SCAT] = round(dz->param[MSHR_SCAT]);
  1094. else
  1095. dz->iparam[MSHR_SCAT] = 0;
  1096. /* setup splice params */
  1097. if(dz->mode == 0)
  1098. chans = dz->iparam[MSHR_OUTCHANS];
  1099. else
  1100. chans = dz->infile->channels;
  1101. dz->iparam[MSHR_SPLEN] = MSHR_SPLICELEN * chans;
  1102. if((dz->lparray[MSHR_CHUNKPTR] = (int *)malloc(dz->iparam[MSHR_CHCNT] * sizeof(int)))==NULL) {
  1103. sprintf(errstr,"INSUFFICIENT MEMORY for chunk cuts array.\n");
  1104. return(MEMORY_ERROR);
  1105. }
  1106. if((dz->lparray[MSHR_CHUNKLEN] = (int *)malloc(dz->iparam[MSHR_CHCNT] * sizeof(int)))==NULL) {
  1107. sprintf(errstr,"INSUFFICIENT MEMORY for chunk lens array.\n");
  1108. return(MEMORY_ERROR);
  1109. }
  1110. if((dz->iparray[MSHR_PERM] = (int *)malloc(dz->iparam[MSHR_CHCNT] * sizeof(int)))==NULL) {
  1111. sprintf(errstr,"INSUFFICIENT MEMORY for chunk permutation array.\n");
  1112. return(MEMORY_ERROR);
  1113. }
  1114. if((dz->iparray[MSHR_PERMCH] = (int *)malloc(chans * sizeof(int)))==NULL) {
  1115. sprintf(errstr,"INSUFFICIENT MEMORY for channel permutation array.\n");
  1116. return(MEMORY_ERROR);
  1117. }
  1118. if((dz->fptr[MSHR_ROTATE] = (float *)malloc(chans * sizeof(float)))==NULL) {
  1119. sprintf(errstr,"INSUFFICIENT MEMORY for channel permutation buffer.\n");
  1120. return(MEMORY_ERROR);
  1121. }
  1122. dz->lparray[MSHR_CHUNKPTR][0] = 0; /* first chunk is at start of buffer */
  1123. return(FINISHED);
  1124. }
  1125. /*************************** CREATE_MCHSHRED_BUFFERS **************************/
  1126. int create_mchshred_buffers(dataptr dz)
  1127. {
  1128. int bigfilesize;
  1129. if(dz->mode == 0)
  1130. bigfilesize = dz->insams[0] * dz->iparam[MSHR_OUTCHANS];
  1131. else
  1132. bigfilesize = dz->insams[0];
  1133. dz->bufcnt = 3;
  1134. if((dz->bigbuf = (float *)malloc((bigfilesize * dz->bufcnt) * sizeof(float)))==NULL) {
  1135. sprintf(errstr,"File too big for this process\n");
  1136. return(DATA_ERROR);
  1137. }
  1138. dz->buflen = bigfilesize;
  1139. dz->sampbuf[0] = dz->bigbuf;
  1140. dz->sampbuf[1] = dz->sampbuf[0] + dz->buflen;
  1141. dz->sampbuf[2] = dz->sampbuf[1] + dz->buflen;
  1142. dz->iparam[MSHR_LAST_BUFLEN] = bigfilesize; /* i.e. buflen = true outfile filelen */
  1143. dz->iparam[MSHR_LAST_CHCNT] = dz->iparam[MSHR_CHCNT];
  1144. dz->iparam[MSHR_LAST_SCAT] = dz->iparam[MSHR_SCAT];
  1145. if(dz->iparam[MSHR_LAST_CHCNT] < 2) {
  1146. fprintf(stdout, "WARNING: FINAL BUFFER WON'T BE SHREDDED (Too short for chunklen set).\n");
  1147. fprintf(stdout, "WARNING: It will shred if you\n");
  1148. fprintf(stdout, "WARNING: a) shorten infile by (>) chunklen, OR\n");
  1149. fprintf(stdout, "WARNING: b) alter chunklen until last buffer has >1 chunk in it.\n");
  1150. fflush(stdout);
  1151. }
  1152. memset((char *) (dz->sampbuf[0]),0,(dz->buflen * dz->bufcnt) * sizeof(float));
  1153. return(FINISHED);
  1154. }
  1155. /************************* MCHSHRED_PROCESS ***************************/
  1156. int mchshred_process(dataptr dz)
  1157. {
  1158. int exit_status;
  1159. int outchans;
  1160. int n, cnt = 0, /*checker = 0,*/ work_len, lfactor;
  1161. double factor = (double)dz->insams[0]/(double)dz->iparam[MSHR_CNT];
  1162. int current_buf;
  1163. if(dz->mode == 0)
  1164. outchans = dz->iparam[MSHR_OUTCHANS];
  1165. else
  1166. outchans = dz->infile->channels;
  1167. memset((char*)dz->sampbuf[2],0,dz->buflen * sizeof(float));
  1168. if(sloom && dz->iparam[MSHR_SCAT]) {
  1169. fprintf(stdout,"WARNING: There is a finite possibility program will not terminate.\n");
  1170. fprintf(stdout,"WARNING: If in doubt, press STOP\n");
  1171. fflush(stdout);
  1172. }
  1173. do {
  1174. if(cnt == 0 && dz->infile->channels == 1) {
  1175. dz->buflen /= outchans;
  1176. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1177. return(exit_status);
  1178. dz->buflen *= outchans;
  1179. } else {
  1180. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1181. return(exit_status);
  1182. }
  1183. current_buf = 0;
  1184. if(dz->samps_left <= 0 ) {
  1185. dz->buflen = dz->iparam[MSHR_LAST_BUFLEN];
  1186. dz->iparam[MSHR_SCAT] = dz->iparam[MSHR_LAST_SCAT];
  1187. dz->iparam[MSHR_CHCNT] = dz->iparam[MSHR_LAST_CHCNT];
  1188. }
  1189. if((dz->iparam[MSHR_CHCNT_LESS_ONE] = dz->iparam[MSHR_CHCNT] - 1)<=0) {
  1190. if(cnt==1) {
  1191. sprintf(errstr,"SOUNDFILE TOO SMALL to shred.\n");
  1192. return(DATA_ERROR);
  1193. } else {
  1194. n = dz->buflen;
  1195. dz->buflen = dz->ssampsread;
  1196. do_bufend_splices(current_buf,dz);
  1197. if((exit_status = write_exact_samps(dz->sampbuf[current_buf],dz->buflen,dz))<0)
  1198. return(exit_status);
  1199. dz->buflen = n;
  1200. }
  1201. } else {
  1202. if((exit_status = get_basis_lengths(&work_len,dz))<0)
  1203. return(exit_status);
  1204. // if(!sloom && !sloombatch)
  1205. // checker = 0;
  1206. else
  1207. display_virtual_time(0L,dz);
  1208. for(n=0;n<dz->iparam[MSHR_CNT];n++) {
  1209. if((exit_status = shred(n,current_buf,work_len,dz))<0)
  1210. return(exit_status);
  1211. current_buf = !current_buf;
  1212. if(!sloom && !sloombatch) {
  1213. fprintf(stdout,"INFO: %d of %d\n",n+1,dz->iparam[MSHR_CNT]);
  1214. fflush(stdout);
  1215. } else {
  1216. lfactor = (int)round((double)n * factor);
  1217. display_virtual_time(lfactor,dz);
  1218. }
  1219. }
  1220. do_bufend_splices(current_buf,dz);
  1221. if((exit_status = write_exact_samps(dz->sampbuf[current_buf],dz->buflen,dz))<0)
  1222. return(exit_status);
  1223. }
  1224. } while(dz->samps_left > 0);
  1225. return(FINISHED);
  1226. }
  1227. /******************************* SHRED **************************
  1228. *
  1229. * AUGUST 2010
  1230. *
  1231. * The logic below is false. The 1st item of the shred DOES
  1232. * need a startsplice because it is taken from some arbitrary place
  1233. * in the source, so will start abruptly. Similarly, the last segment
  1234. * DOES need an endsplice, for the samew reason. So THis has been
  1235. * corrected here .... however the original CDP shred program
  1236. * is INCORRECT ... but I have retained it as that is what
  1237. * one expects to hear!!
  1238. *
  1239. * (1) If the random-scattering of chunk boundaries is <= 1.0, scatter
  1240. * each chunk boundary separately (normal_scat).
  1241. * Else, scatter chunk boundaries over groups of chunklens (heavy_scat).
  1242. * (2) Calculate the lengths of the chunks, from difference of their positions.
  1243. * (2A) NB the length of the is the difference between its start and
  1244. * THE END OF THE work_len (NOT the ned of the buffer). Chunklens are
  1245. * measured from start of startsplice to START of endsplice (see
  1246. * diagram).
  1247. * (3) Generate a permutation (permm[]) of the chunk numbers.
  1248. *
  1249. * (4) The chunk that is to be FIRST in the permuted set does not need
  1250. * to be spliced at its beginning (as there's nothing prior to it,
  1251. * to splice into) but only at its end.
  1252. * (a) The address from which we copy is position in current buffer
  1253. * where chunk associated with 0 (chunk[permm[0]) is.
  1254. * (b) The address to copy TO is start of the OTHER buffer (buf[!this]).
  1255. * (c) The unit_len of the chunk we're copying is chunklen[permm[0]].
  1256. * (d) Copy all of this.
  1257. * (f) Copy SPLICELEN extra (full_len is SPLICELEN bigger that unit_len..
  1258. * .. see diagram), making an endsplice on it as we do.
  1259. *
  1260. * (5) For the rest of the chunks APART FROM THE LAST....
  1261. * (a) as 4(a): n associated with perm[n]..
  1262. * (b) advance in new buffer by chunklen of PREVIOUSLY written chunk..
  1263. * This 'length' is length to START of its endsplice, which is where
  1264. * new chunk is spliced in.
  1265. * (c) as 4(c)
  1266. * (d) Do a startsplice as we copy from old_address to new_address.
  1267. * (e) Copy from END of this startsplice, a segment of length chnklen
  1268. * (length of the total copied chunk) MINUS length of that startsplice
  1269. * (SPLICELEN).
  1270. * (f) as 4(f).
  1271. *
  1272. * (6) For the last chunk, we don't need an endsplice (nothing to splice to)
  1273. * (a-d)as 5(a-d).
  1274. * (e) Copy from end of STARTSPLICE to end of ENDSPLICE ... i.e.
  1275. * a whole chunklen, because full_len - SPLICELEN = chunklen.
  1276. *
  1277. * ___full_len___
  1278. * | |
  1279. * _chunklen__ |
  1280. * | S |
  1281. * | T |E
  1282. * | R ________|N
  1283. * | T/| \D
  1284. * | / | \
  1285. * |/ | \|
  1286. * | |
  1287. * |_chunklen_|
  1288. * |
  1289. * |___full_len___|
  1290. *
  1291. * (7) Set memory in old buffer to 0 (because we ADD into it, with splices).
  1292. */
  1293. int shred(int shredno,int current_buf,int work_len,dataptr dz)
  1294. {
  1295. int n;
  1296. int outchans, outchansratio, permno; // 2 buffers are used
  1297. float *old_addr, *new_addr; // current_buf (0 or 1) is read from
  1298. float *splicbuf = dz->sampbuf[2]; // !current_buf (1 or 0) is written to
  1299. double val;
  1300. int chnk_len, totlen, k;
  1301. char *destination;
  1302. int *chunkptr = dz->lparray[MSHR_CHUNKPTR];
  1303. int *chunklen = dz->lparray[MSHR_CHUNKLEN];
  1304. int *permm = dz->iparray[MSHR_PERM];
  1305. int *permch = dz->iparray[MSHR_PERMCH];
  1306. float *rot = dz->fptr[MSHR_ROTATE];
  1307. if(dz->mode == 0) // No of chans in output
  1308. outchans = dz->iparam[MSHR_OUTCHANS]; // depends on whether input is mono (mode 0)
  1309. else // or multichan (mode 1)
  1310. outchans = dz->infile->channels;
  1311. outchansratio = (int)(outchans/dz->infile->channels); // Ratio chans in out to chans in input
  1312. memset((char*)splicbuf,0,dz->buflen * sizeof(float)); // Preset splicebuffer to zero
  1313. if(!dz->iparam[MSHR_SCAT])
  1314. normal_scat(dz); // Generate the cut points
  1315. else
  1316. heavy_scat(dz);
  1317. for(n=0;n<dz->iparam[MSHR_CHCNT_LESS_ONE];n++) // Deduce the cunkjlens from the cut points
  1318. chunklen[n] = chunkptr[n+1] - chunkptr[n];
  1319. chunklen[n] = work_len - chunkptr[n]; // Get length of last chunk
  1320. permute_chunks(dz); // Permute chunk order
  1321. permute_chans(outchans,dz); // Generate a rand permutation of output chans
  1322. permno = 0; // Set output chan counter to zer0
  1323. if(dz->infile->channels == 1 && shredno == 0) { // First shred of mono file scatters src to N outchans
  1324. old_addr = dz->sampbuf[current_buf] + chunkptr[permm[0]]; // Go to get first (permd) chunlk of mono source
  1325. new_addr = dz->sampbuf[!current_buf]; // Set goal place as start of output buffer
  1326. chnk_len = chunklen[permm[0]]; // Get length of chunk to cut
  1327. totlen = (chnk_len + dz->iparam[MSHR_SPLEN]) * outchans; // Add length of final downsplice, and get actula length in OUTbuffer
  1328. destination = (char *)new_addr;
  1329. for(k = permch[permno]; k < totlen; k+=outchans) // For mono src, all first chunk goes to some rand chan
  1330. splicbuf[k] = *old_addr++; // while all other chans remain (preset) at zero
  1331. permno++; // Proceed to next permd channel, rady for next chunk
  1332. // NEW AUGUST 2010
  1333. do_startsplice(splicbuf,outchans,dz);
  1334. do_endsplice(splicbuf+totlen,outchans,dz); // splice end of segment in splicebuf
  1335. memcpy(destination,(char *)splicbuf,totlen*sizeof(float));
  1336. memset((char*)splicbuf,0,dz->buflen * sizeof(float)); // copy splicebuf to output, and zero splicebuf
  1337. /* MIDDLE-SEGMENTS IN BUFFER */
  1338. for(n=1;n<dz->iparam[MSHR_CHCNT_LESS_ONE];n++) { // For later segments, do the same, except
  1339. old_addr = dz->sampbuf[current_buf] + chunkptr[permm[n]];
  1340. new_addr += chnk_len * outchansratio; // Advance in outbuf by len of inchunk * no of outchans
  1341. chnk_len = chunklen[permm[n]];
  1342. totlen = (chnk_len + dz->iparam[MSHR_SPLEN]) * outchans;// chunk gets written to next random-permd channel
  1343. for(k = permch[permno]; k < totlen; k+=outchans)
  1344. splicbuf[k] = *old_addr++;
  1345. if(++permno >= outchans) { // Proceed to next channel permd channel
  1346. permute_chans(outchans,dz); // If all of perm used up, do a new perm
  1347. permno = 0; // and start at start of new perm
  1348. }
  1349. do_startsplice(splicbuf,outchans,dz); // This time, splice start of chunk as well as
  1350. do_endsplice(splicbuf+totlen,outchans,dz); // end of chunk
  1351. for(k = 0;k < totlen;k++) { // Must now ADD the chunk into the output
  1352. val = *(new_addr+k); // so that splices overlap
  1353. val += splicbuf[k];
  1354. *(new_addr+k) = (float)val;
  1355. }
  1356. memset((char*)splicbuf,0,dz->buflen * sizeof(float));
  1357. } /* f */
  1358. /* NEW END-SEGMENT IN BUFFER */ // For the final chunk, proceed as before
  1359. old_addr = dz->sampbuf[current_buf] + chunkptr[permm[n]];
  1360. new_addr += chnk_len;
  1361. chnk_len = chunklen[permm[n]];
  1362. totlen = (chnk_len + dz->iparam[MSHR_SPLEN]) * outchans;
  1363. for(k = permch[permno]; k < totlen; k+=outchans)
  1364. splicbuf[k] = *old_addr++;
  1365. do_startsplice(splicbuf,outchans,dz); // but this time, no end splice is needed
  1366. // NEW AUGUST 2010
  1367. do_endsplice(splicbuf+totlen,outchans,dz); // end of chunk
  1368. for(k = 0;k < totlen;k++) {
  1369. val = *(new_addr+k);
  1370. val += splicbuf[k];
  1371. *(new_addr+k) = (float)val;
  1372. }
  1373. memset((char*)splicbuf,0,dz->buflen * sizeof(float));
  1374. } else { // For mono input AFTER first pass, chunks are now in multichan buf.
  1375. /* NEW FIRST-SEGMENT IN BUFFER */ // So chunk Location and Len are multiplied by outchanratio (outch/inchan)
  1376. // For multichan input, outchanratio = 1, chunks are just standard size
  1377. old_addr = dz->sampbuf[current_buf] + (chunkptr[permm[0]] * outchansratio); // (Location)
  1378. new_addr = dz->sampbuf[!current_buf]; // For 1st chunk written, proceed as before, but ...
  1379. chnk_len = chunklen[permm[0]]; /* c */
  1380. totlen = (chnk_len + dz->iparam[MSHR_SPLEN]) * outchansratio; // (Len)
  1381. destination = (char *)new_addr;
  1382. memcpy((char *)splicbuf,(char *)old_addr,totlen*sizeof(float)); // Simply copy the required chunk into the splicebuffer
  1383. // NEW AUGUST 2010
  1384. do_startsplice(splicbuf,outchans,dz);
  1385. do_endsplice(splicbuf+totlen,outchans,dz); // and do end splice
  1386. rotate(splicbuf,totlen,permch,rot,outchans); // Permute order of channels in entire chunk
  1387. permute_chans(outchans,dz); // Get next channel-perm, ready for next chunk
  1388. memcpy(destination,(char *)splicbuf,totlen*sizeof(float));
  1389. memset((char*)splicbuf,0,dz->buflen * sizeof(float));
  1390. /* MIDDLE-SEGMENTS IN BUFFER */ // subsequent chunks treated similarly
  1391. for(n=1;n<dz->iparam[MSHR_CHCNT_LESS_ONE];n++) {
  1392. old_addr = dz->sampbuf[current_buf] + (chunkptr[permm[n]]*outchansratio);
  1393. new_addr += chnk_len * outchansratio;
  1394. chnk_len = chunklen[permm[n]];
  1395. totlen = (chnk_len + dz->iparam[MSHR_SPLEN]) * outchansratio;
  1396. memcpy((char *)splicbuf,(char *)old_addr,totlen*sizeof(float));
  1397. do_startsplice(splicbuf,outchans,dz); // except now we also need a startsplice
  1398. do_endsplice(splicbuf+totlen,outchans,dz);
  1399. rotate(splicbuf,totlen,permch,rot,outchans);
  1400. permute_chans(outchans,dz);
  1401. for(k = 0;k < totlen;k++) { // and output must be ADDED into outbuf, so splices overlap
  1402. val = *(new_addr+k);
  1403. val += splicbuf[k];
  1404. *(new_addr+k) = (float)val;
  1405. }
  1406. memset((char*)splicbuf,0,dz->buflen * sizeof(float));
  1407. } /* f */
  1408. /* NEW END-SEGMENT IN BUFFER */ // and final chunk treated siilarly
  1409. old_addr = dz->sampbuf[current_buf] + (chunkptr[permm[n]] * outchansratio);
  1410. new_addr += chnk_len * outchansratio;
  1411. chnk_len = chunklen[permm[n]];
  1412. totlen = (chnk_len + dz->iparam[MSHR_SPLEN]) * outchansratio;
  1413. memcpy((char *)splicbuf,(char *)old_addr,totlen*sizeof(float));
  1414. do_startsplice(splicbuf,outchans,dz); // except NO endsplice required
  1415. // NEW AUGUST 2010
  1416. do_endsplice(splicbuf+totlen,outchans,dz);
  1417. rotate(splicbuf,totlen,permch,rot,outchans); // Permute order of channels in entire chunk
  1418. for(k = 0;k < totlen;k++) {
  1419. val = *(new_addr+k);
  1420. val += splicbuf[k];
  1421. *(new_addr+k) = (float)val;
  1422. }
  1423. memset((char*)splicbuf,0,dz->buflen * sizeof(float));
  1424. }
  1425. /* RESET BUFFERS */ // Set to zero (what will become) output buffer, for next pass
  1426. memset((char *)dz->sampbuf[current_buf],0,dz->buflen * sizeof(float));
  1427. return(FINISHED);
  1428. }
  1429. /*********************** GET_BASIS_LENGTHS **********************
  1430. *
  1431. *
  1432. * ______________buflen_______________
  1433. * |............worklen............. | buflen - SPLICELEN = worklen.
  1434. * | unitlen unitlen | | unit_len * dz->iparam[MSHR_CHCNT] = worklen.
  1435. * | | | | |
  1436. * |_full_len_ | _full_len__| full_len = worklen + SPLICELEN.
  1437. * | | | | | | |
  1438. * | _____| |_____| ____| _____| |
  1439. * | /| \ / \ / \ / \ |
  1440. * | / | |X| X X \ |
  1441. * |/ | / \ / \ / \ \|
  1442. * | | |
  1443. * | | |
  1444. * rawlen
  1445. *
  1446. *
  1447. */
  1448. int get_basis_lengths(int *work_len,dataptr dz)
  1449. {
  1450. int inbuflen;
  1451. int excess, full_len, endunit_len, endfull_len, chans = dz->infile->channels;
  1452. if(dz->mode == 0)
  1453. inbuflen = dz->buflen/dz->iparam[MSHR_OUTCHANS];
  1454. else
  1455. inbuflen = dz->buflen;
  1456. *work_len = inbuflen - (dz->iparam[MSHR_SPLEN] * chans);
  1457. dz->iparam[MSHR_UNITLEN] = (int)round((*work_len)/dz->iparam[MSHR_CHCNT]);
  1458. excess = dz->iparam[MSHR_UNITLEN] % chans;
  1459. dz->iparam[MSHR_UNITLEN] -= excess;
  1460. excess = (*work_len) - (dz->iparam[MSHR_UNITLEN] * dz->iparam[MSHR_CHCNT]);
  1461. if(excess % chans) {
  1462. sprintf(errstr,"Problem in buffer accounting.\n");
  1463. return(PROGRAM_ERROR);
  1464. }
  1465. dz->iparam[MSHR_RAWLEN] = dz->iparam[MSHR_UNITLEN] - dz->iparam[MSHR_SPLEN];
  1466. full_len = dz->iparam[MSHR_UNITLEN] + dz->iparam[MSHR_SPLEN];
  1467. endunit_len = dz->iparam[MSHR_UNITLEN] + excess;
  1468. endfull_len = full_len + excess;
  1469. dz->iparam[MSHR_ENDRAWLEN] = dz->iparam[MSHR_RAWLEN] + excess;
  1470. if(full_len < (dz->iparam[MSHR_SPLEN] /* * 2 */) || endfull_len < (dz->iparam[MSHR_SPLEN]/* * 2 */)) {
  1471. sprintf(errstr,"Chunksizes %d and %d too small for splices. mshr_splen = %d\n",full_len,endfull_len,dz->iparam[MSHR_SPLEN]);
  1472. return(DATA_ERROR);
  1473. }
  1474. if(dz->iparam[MSHR_SCAT]) {
  1475. dz->iparam[MSHR_SCATGRPCNT] = (int)(dz->iparam[MSHR_CHCNT]/dz->iparam[MSHR_SCAT]);
  1476. dz->iparam[MSHR_ENDSCAT] = (int)(dz->iparam[MSHR_CHCNT] - (dz->iparam[MSHR_SCATGRPCNT] * dz->iparam[MSHR_SCAT]));
  1477. dz->iparam[MSHR_RANGE] = dz->iparam[MSHR_UNITLEN] * dz->iparam[MSHR_SCAT];
  1478. dz->iparam[MSHR_ENDRANGE] = ((dz->iparam[MSHR_ENDSCAT]-1) * dz->iparam[MSHR_UNITLEN]) + endunit_len;
  1479. }
  1480. return(FINISHED);
  1481. }
  1482. /************************** NORMAL_SCAT ******************************
  1483. *
  1484. * (1) TOTLA_LEN generates the unscattered positions of the chunks.
  1485. * Each is UNIT_LEN long, so they are equally spaced at UNIT_LEN
  1486. * intervals.
  1487. We can't scatter the FIRST chunk as it MUST start at ZERO!!
  1488. * (2) For all chunks except the first and last...
  1489. * (3) Scatter position of chunk over +- 1/2 of value of scatter,
  1490. * times the RAW-distance (not including splices) between chunks.
  1491. * (4) Add (could be negative) this scattering to orig position.
  1492. * (5) For the last chunk, do the same, scattering over RAW-len of previous
  1493. * chunk, if scatter -ve, and over endraw_len of final chunk, if +ve.
  1494. */
  1495. void normal_scat(dataptr dz)
  1496. {
  1497. double this_scatter;
  1498. int n, k;
  1499. int chunkscat, total_len = dz->iparam[MSHR_UNITLEN]; /* 1 */
  1500. int *chunkptr = dz->lparray[MSHR_CHUNKPTR];
  1501. for(n=1;n<dz->iparam[MSHR_CHCNT_LESS_ONE];n++) { /* 2 */
  1502. this_scatter = (drand48() - 0.5) * dz->param[MSHR_SCAT];
  1503. chunkscat = (int)(this_scatter * (double)dz->iparam[MSHR_RAWLEN]);
  1504. k = chunkscat % dz->infile->channels;
  1505. chunkscat -= k;
  1506. chunkptr[n] = total_len + chunkscat;
  1507. total_len += dz->iparam[MSHR_UNITLEN]; /* 4 */
  1508. }
  1509. this_scatter = (drand48() - 0.5) * dz->param[MSHR_SCAT];
  1510. if(this_scatter<0.0) { /* 5 */
  1511. chunkscat = (int)(this_scatter * (double)dz->iparam[MSHR_RAWLEN]);
  1512. k = chunkscat % dz->infile->channels;
  1513. chunkscat -= k;
  1514. chunkptr[n] = total_len - chunkscat;
  1515. } else {
  1516. chunkscat = (int)(this_scatter * (double)dz->iparam[MSHR_ENDRAWLEN]);
  1517. k = chunkscat % dz->infile->channels;
  1518. chunkscat -= k;
  1519. chunkptr[n] = total_len + chunkscat;
  1520. }
  1521. }
  1522. /*********************** HEAVY_SCAT ***************************
  1523. *
  1524. * (1) Start at the chunk (this=1) AFTER the first (which can't be moved).
  1525. * (2) STARTPTR marks the start of the chunk GROUP (and will be advanced
  1526. * by RANGE, which is length of chunk-group).
  1527. * (3) The loop will generate a set of positions for the chunks in
  1528. * a chunk-group. In the first chunkgroup the position of the
  1529. * first chunk (start of file) can't be moved, so loop starts at
  1530. * (first=) 1. Subsequemt loop passes start at 0.
  1531. * (4) For eveery chunk-group.
  1532. * (5) Set the index of the first chunk in this group (start) to the
  1533. * current index (this).
  1534. * (6) For every member of this chunk-group.
  1535. * (7) Generate a random-position within the chunk-grp's range
  1536. * and check it is not too close ( < SPLICELEN) to the others.
  1537. * Set a checking flag (OK).
  1538. * (8) Generate a position within the range, and after the startptr.
  1539. * (9) Compare it with all previously generated positions in this
  1540. * chunk-grp AND with last position of previous chunk-group!!
  1541. * If it's closer than SPLICELEN, set OK = 0, drop out of
  1542. checking loop and generate another position instead.
  1543. * (10) If the position is OK, drop out of position generating loop..
  1544. * (11) Advance to next chunk in this group.
  1545. * (12) Once all this group is done, advance the group startpoint by RANGE.
  1546. * (13) After FIRST grp, all positions can by varied, so set the initial
  1547. * loop counter to (first=)0.
  1548. * (14) If there are chunks left over (endscat!=0)..
  1549. * Follow the same procedure for chunks in end group, using the
  1550. * alternative variables, endscat and endrange.
  1551. */
  1552. void heavy_scat(dataptr dz)
  1553. {
  1554. int thiss = 1, that, start, n, m, OK; /* 1 */
  1555. int k;
  1556. int startptr = 0; /* 2 */
  1557. int endptr = 0;
  1558. int first = 1; /* 3 */
  1559. int *chunkptr = dz->lparray[MSHR_CHUNKPTR];
  1560. for(n=0;n<dz->iparam[MSHR_SCATGRPCNT];n++) { /* 4 */
  1561. start = thiss; /* 5 */
  1562. endptr += dz->iparam[MSHR_RANGE];
  1563. for(m=first;m<dz->iparam[MSHR_SCAT];m++) { /* 6 */
  1564. do { /* 7 */
  1565. OK = 1;
  1566. chunkptr[thiss] = (int)(drand48()*dz->iparam[MSHR_RANGE]); /* TRUNCATE (?)*/
  1567. chunkptr[thiss] += startptr; /* 8 */
  1568. k = chunkptr[thiss] % dz->infile->channels;
  1569. chunkptr[thiss] -= k;
  1570. for(that=start-1; that<thiss; that++) {
  1571. if(abs(chunkptr[thiss] - chunkptr[that])<dz->iparam[MSHR_SPLEN]) {
  1572. OK = 0; /* 9 */
  1573. break;
  1574. }
  1575. if(abs(endptr - chunkptr[thiss])<dz->iparam[MSHR_SPLEN]) {
  1576. OK = 0;
  1577. break;
  1578. }
  1579. }
  1580. } while(!OK); /* 10 */
  1581. thiss++; /* 11 */
  1582. }
  1583. startptr += dz->iparam[MSHR_RANGE]; /* 12 */
  1584. first = 0; /* 13 */
  1585. }
  1586. endptr += dz->iparam[MSHR_ENDRANGE];
  1587. if(dz->iparam[MSHR_ENDSCAT]) { /* 14 */
  1588. start = thiss;
  1589. for(m=0;m<dz->iparam[MSHR_ENDSCAT];m++) {
  1590. do {
  1591. OK = 1;
  1592. chunkptr[thiss] = (int)(drand48() * dz->iparam[MSHR_ENDRANGE]); /* TRUNCATE (?) */
  1593. chunkptr[thiss] += startptr;
  1594. k = chunkptr[thiss] % dz->infile->channels;
  1595. chunkptr[thiss] -= k;
  1596. for(that=start-1; that<thiss; that++) {
  1597. if(abs(chunkptr[thiss] - chunkptr[that])<dz->iparam[MSHR_SPLEN]) {
  1598. OK = 0;
  1599. break;
  1600. }
  1601. if(abs(endptr - chunkptr[thiss])<dz->iparam[MSHR_SPLEN]) {
  1602. OK = 0;
  1603. break;
  1604. }
  1605. }
  1606. } while(!OK);
  1607. thiss++;
  1608. }
  1609. }
  1610. ptr_sort(thiss,dz);
  1611. }
  1612. /*************************** PERMUTE_CHUNKS ***************************/
  1613. void permute_chunks(dataptr dz)
  1614. {
  1615. int n, t;
  1616. for(n=0;n<dz->iparam[MSHR_CHCNT];n++) {
  1617. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  1618. if(t==n)
  1619. prefix(n,dz);
  1620. else
  1621. insert(n,t,dz);
  1622. }
  1623. }
  1624. /****************************** INSERT ****************************/
  1625. void insert(int n,int t,dataptr dz)
  1626. {
  1627. shuflup(t+1,dz);
  1628. dz->iparray[MSHR_PERM][t+1] = n;
  1629. }
  1630. /****************************** PREFIX ****************************/
  1631. void prefix(int n,dataptr dz)
  1632. {
  1633. shuflup(0,dz);
  1634. dz->iparray[MSHR_PERM][0] = n;
  1635. }
  1636. /****************************** SHUFLUP ****************************/
  1637. void shuflup(int k,dataptr dz)
  1638. {
  1639. int n;
  1640. for(n = dz->iparam[MSHR_CHCNT_LESS_ONE]; n > k; n--)
  1641. dz->iparray[MSHR_PERM][n] = dz->iparray[MSHR_PERM][n-1];
  1642. }
  1643. /************************* DO_STARTSPLICE *************************
  1644. *
  1645. * (0) For each position in splice.
  1646. * (1) Get the value from the source file & multiply it by position in splice.
  1647. * We 'should' multiply it by position/SPLICELEN,
  1648. * so new value is SPLICELEN too large.
  1649. * (2) Add a rounding factor (if value were correct, this would be 1/2)
  1650. * But everything is SPLICELEN times too big, so add SHRED_HSPLICELEN.
  1651. * (3) Divide by SPLICELEN.
  1652. * (4) ADD this value to existing value (this is a splice TO another chunk!!).
  1653. */
  1654. void do_startsplice(float *i,int chans,dataptr dz)
  1655. {
  1656. double z;
  1657. int n, k;
  1658. for(n = 0; n <dz->iparam[MSHR_SPLEN]; n ++) { /* 0 */
  1659. for(k = 0;k < chans; k++) {
  1660. z = (*i) * (double)n/(double)dz->iparam[MSHR_SPLEN]; /* 1 */
  1661. *i = (float)z; /* 4 */
  1662. i++;
  1663. }
  1664. }
  1665. }
  1666. /************************* DO_ENDSPLICE *************************/
  1667. void do_endsplice(float *i,int chans,dataptr dz)
  1668. {
  1669. double z;
  1670. int n, k;
  1671. i--;
  1672. for(n = 0; n < dz->iparam[MSHR_SPLEN];n++) {
  1673. for(k = 0; k < chans; k++) {
  1674. z = *i * (double)n/(double)dz->iparam[MSHR_SPLEN];
  1675. *i = (float)z;
  1676. i--;
  1677. }
  1678. }
  1679. }
  1680. /********************* DO_BUFEND_SPLICES *************************/
  1681. void do_bufend_splices(int current_buf,dataptr dz)
  1682. {
  1683. double z;
  1684. int n, k, outchans;
  1685. float *b = dz->sampbuf[current_buf];
  1686. if(dz->mode == 0)
  1687. outchans = dz->iparam[MSHR_OUTCHANS];
  1688. else
  1689. outchans = dz->infile->channels;
  1690. for(n = 0; n <dz->iparam[MSHR_SPLEN]; n ++) {
  1691. for(k = 0;k<outchans;k++) {
  1692. z = (*b) * (double)n/(double)dz->iparam[MSHR_SPLEN];
  1693. *b++ = (float)z;
  1694. }
  1695. }
  1696. b = dz->sampbuf[current_buf] + dz->buflen;
  1697. b--;
  1698. for(n = 0; n <dz->iparam[MSHR_SPLEN]; n ++) {
  1699. for(k = 0;k<outchans;k++) {
  1700. z = (*b) * (double)n/(double)dz->iparam[MSHR_SPLEN];
  1701. *b-- = (float)z;
  1702. }
  1703. }
  1704. }
  1705. /************************** PTR_SORT ***************************/
  1706. void ptr_sort(int end,dataptr dz)
  1707. {
  1708. int i,j;
  1709. int a;
  1710. int *chunkptr = dz->lparray[MSHR_CHUNKPTR];
  1711. for(j=1;j<end;j++) {
  1712. a = chunkptr[j];
  1713. i = j-1;
  1714. while(i >= 0 && chunkptr[i] > a) {
  1715. chunkptr[i+1]=chunkptr[i];
  1716. i--;
  1717. }
  1718. chunkptr[i+1] = a;
  1719. }
  1720. }
  1721. /*************************** PERMUTE_CHANS ***************************/
  1722. void permute_chans(int outchans,dataptr dz)
  1723. {
  1724. int n, t;
  1725. for(n=0;n<outchans;n++) {
  1726. t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
  1727. if(t==n)
  1728. prefixch(n,outchans,dz);
  1729. else
  1730. insertch(n,t,outchans,dz);
  1731. }
  1732. }
  1733. /****************************** INSERTCH ****************************/
  1734. void insertch(int n,int t,int outchans,dataptr dz)
  1735. {
  1736. shuflupch(t+1,outchans,dz);
  1737. dz->iparray[MSHR_PERMCH][t+1] = n;
  1738. }
  1739. /****************************** PREFIX ****************************/
  1740. void prefixch(int n,int outchans,dataptr dz)
  1741. {
  1742. shuflupch(0,outchans,dz);
  1743. dz->iparray[MSHR_PERMCH][0] = n;
  1744. }
  1745. /****************************** SHUFLUPCH ****************************/
  1746. void shuflupch(int k,int outchans,dataptr dz)
  1747. {
  1748. int n;
  1749. for(n = outchans - 1; n > k; n--)
  1750. dz->iparray[MSHR_PERMCH][n] = dz->iparray[MSHR_PERMCH][n-1];
  1751. }
  1752. /****************************** ROTATE ****************************
  1753. *
  1754. * Assign each N-chan chunk to a permuted set of channels.
  1755. */
  1756. void rotate(float *splicbuf,int len,int *permch,float *rot,int outchans)
  1757. {
  1758. int k, n, blokcnt = len/outchans;
  1759. for(k=0;k<blokcnt;k++) {
  1760. for(n = 0;n<outchans;n++)
  1761. rot[n] = splicbuf[permch[n]];
  1762. for(n = 0;n<outchans;n++)
  1763. splicbuf[n] = rot[n];
  1764. splicbuf += outchans;
  1765. }
  1766. }
  1767. /***************************** SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS **************************/
  1768. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1769. {
  1770. int n;
  1771. dz->fptr_cnt = 1;
  1772. dz->iarray_cnt = 2;
  1773. dz->larray_cnt = 2;
  1774. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  1775. sprintf(errstr,"INSUFFICIENT MEMORY for internal int arrays.\n");
  1776. return(MEMORY_ERROR);
  1777. }
  1778. for(n=0;n<dz->iarray_cnt;n++)
  1779. dz->iparray[n] = NULL;
  1780. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1781. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1782. return(MEMORY_ERROR);
  1783. }
  1784. for(n=0;n<dz->larray_cnt;n++)
  1785. dz->lparray[n] = NULL;
  1786. if((dz->fptr = (float **)malloc(dz->fptr_cnt * sizeof(float *)))==NULL) {
  1787. sprintf(errstr,"INSUFFICIENT MEMORY for internal float-pointer arrays.\n");
  1788. return(MEMORY_ERROR);
  1789. }
  1790. for(n=0;n<dz->fptr_cnt;n++)
  1791. dz->fptr[n] = NULL;
  1792. return(FINISHED);
  1793. }
  1794. /***************************** SET_LEGAL_INTERNALPARAM_STRUCTURE **************************/
  1795. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1796. {
  1797. int exit_status;
  1798. exit_status = set_internalparam_data("iiiiiiiiiiiii",ap);
  1799. return(exit_status);
  1800. }