distmore.c 104 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695
  1. /*
  2. * Copyright (c) 1983-2013 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. /*
  22. * SPLICES NOT WORKING IN REASSEMBLY.
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <structures.h>
  27. #include <tkglobals.h>
  28. #include <pnames.h>
  29. #include <filetype.h>
  30. #include <processno.h>
  31. #include <modeno.h>
  32. #include <logic.h>
  33. #include <globcon.h>
  34. #include <cdpmain.h>
  35. #include <math.h>
  36. #include <mixxcon.h>
  37. #include <osbind.h>
  38. #include <standalone.h>
  39. #include <ctype.h>
  40. #include <sfsys.h>
  41. #include <string.h>
  42. #include <srates.h>
  43. #include <formants.h>
  44. #include <speccon.h>
  45. #define SAFETY 64
  46. #define maxstep is_sharp
  47. #define minstep scalefact
  48. #define maxxstep rampbrksize
  49. #define SSPLICELEN 15
  50. #define DISTMORERAND (0.2)
  51. #define ZREPETS 0
  52. #define ZDUR 1
  53. #define ZMINSIZ 2
  54. #define ZFRAC 3
  55. #ifdef unix
  56. #define round(x) lround((x))
  57. #endif
  58. #ifndef HUGE
  59. #define HUGE 3.40282347e+38F
  60. #endif
  61. char errstr[2400];
  62. int anal_infiles = 1;
  63. int sloom = 0;
  64. int sloombatch = 0;
  65. const char* cdp_version = "6.2.0";
  66. //CDP LIB REPLACEMENTS
  67. static int setup_distmore_application(dataptr dz);
  68. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  69. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  70. static int setup_distmore_param_ranges_and_defaults(dataptr dz);
  71. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  72. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  73. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  74. static int establish_application(dataptr dz);
  75. static int initialise_vflags(dataptr dz);
  76. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  77. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  78. static int mark_parameter_types(dataptr dz,aplptr ap);
  79. static int assign_file_data_storage(int infilecnt,dataptr dz);
  80. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  81. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  82. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  83. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  84. static int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz);
  85. static int read_mark_data(char *filename,dataptr dz);
  86. //static int read_feature_data(char *filename,dataptr dz);
  87. static int check_distmore_param_validity_and_consistency(dataptr dz);
  88. static int distmore_param_preprocess(dataptr dz);
  89. static int distbright (dataptr dz);
  90. static int distdouble (dataptr dz);
  91. static int generate_tail_segments(dataptr dz);
  92. static int create_distmore_sndbufs(dataptr dz);
  93. static int recreate_distmore_sndbufs(dataptr dz);
  94. static void reversebuf2(float *buf1,float *buf2,int sampcnt);
  95. static void reversebuf(float *buf,int sampcnt);
  96. static int segsbkwd(dataptr dz);
  97. static int segszig(dataptr dz);
  98. static void cutend_and_splicend(float *buf,int cutlen,int sampcnt,int splicelen);
  99. static double getstepratio(dataptr dz);
  100. /**************************************** MAIN *********************************************/
  101. int main(int argc,char *argv[])
  102. {
  103. int exit_status;
  104. dataptr dz = NULL;
  105. char **cmdline;
  106. int cmdlinecnt;
  107. aplptr ap;
  108. int is_launched = FALSE;
  109. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  110. fprintf(stdout,"%s\n",cdp_version);
  111. fflush(stdout);
  112. return 0;
  113. }
  114. /* CHECK FOR SOUNDLOOM */
  115. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  116. sloom = 0;
  117. sloombatch = 1;
  118. }
  119. if(sflinit("cdp")){
  120. sfperror("cdp: initialisation\n");
  121. return(FAILED);
  122. }
  123. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  124. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  125. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  126. return(FAILED);
  127. }
  128. if(!sloom) {
  129. if(argc == 1) {
  130. usage1();
  131. return(FAILED);
  132. } else if(argc == 2) {
  133. usage2(argv[1]);
  134. return(FAILED);
  135. }
  136. }
  137. if(!sloom) {
  138. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  139. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  140. return(FAILED);
  141. }
  142. cmdline = argv;
  143. cmdlinecnt = argc;
  144. if((get_the_process_no(argv[0],dz))<0)
  145. return(FAILED);
  146. cmdline++;
  147. cmdlinecnt--;
  148. switch(dz->process) {
  149. case(DISTBRIGHT): dz->maxmode = 3; break;
  150. case(DISTDOUBLE): dz->maxmode = 0; break;
  151. case(SEGSBKWD): dz->maxmode = 9; break;
  152. case(SEGSZIG): dz->maxmode = 3; break;
  153. }
  154. if(dz->maxmode > 0) {
  155. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  156. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  157. return(exit_status);
  158. }
  159. cmdline++;
  160. cmdlinecnt--;
  161. }
  162. // setup_particular_application =
  163. if((exit_status = setup_distmore_application(dz))<0) {
  164. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  165. return(FAILED);
  166. }
  167. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  168. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  169. return(FAILED);
  170. }
  171. } else {
  172. //parse_TK_data() =
  173. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  174. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  175. return(exit_status);
  176. }
  177. }
  178. ap = dz->application;
  179. // parse_infile_and_hone_type() =
  180. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  181. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  182. return(FAILED);
  183. }
  184. // open_first_infile CDP LIB
  185. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  186. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  187. return(FAILED);
  188. }
  189. cmdlinecnt--;
  190. cmdline++;
  191. // setup_param_ranges_and_defaults() =
  192. if((exit_status = setup_distmore_param_ranges_and_defaults(dz))<0) {
  193. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  194. return(FAILED);
  195. }
  196. // handle_extra_infiles() : redundant
  197. // handle_outfile() =
  198. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  199. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  200. return(FAILED);
  201. }
  202. // handle_formants() redundant
  203. // handle_formant_quiksearch() redundant
  204. dz->array_cnt = 0;
  205. dz->iarray_cnt = 0;
  206. dz->larray_cnt = 0;
  207. if(dz->process == DISTBRIGHT) {
  208. dz->array_cnt = 3; // 3 for: Seg starttimes, average zerocross rates, possibly expanded seg starttimes
  209. dz->iarray_cnt = 2; // 2 for: H/T labels, reordering list
  210. dz->larray_cnt = 1; // For times as sample-cnts
  211. }
  212. if(dz->process == SEGSBKWD || dz->process == SEGSZIG) {
  213. dz->array_cnt = 1; // 1 for: Seg starttimes
  214. dz->larray_cnt = 1; // For times as sample-cnts
  215. }
  216. // handle_special_data ....
  217. if(dz->process != DISTDOUBLE && !(dz->process == SEGSZIG && dz->mode != 0)) {
  218. if((exit_status = handle_the_special_data(&cmdlinecnt,&cmdline,dz))<0) {
  219. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  220. return(FAILED);
  221. }
  222. }
  223. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  224. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  225. return(FAILED);
  226. }
  227. // check_param_validity_and_consistency .....
  228. if((exit_status = check_distmore_param_validity_and_consistency(dz))<0) {
  229. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  230. return(FAILED);
  231. }
  232. if((exit_status = create_distmore_sndbufs(dz))<0) {
  233. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  234. return(FAILED);
  235. }
  236. if(dz->process == DISTDOUBLE) {
  237. if((exit_status = distmore_param_preprocess(dz))<0) {
  238. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  239. return(FAILED);
  240. }
  241. }
  242. is_launched = TRUE;
  243. switch(dz->process) {
  244. case(DISTBRIGHT):
  245. if((exit_status = distbright(dz))<0) {
  246. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  247. return(FAILED);
  248. }
  249. break;
  250. case(DISTDOUBLE):
  251. if((exit_status = distdouble(dz))<0) {
  252. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  253. return(FAILED);
  254. }
  255. break;
  256. case(SEGSBKWD):
  257. if((exit_status = segsbkwd(dz))<0) {
  258. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  259. return(FAILED);
  260. }
  261. break;
  262. case(SEGSZIG):
  263. if((exit_status = segszig(dz))<0) {
  264. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  265. return(FAILED);
  266. }
  267. break;
  268. }
  269. if((exit_status = complete_output(dz))<0) {
  270. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  271. return(FAILED);
  272. }
  273. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz);
  274. free(dz);
  275. return(SUCCEEDED);
  276. }
  277. /**********************************************
  278. REPLACED CDP LIB FUNCTIONS
  279. **********************************************/
  280. /****************************** SET_PARAM_DATA *********************************/
  281. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  282. {
  283. ap->special_data = (char)special_data;
  284. ap->param_cnt = (char)paramcnt;
  285. ap->max_param_cnt = (char)maxparamcnt;
  286. if(ap->max_param_cnt>0) {
  287. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  288. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  289. return(MEMORY_ERROR);
  290. }
  291. strcpy(ap->param_list,paramlist);
  292. }
  293. return(FINISHED);
  294. }
  295. /****************************** SET_VFLGS *********************************/
  296. int set_vflgs
  297. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  298. {
  299. ap->option_cnt = (char) optcnt; /*RWD added cast */
  300. if(optcnt) {
  301. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  302. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  303. return(MEMORY_ERROR);
  304. }
  305. strcpy(ap->option_list,optlist);
  306. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  307. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  308. return(MEMORY_ERROR);
  309. }
  310. strcpy(ap->option_flags,optflags);
  311. }
  312. ap->vflag_cnt = (char) vflagcnt;
  313. ap->variant_param_cnt = (char) vparamcnt;
  314. if(vflagcnt) {
  315. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  316. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  317. return(MEMORY_ERROR);
  318. }
  319. strcpy(ap->variant_list,varlist);
  320. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  321. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  322. return(MEMORY_ERROR);
  323. }
  324. strcpy(ap->variant_flags,varflags);
  325. }
  326. return(FINISHED);
  327. }
  328. /***************************** APPLICATION_INIT **************************/
  329. int application_init(dataptr dz)
  330. {
  331. int exit_status;
  332. int storage_cnt;
  333. int tipc, brkcnt;
  334. aplptr ap = dz->application;
  335. if(ap->vflag_cnt>0)
  336. initialise_vflags(dz);
  337. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  338. ap->total_input_param_cnt = (char)tipc;
  339. if(tipc>0) {
  340. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  341. return(exit_status);
  342. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  343. return(exit_status);
  344. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  345. return(exit_status);
  346. }
  347. brkcnt = tipc;
  348. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  349. if(brkcnt>0) {
  350. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  351. return(exit_status);
  352. }
  353. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  354. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  355. return(exit_status);
  356. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  357. return(exit_status);
  358. }
  359. if((exit_status = mark_parameter_types(dz,ap))<0)
  360. return(exit_status);
  361. // establish_infile_constants() replaced by
  362. dz->infilecnt = 1;
  363. //establish_bufptrs_and_extra_buffers():
  364. return(FINISHED);
  365. }
  366. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  367. /* RWD mallo changed to calloc; helps debug verison run as release! */
  368. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  369. {
  370. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  371. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  372. return(MEMORY_ERROR);
  373. }
  374. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  375. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  376. return(MEMORY_ERROR);
  377. }
  378. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  379. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  380. return(MEMORY_ERROR);
  381. }
  382. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  383. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  384. return(MEMORY_ERROR);
  385. }
  386. return(FINISHED);
  387. }
  388. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  389. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  390. {
  391. int n;
  392. for(n=0;n<storage_cnt;n++) {
  393. dz->is_int[n] = (char)0;
  394. dz->no_brk[n] = (char)0;
  395. }
  396. return(FINISHED);
  397. }
  398. /***************************** MARK_PARAMETER_TYPES **************************/
  399. int mark_parameter_types(dataptr dz,aplptr ap)
  400. {
  401. int n, m; /* PARAMS */
  402. for(n=0;n<ap->max_param_cnt;n++) {
  403. switch(ap->param_list[n]) {
  404. case('0'): break; /* dz->is_active[n] = 0 is default */
  405. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  406. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  407. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  408. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  409. default:
  410. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  411. return(PROGRAM_ERROR);
  412. }
  413. } /* OPTIONS */
  414. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  415. switch(ap->option_list[n]) {
  416. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  417. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  418. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  419. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  420. default:
  421. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  422. return(PROGRAM_ERROR);
  423. }
  424. } /* VARIANTS */
  425. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  426. switch(ap->variant_list[n]) {
  427. case('0'): break;
  428. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  429. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  430. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  431. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  432. default:
  433. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  434. return(PROGRAM_ERROR);
  435. }
  436. } /* INTERNAL */
  437. for(n=0,
  438. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  439. switch(ap->internal_param_list[n]) {
  440. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  441. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  442. case('d'): dz->no_brk[m] = (char)1; break;
  443. default:
  444. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  445. return(PROGRAM_ERROR);
  446. }
  447. }
  448. return(FINISHED);
  449. }
  450. /************************ HANDLE_THE_OUTFILE *********************/
  451. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  452. {
  453. int exit_status;
  454. char *filename = (*cmdline)[0];
  455. if(filename[0]=='-' && filename[1]=='f') {
  456. dz->floatsam_output = 1;
  457. dz->true_outfile_stype = SAMP_FLOAT;
  458. filename+= 2;
  459. }
  460. if(!sloom) {
  461. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  462. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  463. return(DATA_ERROR);
  464. }
  465. }
  466. strcpy(dz->outfilename,filename);
  467. if((exit_status = create_sized_outfile(filename,dz))<0)
  468. return(exit_status);
  469. (*cmdline)++;
  470. (*cmdlinecnt)--;
  471. return(FINISHED);
  472. }
  473. /***************************** ESTABLISH_APPLICATION **************************/
  474. int establish_application(dataptr dz)
  475. {
  476. aplptr ap;
  477. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  478. sprintf(errstr,"establish_application()\n");
  479. return(MEMORY_ERROR);
  480. }
  481. ap = dz->application;
  482. memset((char *)ap,0,sizeof(struct applic));
  483. return(FINISHED);
  484. }
  485. /************************* INITIALISE_VFLAGS *************************/
  486. int initialise_vflags(dataptr dz)
  487. {
  488. int n;
  489. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  490. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  491. return(MEMORY_ERROR);
  492. }
  493. for(n=0;n<dz->application->vflag_cnt;n++)
  494. dz->vflag[n] = FALSE;
  495. return FINISHED;
  496. }
  497. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  498. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  499. {
  500. int n;
  501. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  502. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  503. return(MEMORY_ERROR);
  504. }
  505. for(n=0;n<tipc;n++)
  506. ap->default_val[n] = 0.0;
  507. return(FINISHED);
  508. }
  509. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  510. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  511. {
  512. int n;
  513. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  514. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  515. return(MEMORY_ERROR);
  516. }
  517. for(n=0;n<tipc;n++)
  518. dz->is_active[n] = (char)0;
  519. return(FINISHED);
  520. }
  521. /************************* SETUP_DISTMORE_APPLICATION *******************/
  522. int setup_distmore_application(dataptr dz)
  523. {
  524. int exit_status;
  525. aplptr ap;
  526. if((exit_status = establish_application(dz))<0) // GLOBAL
  527. return(FAILED);
  528. ap = dz->application;
  529. // SEE parstruct FOR EXPLANATION of next 2 functions
  530. switch(dz->process) {
  531. case(DISTBRIGHT):
  532. if((exit_status = set_param_data(ap,MARKLIST,0,0,""))<0)
  533. return(FAILED);
  534. if((exit_status = set_vflgs(ap,"s",1,"d","d",1,0,"0"))<0)
  535. return(FAILED);
  536. dz->maxmode = 3;
  537. break;
  538. case(DISTDOUBLE):
  539. if((exit_status = set_param_data(ap,0,1,1,"i"))<0)
  540. return(FAILED);
  541. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  542. return(FAILED);
  543. dz->maxmode = 0;
  544. break;
  545. case(SEGSBKWD):
  546. if((exit_status = set_param_data(ap,MARKLIST,0,0,""))<0)
  547. return(FAILED);
  548. if((exit_status = set_vflgs(ap,"",0,"","",0,0,""))<0)
  549. return(FAILED);
  550. dz->maxmode = 9;
  551. break;
  552. case(SEGSZIG):
  553. switch(dz->mode) {
  554. case(0): exit_status = set_param_data(ap,MARKLIST,2,1,"I0"); break;
  555. case(1): exit_status = set_param_data(ap,0 ,2,1,"i0"); break;
  556. case(2): exit_status = set_param_data(ap,0 ,2,2,"id"); break;
  557. }
  558. if(exit_status < 0)
  559. return(FAILED);
  560. switch(dz->mode) {
  561. case(0): exit_status = set_vflgs(ap,"sp",2,"dD","l",1,0,"0"); break;
  562. case(1): exit_status = set_vflgs(ap,"sp",2,"dd","l",1,0,"0"); break;
  563. case(2): exit_status = set_vflgs(ap,"sp",2,"dd","l",1,0,"0"); break;
  564. }
  565. if(exit_status < 0)
  566. return(FAILED);
  567. dz->maxmode = 3;
  568. break;
  569. }
  570. dz->input_data_type = SNDFILES_ONLY;
  571. dz->process_type = UNEQUAL_SNDFILE;
  572. dz->outfiletype = SNDFILE_OUT;
  573. // set_legal_infile_structure -->
  574. dz->has_otherfile = FALSE;
  575. // assign_process_logic -->
  576. return application_init(dz); //GLOBAL
  577. }
  578. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  579. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  580. {
  581. int exit_status;
  582. infileptr infile_info;
  583. if(!sloom) {
  584. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  585. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  586. return(MEMORY_ERROR);
  587. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  588. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  589. return(DATA_ERROR);
  590. } else if(infile_info->filetype != SNDFILE) {
  591. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  592. return(DATA_ERROR);
  593. } else if(infile_info->channels != 1) {
  594. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  595. return(DATA_ERROR);
  596. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  597. sprintf(errstr,"Failed to copy file parsing information\n");
  598. return(PROGRAM_ERROR);
  599. }
  600. free(infile_info);
  601. }
  602. return(FINISHED);
  603. }
  604. /************************* SETUP_DISTMORE_PARAM_RANGES_AND_DEFAULTS *******************/
  605. int setup_distmore_param_ranges_and_defaults(dataptr dz)
  606. {
  607. int exit_status;
  608. aplptr ap = dz->application;
  609. // set_param_ranges()
  610. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  611. // NB total_input_param_cnt is > 0 !!!
  612. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  613. return(FAILED);
  614. // get_param_ranges()
  615. switch(dz->process) {
  616. case(DISTBRIGHT):
  617. ap->lo[0] = 2;
  618. ap->hi[0] = 15;
  619. ap->default_val[0] = 15;
  620. dz->maxmode = 3;
  621. break;
  622. case(DISTDOUBLE):
  623. ap->lo[0] = 1;
  624. ap->hi[0] = 4;
  625. ap->default_val[0] = 1;
  626. dz->maxmode = 0;
  627. break;
  628. case(SEGSBKWD):
  629. dz->maxmode = 0;
  630. break;
  631. case(SEGSZIG):
  632. ap->lo[0] = 1;
  633. ap->hi[0] = 64;
  634. ap->default_val[0] = 1;
  635. if(dz->mode==2) {
  636. ap->lo[1] = dz->duration * 2;
  637. ap->hi[1] = dz->duration * 64;
  638. ap->default_val[1] = dz->duration * 4;
  639. }
  640. ap->lo[2] = 0;
  641. ap->hi[2] = 1000;
  642. ap->default_val[2] = 0;
  643. ap->lo[3] = 0.2;
  644. ap->hi[3] = 1.0;
  645. ap->default_val[3] = 1.0;
  646. dz->maxmode = 3;
  647. break;
  648. }
  649. if(!sloom)
  650. put_default_vals_in_all_params(dz);
  651. return(FINISHED);
  652. }
  653. /********************************* PARSE_SLOOM_DATA *********************************/
  654. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  655. {
  656. int exit_status;
  657. int cnt = 1, infilecnt;
  658. int filesize, insams, inbrksize;
  659. double dummy;
  660. int true_cnt = 0;
  661. aplptr ap;
  662. while(cnt<=PRE_CMDLINE_DATACNT) {
  663. if(cnt > argc) {
  664. sprintf(errstr,"Insufficient data sent from TK\n");
  665. return(DATA_ERROR);
  666. }
  667. switch(cnt) {
  668. case(1):
  669. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  670. sprintf(errstr,"Cannot read process no. sent from TK\n");
  671. return(DATA_ERROR);
  672. }
  673. break;
  674. case(2):
  675. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  676. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  677. return(DATA_ERROR);
  678. }
  679. if(dz->mode > 0)
  680. dz->mode--;
  681. //setup_particular_application() =
  682. if((exit_status = setup_distmore_application(dz))<0)
  683. return(exit_status);
  684. ap = dz->application;
  685. break;
  686. case(3):
  687. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  688. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  689. return(DATA_ERROR);
  690. }
  691. if(infilecnt < 1) {
  692. true_cnt = cnt + 1;
  693. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  694. }
  695. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  696. return(exit_status);
  697. break;
  698. case(INPUT_FILETYPE+4):
  699. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  700. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  701. return(DATA_ERROR);
  702. }
  703. break;
  704. case(INPUT_FILESIZE+4):
  705. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  706. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  707. return(DATA_ERROR);
  708. }
  709. dz->insams[0] = filesize;
  710. break;
  711. case(INPUT_INSAMS+4):
  712. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  713. sprintf(errstr,"Cannot read insams sent from TK\n");
  714. return(DATA_ERROR);
  715. }
  716. dz->insams[0] = insams;
  717. break;
  718. case(INPUT_SRATE+4):
  719. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  720. sprintf(errstr,"Cannot read srate sent from TK\n");
  721. return(DATA_ERROR);
  722. }
  723. break;
  724. case(INPUT_CHANNELS+4):
  725. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  726. sprintf(errstr,"Cannot read channels sent from TK\n");
  727. return(DATA_ERROR);
  728. }
  729. break;
  730. case(INPUT_STYPE+4):
  731. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  732. sprintf(errstr,"Cannot read stype sent from TK\n");
  733. return(DATA_ERROR);
  734. }
  735. break;
  736. case(INPUT_ORIGSTYPE+4):
  737. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  738. sprintf(errstr,"Cannot read origstype sent from TK\n");
  739. return(DATA_ERROR);
  740. }
  741. break;
  742. case(INPUT_ORIGRATE+4):
  743. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  744. sprintf(errstr,"Cannot read origrate sent from TK\n");
  745. return(DATA_ERROR);
  746. }
  747. break;
  748. case(INPUT_MLEN+4):
  749. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  750. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  751. return(DATA_ERROR);
  752. }
  753. break;
  754. case(INPUT_DFAC+4):
  755. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  756. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  757. return(DATA_ERROR);
  758. }
  759. break;
  760. case(INPUT_ORIGCHANS+4):
  761. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  762. sprintf(errstr,"Cannot read origchans sent from TK\n");
  763. return(DATA_ERROR);
  764. }
  765. break;
  766. case(INPUT_SPECENVCNT+4):
  767. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  768. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  769. return(DATA_ERROR);
  770. }
  771. dz->specenvcnt = dz->infile->specenvcnt;
  772. break;
  773. case(INPUT_WANTED+4):
  774. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  775. sprintf(errstr,"Cannot read wanted sent from TK\n");
  776. return(DATA_ERROR);
  777. }
  778. break;
  779. case(INPUT_WLENGTH+4):
  780. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  781. sprintf(errstr,"Cannot read wlength sent from TK\n");
  782. return(DATA_ERROR);
  783. }
  784. break;
  785. case(INPUT_OUT_CHANS+4):
  786. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  787. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  788. return(DATA_ERROR);
  789. }
  790. break;
  791. /* RWD these chanegs to samps - tk will have to deal with that! */
  792. case(INPUT_DESCRIPTOR_BYTES+4):
  793. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  794. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  795. return(DATA_ERROR);
  796. }
  797. break;
  798. case(INPUT_IS_TRANSPOS+4):
  799. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  800. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  801. return(DATA_ERROR);
  802. }
  803. break;
  804. case(INPUT_COULD_BE_TRANSPOS+4):
  805. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  806. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  807. return(DATA_ERROR);
  808. }
  809. break;
  810. case(INPUT_COULD_BE_PITCH+4):
  811. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  812. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  813. return(DATA_ERROR);
  814. }
  815. break;
  816. case(INPUT_DIFFERENT_SRATES+4):
  817. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  818. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  819. return(DATA_ERROR);
  820. }
  821. break;
  822. case(INPUT_DUPLICATE_SNDS+4):
  823. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  824. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  825. return(DATA_ERROR);
  826. }
  827. break;
  828. case(INPUT_BRKSIZE+4):
  829. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  830. sprintf(errstr,"Cannot read brksize sent from TK\n");
  831. return(DATA_ERROR);
  832. }
  833. if(inbrksize > 0) {
  834. switch(dz->input_data_type) {
  835. case(WORDLIST_ONLY):
  836. break;
  837. case(PITCH_AND_PITCH):
  838. case(PITCH_AND_TRANSPOS):
  839. case(TRANSPOS_AND_TRANSPOS):
  840. dz->tempsize = inbrksize;
  841. break;
  842. case(BRKFILES_ONLY):
  843. case(UNRANGED_BRKFILE_ONLY):
  844. case(DB_BRKFILES_ONLY):
  845. case(ALL_FILES):
  846. case(ANY_NUMBER_OF_ANY_FILES):
  847. if(dz->extrabrkno < 0) {
  848. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  849. return(DATA_ERROR);
  850. }
  851. if(dz->brksize == NULL) {
  852. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  853. return(PROGRAM_ERROR);
  854. }
  855. dz->brksize[dz->extrabrkno] = inbrksize;
  856. break;
  857. default:
  858. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  859. dz->input_data_type);
  860. return(PROGRAM_ERROR);
  861. }
  862. break;
  863. }
  864. break;
  865. case(INPUT_NUMSIZE+4):
  866. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  867. sprintf(errstr,"Cannot read numsize sent from TK\n");
  868. return(DATA_ERROR);
  869. }
  870. break;
  871. case(INPUT_LINECNT+4):
  872. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  873. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  874. return(DATA_ERROR);
  875. }
  876. break;
  877. case(INPUT_ALL_WORDS+4):
  878. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  879. sprintf(errstr,"Cannot read all_words sent from TK\n");
  880. return(DATA_ERROR);
  881. }
  882. break;
  883. case(INPUT_ARATE+4):
  884. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  885. sprintf(errstr,"Cannot read arate sent from TK\n");
  886. return(DATA_ERROR);
  887. }
  888. break;
  889. case(INPUT_FRAMETIME+4):
  890. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  891. sprintf(errstr,"Cannot read frametime sent from TK\n");
  892. return(DATA_ERROR);
  893. }
  894. dz->frametime = (float)dummy;
  895. break;
  896. case(INPUT_WINDOW_SIZE+4):
  897. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  898. sprintf(errstr,"Cannot read window_size sent from TK\n");
  899. return(DATA_ERROR);
  900. }
  901. break;
  902. case(INPUT_NYQUIST+4):
  903. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  904. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  905. return(DATA_ERROR);
  906. }
  907. break;
  908. case(INPUT_DURATION+4):
  909. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  910. sprintf(errstr,"Cannot read duration sent from TK\n");
  911. return(DATA_ERROR);
  912. }
  913. break;
  914. case(INPUT_MINBRK+4):
  915. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  916. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  917. return(DATA_ERROR);
  918. }
  919. break;
  920. case(INPUT_MAXBRK+4):
  921. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  922. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  923. return(DATA_ERROR);
  924. }
  925. break;
  926. case(INPUT_MINNUM+4):
  927. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  928. sprintf(errstr,"Cannot read minnum sent from TK\n");
  929. return(DATA_ERROR);
  930. }
  931. break;
  932. case(INPUT_MAXNUM+4):
  933. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  934. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  935. return(DATA_ERROR);
  936. }
  937. break;
  938. default:
  939. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  940. return(PROGRAM_ERROR);
  941. }
  942. cnt++;
  943. }
  944. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  945. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  946. return(DATA_ERROR);
  947. }
  948. if(true_cnt)
  949. cnt = true_cnt;
  950. *cmdlinecnt = 0;
  951. while(cnt < argc) {
  952. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  953. return(exit_status);
  954. cnt++;
  955. }
  956. return(FINISHED);
  957. }
  958. /********************************* GET_TK_CMDLINE_WORD *********************************/
  959. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  960. {
  961. if(*cmdlinecnt==0) {
  962. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  963. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  964. return(MEMORY_ERROR);
  965. }
  966. } else {
  967. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  968. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  969. return(MEMORY_ERROR);
  970. }
  971. }
  972. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  973. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  974. return(MEMORY_ERROR);
  975. }
  976. strcpy((*cmdline)[*cmdlinecnt],q);
  977. (*cmdlinecnt)++;
  978. return(FINISHED);
  979. }
  980. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  981. int assign_file_data_storage(int infilecnt,dataptr dz)
  982. {
  983. int exit_status;
  984. int no_sndfile_system_files = FALSE;
  985. dz->infilecnt = infilecnt;
  986. if((exit_status = allocate_filespace(dz))<0)
  987. return(exit_status);
  988. if(no_sndfile_system_files)
  989. dz->infilecnt = 0;
  990. return(FINISHED);
  991. }
  992. /************************* redundant functions: to ensure libs compile OK *******************/
  993. int assign_process_logic(dataptr dz)
  994. {
  995. return(FINISHED);
  996. }
  997. void set_legal_infile_structure(dataptr dz)
  998. {}
  999. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1000. {
  1001. return(FINISHED);
  1002. }
  1003. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1004. {
  1005. return(FINISHED);
  1006. }
  1007. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1008. {
  1009. return(FINISHED);
  1010. }
  1011. int read_special_data(char *str,dataptr dz)
  1012. {
  1013. return(FINISHED);
  1014. }
  1015. int inner_loop
  1016. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1017. {
  1018. return(FINISHED);
  1019. }
  1020. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1021. {
  1022. return(FINISHED);
  1023. }
  1024. /******************************** USAGE1 ********************************/
  1025. int usage1(void)
  1026. {
  1027. fprintf(stderr,
  1028. "\nUSAGE: distmore NAME (mode) infile outfile (parameters)\n"
  1029. "\n"
  1030. "MORE WAVESET DISTORTION PROGRAMS\n"
  1031. "\n"
  1032. "where NAME can be any one of\n"
  1033. "\n"
  1034. "bright double segsbkwd segszig\n"
  1035. "\n"
  1036. "Type 'distmore bright' for more info on distmore bright.. ETC.\n");
  1037. return(USAGE_ONLY);
  1038. }
  1039. /********************************************************************************************/
  1040. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1041. {
  1042. if( !strcmp(prog_identifier_from_cmdline,"bright")) dz->process = DISTBRIGHT;
  1043. else if(!strcmp(prog_identifier_from_cmdline,"double")) dz->process = DISTDOUBLE;
  1044. else if(!strcmp(prog_identifier_from_cmdline,"segsbkwd")) dz->process = SEGSBKWD;
  1045. else if(!strcmp(prog_identifier_from_cmdline,"segszig")) dz->process = SEGSZIG;
  1046. else {
  1047. fprintf(stderr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1048. return(USAGE_ONLY);
  1049. }
  1050. return(FINISHED);
  1051. }
  1052. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1053. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1054. {
  1055. int n;
  1056. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1057. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1058. return(MEMORY_ERROR);
  1059. }
  1060. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1061. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1062. return(MEMORY_ERROR);
  1063. }
  1064. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1065. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1066. return(MEMORY_ERROR);
  1067. }
  1068. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1069. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1070. return(MEMORY_ERROR);
  1071. }
  1072. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1073. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1074. return(MEMORY_ERROR);
  1075. }
  1076. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1077. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1078. return(MEMORY_ERROR);
  1079. }
  1080. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1081. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1082. return(MEMORY_ERROR);
  1083. }
  1084. for(n=0;n<brkcnt;n++) {
  1085. dz->brk[n] = NULL;
  1086. dz->brkptr[n] = NULL;
  1087. dz->brkinit[n] = 0;
  1088. dz->brksize[n] = 0;
  1089. }
  1090. return(FINISHED);
  1091. }
  1092. /******************************** USAGE2 ********************************/
  1093. int usage2(char *str)
  1094. {
  1095. if(!strcmp(str,"bright")) {
  1096. fprintf(stderr,
  1097. "USAGE: distmore bright 1-3 infil outfil marklist [-ssplicelen -d]\n"
  1098. "\n"
  1099. "\nReorders sound segments in order of average zero-crossing rate\n."
  1100. "\n"
  1101. "MARKLIST A list of timemarks in source, marking (paired) Heads and Tails.\n"
  1102. " e.g. consonant onset, and vowel continuation of source.\n"
  1103. " (It is assumed that the first mark is at a Head segment.)\n"
  1104. "\n"
  1105. "Extract data ...\n"
  1106. "MODE 1 from Heads, & from Tails cut to segments, size approx equal to Heads.\n"
  1107. "MODE 2 from Heads and Tails, as defined by marklist.\n"
  1108. "MODE 3 from Tails only.\n"
  1109. "\n"
  1110. "SPLICELEN Length of splice in mS\n"
  1111. "-d Output in decreasing order of brightness. (Default: increasing).\n");
  1112. } else if(!strcmp(str,"double")) {
  1113. fprintf(stderr,
  1114. "USAGE: distmore double infil outfil mult\n"
  1115. "\n"
  1116. "Doubles (quadruples etc.) frq of each waveset\n."
  1117. "\n"
  1118. "MULT Octave step up (1-4).\n");
  1119. } else if(!strcmp(str,"segsbkwd")) {
  1120. fprintf(stderr,
  1121. "USAGE: distmore segsbkwd 1-9 infil outfil marklist\n"
  1122. "\n"
  1123. "Reverses certain (sets of) segments\n."
  1124. "\n"
  1125. "MODE 1: Reverse Tails\n"
  1126. "MODE 2: Reverse Heads\n"
  1127. "MODE 3: Reverse Head+Tail pairs\n"
  1128. "MODE 4: Reverse Head & Tail+Head+Tail set\n"
  1129. "MODE 5: Reverse Head+Tail+Head+Tail set\n"
  1130. "MODE 6: Reverse Head & Tail+Head+Tail+Head+Tail set\n"
  1131. "MODE 7: Reverse Head+Tail+Head+Tail+Head+Tail set\n"
  1132. "MODE 8: Reverse Head & Tail+Head+Tail+Head+Tail+Head+Tail set\n"
  1133. "MODE 9: Reverse Head+Tail+Head+Tail+Head+Tail+Head+Tail set\n"
  1134. "\n"
  1135. "MARKLIST A list of timemarks in source, marking (paired) Heads and Tails.\n"
  1136. " e.g. consonant onset, and vowel continuation of source.\n"
  1137. " (It is assumed that the first mark is at a Head segment.)\n");
  1138. } else if(!strcmp(str,"segszig")) {
  1139. fprintf(stderr,
  1140. "USAGE: distmore segszig 1 infil outfil marklist repets [-sshrinkto] [-pprop] [-l]\n"
  1141. "OR: distmore segszig 2 infil outfil repets [-sshrinkto] [-pprop] [-l]\n"
  1142. "OR: distmore segszig 3 infil outfil repets dur [-sshrinkto] [-pprop]\n"
  1143. "\n"
  1144. "MODE1 Zigzags across tail segments of a soundfile while playing it.\n"
  1145. "MODES 2&3 Zigzag across entire soundfile.\n"
  1146. "\n"
  1147. "MARKLIST A list of timemarks in source, marking (paired) Heads and Tails.\n"
  1148. " e.g. consonant onsets, and vowel continuations in source.\n"
  1149. " (First mark is assumed to be a Head segment).\n"
  1150. " In Mode 2, the whole file is processed.\n"
  1151. "\n"
  1152. "REPETS Number of zigzags (timevariable).\n"
  1153. "\n"
  1154. "SHRINKTO If set to zero, has no effect.\n"
  1155. " Otherwize Zigzags contract to minimum size 'minsiz' mS (Range %d upwards).\n"
  1156. "\n"
  1157. "DUR Duration of zigged output.\n"
  1158. "\n"
  1159. "PROP Proportion of Tail to use. Default, all of it. (timevariable).\n"
  1160. " CARE: If length of used-portion of any particular tail too short,\n"
  1161. " (less than \"SHRINKTO\" size) zigs for that tail will not shrink.\n"
  1162. "-l Shrink zigs logarithmically (default, linear shrink).\n",(SSPLICELEN * 2) + 1);
  1163. } else {
  1164. fprintf(stdout,"Unknown option '%s'\n",str);
  1165. fflush(stdout);
  1166. }
  1167. return(USAGE_ONLY);
  1168. }
  1169. int usage3(char *str1,char *str2)
  1170. {
  1171. fprintf(stderr,"Insufficient parameters on command line.\n");
  1172. return(USAGE_ONLY);
  1173. }
  1174. /****************************** GET_MODE *********************************/
  1175. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1176. {
  1177. char temp[200], *p;
  1178. if(sscanf(str,"%s",temp)!=1) {
  1179. sprintf(errstr,"Cannot read mode of program.\n");
  1180. return(USAGE_ONLY);
  1181. }
  1182. p = temp + strlen(temp) - 1;
  1183. while(p >= temp) {
  1184. if(!isdigit(*p)) {
  1185. fprintf(stderr,"Invalid mode of program entered.\n");
  1186. return(USAGE_ONLY);
  1187. }
  1188. p--;
  1189. }
  1190. if(sscanf(str,"%d",&dz->mode)!=1) {
  1191. fprintf(stderr,"Cannot read mode of program.\n");
  1192. return(USAGE_ONLY);
  1193. }
  1194. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1195. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1196. return(USAGE_ONLY);
  1197. }
  1198. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1199. return(FINISHED);
  1200. }
  1201. /************************ HANDLE_THE_SPECIAL_DATA *********************/
  1202. int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz)
  1203. {
  1204. int exit_status;
  1205. if(!sloom) {
  1206. if(*cmdlinecnt <= 0) {
  1207. sprintf(errstr,"Insufficient parameters on command line.\n");
  1208. return(USAGE_ONLY);
  1209. }
  1210. }
  1211. if((exit_status = read_mark_data((*cmdline)[0],dz))<0)
  1212. return(exit_status);
  1213. (*cmdline)++;
  1214. (*cmdlinecnt)--;
  1215. return(FINISHED);
  1216. }
  1217. /************************************ READ_MARK_DATA ************************************/
  1218. int read_mark_data(char *filename,dataptr dz)
  1219. {
  1220. double *time, lasttime, dummy, timestep;
  1221. int cnt, warned = 0;
  1222. int arraysize;
  1223. char temp[200], *q;
  1224. aplptr ap;
  1225. FILE *fp;
  1226. ap = dz->application;
  1227. if((fp = fopen(filename,"r"))==NULL) {
  1228. sprintf(errstr, "Can't open file %s to read data.\n",filename);
  1229. return(DATA_ERROR);
  1230. }
  1231. cnt = 0;
  1232. lasttime = -1.0;
  1233. dz->minstep = HUGE;
  1234. dz->maxstep = 0.0;
  1235. while(fgets(temp,200,fp)==temp) {
  1236. q = temp;
  1237. if(*q == ';') // Allow comments in file
  1238. continue;
  1239. while(get_float_from_within_string(&q,&dummy)) {
  1240. if(dummy < 0.0 || dummy <= lasttime) {
  1241. sprintf(errstr,"Times do not advance correctly in file %s.\n",filename);
  1242. return(DATA_ERROR);
  1243. }
  1244. if(dummy >= dz->duration) {
  1245. if(!warned) {
  1246. fprintf(stdout,"WARNING: Times beyond end of sndfile (%lf) in file %s. Ignoring them.\n",dz->duration,filename);
  1247. fflush(stdout);
  1248. warned = 1;
  1249. }
  1250. break;
  1251. }
  1252. if(cnt > 0) {
  1253. timestep = dummy - lasttime;
  1254. if(timestep < dz->minstep)
  1255. dz->minstep = timestep;
  1256. if(timestep > dz->maxstep)
  1257. dz->maxstep = timestep;
  1258. }
  1259. lasttime = dummy;
  1260. cnt++;
  1261. }
  1262. }
  1263. if(cnt == 0) {
  1264. sprintf(errstr,"No data in file %s\n",filename);
  1265. return(DATA_ERROR);
  1266. }
  1267. if(cnt < 4) {
  1268. sprintf(errstr,"Insufficient data (%d values) in file %s : Need at least 4\n",cnt,filename);
  1269. return(DATA_ERROR);
  1270. }
  1271. dz->itemcnt = cnt;
  1272. timestep = dz->duration - lasttime;
  1273. if(timestep < dz->minstep)
  1274. dz->minstep = timestep;
  1275. if(timestep > dz->maxstep)
  1276. dz->maxstep = timestep;
  1277. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  1278. sprintf(errstr,"INSUFFICIENT MEMORY for zerocross-density array (1)\n");
  1279. return(MEMORY_ERROR);
  1280. }
  1281. if(dz->iarray_cnt > 0) {
  1282. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  1283. sprintf(errstr,"INSUFFICIENT MEMORY for reordering array (1)\n");
  1284. return(MEMORY_ERROR);
  1285. }
  1286. }
  1287. if(dz->larray_cnt > 0) {
  1288. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1289. sprintf(errstr,"INSUFFICIENT MEMORY for sample times (1)\n");
  1290. return(MEMORY_ERROR);
  1291. }
  1292. }
  1293. if(dz->process == DISTBRIGHT && dz->mode == 0)
  1294. arraysize = (int)ceil(dz->duration/dz->minstep) + SAFETY; // In this mode, tail segs are further subdivided
  1295. else
  1296. arraysize = dz->itemcnt + SAFETY;
  1297. if(dz->process == DISTBRIGHT) {
  1298. if((dz->iparray[0] = (int *)malloc(arraysize * sizeof(int)))==NULL) { // Array for Head/Tail flags for labelling segments
  1299. sprintf(errstr,"INSUFFICIENT MEMORY for Head/Tail flags for labelling segments\n");
  1300. return(MEMORY_ERROR);
  1301. }
  1302. if((dz->iparray[1] = (int *)malloc(arraysize * sizeof(int)))==NULL) { // Array for Reordering these segments
  1303. sprintf(errstr,"INSUFFICIENT MEMORY for reordering array\n");
  1304. return(MEMORY_ERROR);
  1305. }
  1306. }
  1307. if((dz->parray[0] = (double *)malloc(arraysize * sizeof(double)))==NULL) { // Array for segment times
  1308. sprintf(errstr,"INSUFFICIENT MEMORY for time data in file %s. (2)\n",filename);
  1309. return(MEMORY_ERROR);
  1310. }
  1311. if(dz->process == DISTBRIGHT) {
  1312. if((dz->parray[1] = (double *)malloc(arraysize * sizeof(double)))==NULL) { // Array for zcross-density values (and possibly also for expanded time-set)
  1313. sprintf(errstr,"INSUFFICIENT MEMORY for time data in file %s. (2)\n",filename);
  1314. return(MEMORY_ERROR);
  1315. }
  1316. }
  1317. if((dz->lparray[0] = (int *)malloc(arraysize * 2 * sizeof(int)))==NULL) { // Array for segment sampletimes
  1318. sprintf(errstr,"INSUFFICIENT MEMORY for sampletime data from file %s. (2)\n",filename);
  1319. return(MEMORY_ERROR);
  1320. }
  1321. time = dz->parray[0];
  1322. rewind(fp);
  1323. lasttime = -1.0;
  1324. cnt = 0;
  1325. while(fgets(temp,200,fp)==temp) {
  1326. q = temp;
  1327. if(*q == ';') // Allow comments in file
  1328. continue;
  1329. while(get_float_from_within_string(&q,&dummy)) {
  1330. if(dummy >= dz->duration) {
  1331. if(!warned) {
  1332. fprintf(stdout,"WARNING: Times beyond end of sndfile (%lf) in file %s. Ignoring them.\n",dz->duration,filename);
  1333. fflush(stdout);
  1334. }
  1335. break;
  1336. }
  1337. *time = dummy;
  1338. lasttime = *time;
  1339. time++;
  1340. cnt++;
  1341. }
  1342. }
  1343. if(fclose(fp)<0) {
  1344. fprintf(stdout,"WARNING: Failed to close file %s.\n",filename);
  1345. fflush(stdout);
  1346. }
  1347. if((dz->process == SEGSBKWD || dz->process == SEGSZIG) && dz->minstep <= (2.0 * SSPLICELEN * MS_TO_SECS)) {
  1348. sprintf(errstr,"Some marked segment(s) shorter (%lf secs) than 2 splices (%lf): Cannot proceed.\n",dz->minstep,2.0 * SSPLICELEN * MS_TO_SECS);
  1349. return DATA_ERROR;
  1350. }
  1351. dz->itemcnt = cnt;
  1352. return(FINISHED);
  1353. }
  1354. /************************************ DISTMORE_PARAM_PREPROCESS ************************************/
  1355. int distmore_param_preprocess(dataptr dz)
  1356. {
  1357. int exit_status, phase = 0, startphase = 0, halfwavesetcnt = 0;
  1358. int n, wavsetsize = 0, maxwavsetsize = 0;
  1359. float *ibuf = dz->sampbuf[0];
  1360. if((exit_status = read_samps(ibuf,dz))<0)
  1361. return(exit_status);
  1362. while(dz->ssampsread > 0) {
  1363. for(n = 0; n < dz->ssampsread;n++) {
  1364. if(ibuf[n] > 0.0) {
  1365. if(startphase == 0) // If startphase not set (at outset), set startphase to equal phase found
  1366. startphase = 1;
  1367. phase = 1;
  1368. } else if(ibuf[n] < 0.0) {
  1369. if(startphase == 0)
  1370. startphase = -1;
  1371. phase = -1;
  1372. }
  1373. if(phase != startphase) { // If phase changes
  1374. halfwavesetcnt++; // Count half-wavesets
  1375. if(halfwavesetcnt > 1) { // Once we have 2 half-wavesets, we have a waveset
  1376. maxwavsetsize = max(maxwavsetsize,wavsetsize); // Save largest
  1377. wavsetsize = 0; // Reset counts of wavsetsize and halfwavesets
  1378. halfwavesetcnt = 0;
  1379. }
  1380. startphase = phase; // Starting phase reset to current phase
  1381. }
  1382. wavsetsize++; // Count size of current waveset
  1383. }
  1384. if((exit_status = read_samps(ibuf,dz))<0)
  1385. return(exit_status);
  1386. }
  1387. if(maxwavsetsize > dz->maxxstep) {
  1388. dz->maxxstep = maxwavsetsize;
  1389. if((exit_status = recreate_distmore_sndbufs(dz))<0)
  1390. return(exit_status);
  1391. }
  1392. sndseekEx(dz->ifd[0],0,0);
  1393. return FINISHED;
  1394. }
  1395. /************************************ CHECK_DISTMORE_PARAM_VALIDITY_AND_CONSISTENCY ************************************/
  1396. int check_distmore_param_validity_and_consistency(dataptr dz)
  1397. {
  1398. double srate = (double)dz->infile->srate;
  1399. switch(dz->process) {
  1400. case(DISTDOUBLE):
  1401. dz->iparam[0] = (int)round(pow(2.0,dz->iparam[0])); // Convert octs to frq multiplier
  1402. break;
  1403. case(DISTBRIGHT):
  1404. dz->iparam[0] = (int)round(dz->param[0] * MS_TO_SECS * srate); // Splicelen in samples
  1405. break;
  1406. case(SEGSZIG):
  1407. if(dz->param[ZMINSIZ] > 0 && dz->param[ZMINSIZ] < (SSPLICELEN * 2) + 1) {
  1408. sprintf(errstr,"MINIMUM ZIG SIZE CANNOT BE LESS THAN %d IF IT IS NOT ZERO\n",(SSPLICELEN * 2) + 1);
  1409. return DATA_ERROR;
  1410. }
  1411. dz->iparam[ZMINSIZ] = (int)round(dz->param[ZMINSIZ] * MS_TO_SECS * srate); // Min size of zigs in samples
  1412. break;
  1413. }
  1414. return FINISHED;
  1415. }
  1416. /************************************ DISTBRIGHT ************************************/
  1417. int distbright(dataptr dz)
  1418. {
  1419. int exit_status, n, m, done = 0;
  1420. int lastphase = 0, phase = 0;
  1421. int startindex, zcro = 0, sttindex = 0;
  1422. double srate = (double)dz->infile->srate;
  1423. double *time = dz->parray[0];
  1424. double *zcros = dz->parray[1];
  1425. int firsttime, nexttime, samptime;
  1426. int *ishead = dz->iparray[0], is_head;
  1427. int *order = dz->iparray[1]; // Holds reordering sequence
  1428. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1], *buf1, *buf2, *bufa = dz->sampbuf[2], *bufb = dz->sampbuf[3], *tempbuf;
  1429. int increases = 1, temp;
  1430. int k, j, z, obufpos, stt, sttsamp, endsamp, sampcnt1, sampcnt2;
  1431. int *sttend = dz->lparray[0];
  1432. double valn, valm;
  1433. int splicelen = dz->iparam[0];
  1434. samptime = 0;
  1435. startindex = 0;
  1436. is_head = 1;
  1437. for(n=0;n<dz->itemcnt;n++) { // Initially mark Head/Tail sequence
  1438. ishead[n] = is_head;
  1439. is_head = !is_head;
  1440. }
  1441. time[dz->itemcnt] = dz->duration; // Complete times array with the duration of the src
  1442. if(dz->mode == 0) {
  1443. if((exit_status = generate_tail_segments(dz)) < 0) // For mode 0, Head/Tail sequence re-marked here, as tail subdivisions added
  1444. return exit_status; // & dz->itemcnt increased
  1445. }
  1446. for(n=0,m=0;n < dz->itemcnt;n++,m+=2) {
  1447. sttend[m] = (int)round(time[n] * srate); // starttime of segment
  1448. if(flteq(time[n+1],dz->duration))
  1449. sttend[m+1] = dz->insams[0];
  1450. else { // endtime of segment
  1451. sttend[m+1] = (int)round(time[n+1] * srate); // including splice fade-down time
  1452. sttend[m+1] += splicelen;
  1453. sttend[m+1] = min(sttend[m+1],dz->insams[0]);
  1454. }
  1455. }
  1456. firsttime = sttend[sttindex];
  1457. nexttime = sttend[sttindex+2];
  1458. is_head = 1;
  1459. if((exit_status = read_samps(ibuf,dz))< 0) {
  1460. sprintf(errstr,"Failed to read data from input file.\n");
  1461. return(SYSTEM_ERROR);
  1462. }
  1463. while(dz->ssampsread > 0) {
  1464. n = 0;
  1465. while(n < dz->ssampsread) {
  1466. if(samptime >= firsttime) { // Skip over any sound before the first timemark in marklist
  1467. if(samptime >= nexttime) {
  1468. zcros[startindex] = (double)zcro/(time[sttindex+2] - time[sttindex]);
  1469. startindex++;
  1470. sttindex += 2;
  1471. zcro = 0;
  1472. lastphase = 0;
  1473. if(startindex >= dz->itemcnt) { // NB there is an extra time (src duration) at end of times data
  1474. done = 1;
  1475. break;
  1476. }
  1477. is_head = ishead[startindex];
  1478. nexttime = sttend[sttindex+2];
  1479. }
  1480. if(ibuf[n] > 0.0) {
  1481. phase = 1;
  1482. if(lastphase == 0)
  1483. lastphase = phase;
  1484. } else if(ibuf[n] < 0.0) {
  1485. phase = -1;
  1486. if(lastphase == 0)
  1487. lastphase = phase;
  1488. }
  1489. if(phase != lastphase) {
  1490. zcro++;
  1491. lastphase = phase;
  1492. }
  1493. }
  1494. samptime++;
  1495. n++;
  1496. }
  1497. if(done)
  1498. break;
  1499. if((exit_status = read_samps(ibuf,dz))< 0) {
  1500. sprintf(errstr,"Failed to read data from input file.\n");
  1501. return(SYSTEM_ERROR);
  1502. }
  1503. }
  1504. if(dz->mode == 2) { // In mode 2, join together H+T segs as single items
  1505. for(m=1,n=2;n<dz->itemcnt;m++,n+=2) // itemcnt itemcnt
  1506. time[m] = time[n]; // H T H T H T END ~OR~ H T H T H END
  1507. dz->itemcnt = m; // h h h h h h
  1508. }
  1509. // DO SORT AND THEN RECONSTRUCT
  1510. dz->itemcnt = startindex; // Reset count to actual count of zcros data items
  1511. if(dz->vflag[0])
  1512. increases = 0;
  1513. for(n=0;n<dz->itemcnt;n++)
  1514. order[n] = n;
  1515. for(n=0;n < dz->itemcnt-1;n++) { // Do the data/order sort
  1516. valn = zcros[n];
  1517. for(m=n+1;m < dz->itemcnt;m++) {
  1518. valm = zcros[m]; // If vals out of order
  1519. if((increases && valn > valm) || (!increases && valn < valm)) {
  1520. zcros[n] = valm; // Swap vals in array
  1521. zcros[m] = valn;
  1522. valn = zcros[n]; // Reset valn to its new value
  1523. temp = order[n]; // Swap order of items
  1524. order[n] = order[m];
  1525. order[m] = temp;
  1526. }
  1527. }
  1528. }
  1529. buf1 = bufa;
  1530. buf2 = bufb;
  1531. obufpos = 0;
  1532. // Copy initial segment into buffer 1
  1533. stt = order[0] * 2; // Start and endtimes of segs are in double-length int-array
  1534. sttsamp = sttend[stt];
  1535. endsamp = sttend[stt+1];
  1536. sampcnt1 = endsamp - sttsamp;
  1537. sndseekEx(dz->ifd[0],sttsamp,0);
  1538. if((exit_status = read_samps(ibuf,dz))<0)
  1539. return(exit_status);
  1540. memcpy((char *)buf1,(char *)ibuf,sampcnt1 * sizeof(float)); // Copy src chunk to buf1
  1541. for(k = 0; k < splicelen; k++)
  1542. buf1[k] = (float)(buf1[k] * ((double)k/(double)splicelen)); // DO start and end splices
  1543. for(k = 0, j = sampcnt1-1; k < splicelen; k++,j--)
  1544. buf1[j] = (float)(buf1[j] * ((double)k/(double)splicelen));
  1545. // Write the upsplice portion of 1st segment to obuf
  1546. for(m=0; m < splicelen; m++) {
  1547. obuf[obufpos++] = buf1[m];
  1548. //PROBABLY REDUNDANT
  1549. if(obufpos >= dz->buflen) {
  1550. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1551. return(exit_status);
  1552. obufpos = 0;
  1553. }
  1554. }
  1555. // Copy next segment into buffer 2
  1556. for(n=1;n < dz->itemcnt;n++) {
  1557. stt = order[n] * 2;
  1558. sttsamp = sttend[stt];
  1559. endsamp = sttend[stt+1];
  1560. sampcnt2 = endsamp - sttsamp;
  1561. sndseekEx(dz->ifd[0],sttsamp,0);
  1562. if((exit_status = read_samps(ibuf,dz))<0)
  1563. return(exit_status);
  1564. memcpy((char *)buf2,(char *)ibuf,sampcnt2 * sizeof(float));
  1565. for(k = 0; k < splicelen; k++)
  1566. buf2[k] = (float)(buf2[k] * ((double)k/(double)splicelen));
  1567. for(k = 0, j = sampcnt2-1; k < splicelen; k++,j--)
  1568. buf2[j] = (float)(buf2[j] * ((double)k/(double)splicelen));
  1569. // Write buf1 apart from the splice-brackets, to obuf
  1570. for(m=splicelen; m < sampcnt1 - splicelen;m++) {
  1571. obuf[obufpos++] = buf1[m];
  1572. if(obufpos >= dz->buflen) {
  1573. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1574. return(exit_status);
  1575. obufpos = 0;
  1576. }
  1577. }
  1578. // Write the cross-splice
  1579. for(z = 0;z < splicelen; z++,m++) {
  1580. obuf[obufpos++] = (float)(buf1[m] + buf2[z]);
  1581. if(obufpos >= dz->buflen) {
  1582. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1583. return(exit_status);
  1584. obufpos = 0;
  1585. }
  1586. }
  1587. // Swap the buffers, and buffer-data
  1588. tempbuf = buf1;
  1589. buf1 = buf2;
  1590. buf2 = tempbuf;
  1591. sampcnt1 = sampcnt2;
  1592. }
  1593. // Write all of the remaining segment
  1594. for(m=splicelen; m < sampcnt1; m++) {
  1595. obuf[obufpos++] = buf1[m];
  1596. if(obufpos >= dz->buflen) {
  1597. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1598. return(exit_status);
  1599. obufpos = 0;
  1600. }
  1601. }
  1602. // Flush the output buffer
  1603. if(obufpos > 0) {
  1604. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1605. return(exit_status);
  1606. }
  1607. return FINISHED;
  1608. }
  1609. /************************************ GENERATE_TAIL_SEGMENTS ************************************
  1610. *
  1611. * Slice tail sections into segments approx same size as bracketing head segments
  1612. */
  1613. int generate_tail_segments(dataptr dz)
  1614. {
  1615. int n, j, k, tailsegcnt;
  1616. double *time = dz->parray[0];
  1617. double *nutime = dz->parray[1];
  1618. int *ishead = dz->iparray[0];
  1619. double stthsize, endhsize, meanhsize, tailsize, randoffset = 0.0;
  1620. ishead[0] = 1;
  1621. ishead[1] = 0;
  1622. nutime[0] = time[0]; // H T H T H T
  1623. nutime[1] = time[1]; // n0 n1 n2 n3 n4 n5
  1624. j = 2; // |-|-----------|-|-----------|-|---------
  1625. stthsize = time[1] - time[0]; // tailsize
  1626. for(n=2;n < dz->itemcnt; n+=2) { // Step to next HEAD //stthsize endhsize
  1627. tailsize = time[n] - time[n-1]; //
  1628. endhsize = time[n+1] - time[n];
  1629. meanhsize = (stthsize + endhsize)/2.0; // New times(j), at n = 2, if tailsegcnt = 4
  1630. tailsegcnt = (int)round(tailsize/meanhsize); // n0 n1 n2 n3 n4 n5
  1631. meanhsize = tailsize/(double)tailsegcnt; // |-|-----------|-|-----------|-|---------
  1632. for(k=1;k < tailsegcnt;k++) { // j0 j1 | | |
  1633. nutime[j] = time[n-1] + (meanhsize * k); // j2 j3 j4 (3 new times inserted)
  1634. // H T T T T
  1635. randoffset = ((drand48() * 2.0) - 1.0)/3.0; // <-> <-> <->
  1636. randoffset *= DISTMORERAND; // j2 j3 j4
  1637. randoffset *= meanhsize; // Rand in range max of (-1/3 to + 1/3 * meanhsize)
  1638. nutime[j] += randoffset; //
  1639. //
  1640. ishead[j] = 0; //
  1641. j++; // Ending at j5 = n2
  1642. } // n0 n1 n2 n3 n4 n5
  1643. nutime[j] = time[n]; // |-|-----------|-|-----------|-|---------
  1644. ishead[j++] = 1; // j0 j1 j2 j3 j4 | |
  1645. nutime[j] = time[n+1]; // j5 j6
  1646. ishead[j++] = 0; // H T T T T H T
  1647. stthsize = endhsize;
  1648. }
  1649. if(n == dz->itemcnt) { // IF end of file is end of a tail
  1650. tailsize = time[n] - time[n-1]; // H T H T End
  1651. meanhsize = stthsize; // | | | | |
  1652. tailsegcnt = (int)round(tailsize/meanhsize); // n-1 n
  1653. meanhsize = tailsize/(double)tailsegcnt; // endhsize |
  1654. for(k=1;k < tailsegcnt;k++) { // j22 j23 | | |
  1655. nutime[j] = time[n-1] + (meanhsize * k); // j24 j25 |
  1656. // <-> <-> |
  1657. randoffset = ((drand48() * 2.0) - 1.0)/3.0; // j26
  1658. randoffset *= DISTMORERAND; // ....... H T T T T
  1659. randoffset *= meanhsize;
  1660. nutime[j] += randoffset;
  1661. ishead[j] = 0;
  1662. j++;
  1663. }
  1664. nutime[j] = time[n];
  1665. }
  1666. dz->itemcnt = j;
  1667. memcpy((char *)time,(char *)nutime,(dz->itemcnt+1) * sizeof(double));
  1668. memset((char *)nutime,0,(dz->itemcnt+1) * sizeof(double)); // Clear, as array is reused for zcros-density vals
  1669. return FINISHED;
  1670. }
  1671. /**************************** CREATE_DISTMORE_SNDBUFS ****************************/
  1672. int create_distmore_sndbufs(dataptr dz)
  1673. {
  1674. int n;
  1675. unsigned int buffersize = 0;
  1676. switch(dz->process) {
  1677. case(DISTBRIGHT):
  1678. dz->bufcnt = 4;
  1679. buffersize = (unsigned int)round((dz->maxstep * 2) * (double)dz->infile->srate);
  1680. break;
  1681. case(DISTDOUBLE):
  1682. dz->bufcnt = 3;
  1683. dz->maxxstep = F_SECSIZE * 64;
  1684. buffersize = dz->maxxstep * 2;
  1685. break;
  1686. case(SEGSBKWD):
  1687. dz->bufcnt = 4;
  1688. if(dz->mode < 2)
  1689. buffersize = (unsigned int)round((dz->maxstep * 2) * (double)dz->infile->srate); // largest seg + overflow
  1690. else
  1691. buffersize = (unsigned int)round((dz->maxstep * (dz->mode+1)) * (double)dz->infile->srate); // largest N segs + overflow
  1692. break;
  1693. case(SEGSZIG):
  1694. if(dz->mode == 0) {
  1695. dz->bufcnt = 5;
  1696. buffersize = (unsigned int)round((dz->maxstep * 2) * (double)dz->infile->srate); // largest seg + overflow
  1697. } else {
  1698. dz->bufcnt = 3;
  1699. buffersize = (unsigned int)(dz->insams[0] + SAFETY); // infile size + overflow
  1700. }
  1701. break;
  1702. }
  1703. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  1704. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  1705. return(MEMORY_ERROR);
  1706. }
  1707. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  1708. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  1709. return(MEMORY_ERROR);
  1710. }
  1711. buffersize = (buffersize/F_SECSIZE + 1) * F_SECSIZE;
  1712. dz->buflen = buffersize;
  1713. if((dz->buflen < 0) || (dz->buflen * dz->bufcnt < 0)) {
  1714. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1715. return(MEMORY_ERROR);
  1716. }
  1717. if((dz->bigfbuf = (float*) malloc(dz->buflen * dz->bufcnt * sizeof(float)))==NULL) {
  1718. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1719. return(MEMORY_ERROR);
  1720. }
  1721. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigfbuf;
  1722. for(n = 1;n < dz->bufcnt;n++)
  1723. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigfbuf + (n * dz->buflen);
  1724. dz->sampbuf[n] = dz->bigfbuf + (n * dz->buflen);
  1725. return(FINISHED);
  1726. }
  1727. /**************************** RECREATE_DISTMORE_SNDBUFS ****************************/
  1728. int recreate_distmore_sndbufs(dataptr dz)
  1729. {
  1730. int n;
  1731. unsigned int buffersize = 0;
  1732. free(dz->bigbuf);
  1733. buffersize = dz->maxxstep * 2;
  1734. buffersize = (buffersize/F_SECSIZE) * F_SECSIZE;
  1735. dz->buflen = buffersize;
  1736. if((dz->buflen < 0) || (dz->buflen * dz->bufcnt < 0)) {
  1737. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1738. return(MEMORY_ERROR);
  1739. }
  1740. if((dz->bigfbuf = (float*) malloc(dz->buflen * dz->bufcnt * sizeof(float)))==NULL) {
  1741. sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
  1742. return(MEMORY_ERROR);
  1743. }
  1744. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigfbuf;
  1745. for(n = 1;n < dz->bufcnt;n++)
  1746. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigfbuf + (n * dz->buflen);
  1747. dz->sampbuf[n] = dz->bigfbuf + (n * dz->buflen);
  1748. return(FINISHED);
  1749. }
  1750. /**************************** DISTDOUBLE ****************************/
  1751. int distdouble(dataptr dz)
  1752. {
  1753. int exit_status;
  1754. int obufpos = 0, wbufpos = 0, n, j, k, lastk = 0, fill, m;
  1755. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1], *wbuf = dz->sampbuf[2];
  1756. int lastphase = 0, phase = 0, zerocross = 0, jj, group = dz->iparam[0];
  1757. if((exit_status = read_samps(ibuf,dz))< 0) {
  1758. sprintf(errstr,"Failed to read data from input file.\n");
  1759. return(SYSTEM_ERROR);
  1760. }
  1761. while(dz->ssampsread > 0) {
  1762. n = 0;
  1763. while(n < dz->ssampsread) {
  1764. if(ibuf[n] > 0.0) {
  1765. phase = 1;
  1766. if(lastphase == 0)
  1767. lastphase = phase;
  1768. } else if(ibuf[n] < 0.0) {
  1769. phase = -1;
  1770. if(lastphase == 0)
  1771. lastphase = phase;
  1772. }
  1773. if((lastphase != 0) && (phase != lastphase)) {
  1774. zerocross++;
  1775. if(zerocross == 2) {
  1776. switch(group) {
  1777. case(2):
  1778. if(EVEN(wbufpos)) {
  1779. for(k=0,j=0;k < wbufpos; k+=2,j++) // Copy every other sample
  1780. wbuf[j] = wbuf[k];
  1781. jj = j;
  1782. for(k=0;k < jj; k++,j++) // Duplicate the copy
  1783. wbuf[j] = wbuf[k];
  1784. } else {
  1785. for(k=0,j=0;k < wbufpos; k+=2,j++) // Copy every other sample
  1786. wbuf[j] = wbuf[k];
  1787. jj = j;
  1788. for(k=1;k < jj; k++,j++) // Duplicate the copy
  1789. wbuf[j] = wbuf[k];
  1790. }
  1791. break;
  1792. default:
  1793. if(wbufpos > dz->iparam[0]) {
  1794. for(k = 0,j= 0; k < wbufpos; k+=group,j++) {
  1795. wbuf[j] = wbuf[k];
  1796. lastk = k;
  1797. }
  1798. if(lastk != wbufpos - 1)
  1799. wbuf[j++] = wbuf[wbufpos - 1];
  1800. jj = j;
  1801. fill = (int)round((double)wbufpos/(double)j);
  1802. for(m=1;m < fill;m++) {
  1803. for(k=0;k < jj; k++,j++) // Duplicate the copy
  1804. wbuf[j] = wbuf[k];
  1805. }
  1806. wbufpos = j; // Truncate output (if ness)
  1807. }
  1808. break;
  1809. }
  1810. for(k=0;k < wbufpos; k++) { // Copy to output buffer
  1811. obuf[obufpos++] = wbuf[k];
  1812. if(obufpos >= dz->buflen) {
  1813. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1814. return(exit_status);
  1815. obufpos = 0;
  1816. }
  1817. }
  1818. memset((char *)wbuf,0,dz->buflen * sizeof(float));
  1819. zerocross = 0;
  1820. wbufpos = 0;
  1821. }
  1822. lastphase = phase;
  1823. }
  1824. wbuf[wbufpos++] = ibuf[n];
  1825. n++;
  1826. }
  1827. if((exit_status = read_samps(ibuf,dz))< 0) {
  1828. sprintf(errstr,"Failed to read data from input file.\n");
  1829. return(SYSTEM_ERROR);
  1830. }
  1831. }
  1832. if(obufpos > 0) {
  1833. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1834. return(exit_status);
  1835. }
  1836. return FINISHED;
  1837. }
  1838. /************************************ SEGSBKWD ************************************/
  1839. int segsbkwd(dataptr dz)
  1840. {
  1841. int exit_status, n, m, forwards, reversals;
  1842. double srate = (double)dz->infile->srate;
  1843. double *time = dz->parray[0];
  1844. int samptime;
  1845. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1], *buf1, *buf2, *bufa = dz->sampbuf[2], *bufb = dz->sampbuf[3], *tempbuf;
  1846. int modd;
  1847. int k, j, z, obufpos, stt, sttsamp, endsamp, sampcnt1, sampcnt2;
  1848. int *sttend = dz->lparray[0];
  1849. int splicelen = (int)round(SSPLICELEN * MS_TO_SECS * srate);
  1850. samptime = 0;
  1851. time[0] = 0.0; // Stretch initial time to start of file
  1852. time[dz->itemcnt] = dz->duration; // Complete times array with the duration of the src
  1853. switch(dz->mode) {
  1854. case(0): // H-> <-T
  1855. case(1): // H<- ->T
  1856. break;
  1857. case(2): // <-- <--
  1858. // H T H T
  1859. for(m=0,n=0;n<=dz->itemcnt;m++,n+=2) // H1 T2 H2 T2 H3 T3 end ~OR~ H1 T1 H2 T2 H3 end
  1860. time[m] = time[n]; // H1 H2 H3 H1 H2 H3
  1861. dz->itemcnt = m-1;
  1862. break;
  1863. default:
  1864. modd = dz->mode; // modulus for selecting times to keep
  1865. if(ODD(dz->mode)) // modulus is 4 for modes 3 and 4 (etc)
  1866. modd++;
  1867. m = 0;
  1868. for(n=0;n<=dz->itemcnt;n++) { // case(3):-> <-------- case(4):<------------
  1869. k = n % modd; // H T H T H T H T
  1870. if(k == 0) // case(5):-> <---------------- case(6) <--------------------
  1871. time[m++] = time[n]; // H T H T H T H T H T H T
  1872. if(ODD(dz->mode) && k == 1) // case(7):-> <------------------------ case(8):<----------------------------
  1873. time[m++] = time[n]; // H T H T H T H T H T H T H T H T
  1874. }
  1875. if(time[m-1] != dz->duration)
  1876. time[m++] = dz->duration;
  1877. dz->itemcnt = m-1;
  1878. break;
  1879. }
  1880. for(n=0,m=0;n < dz->itemcnt;n++,m+=2) {
  1881. sttend[m] = (int)round(time[n] * srate); // sample-starttime of segment
  1882. if(flteq(time[n+1],dz->duration))
  1883. sttend[m+1] = dz->insams[0];
  1884. else { // sample-endtime of segment
  1885. sttend[m+1] = (int)round(time[n+1] * srate); // including splice fade-down time
  1886. sttend[m+1] += splicelen;
  1887. sttend[m+1] = min(sttend[m+1],dz->insams[0]);
  1888. }
  1889. }
  1890. switch(dz->mode) {
  1891. case(0): // FR
  1892. forwards = 1;
  1893. reversals = 1;
  1894. break;
  1895. case(1): // RF
  1896. forwards = 0;
  1897. reversals = 1;
  1898. break;
  1899. default:
  1900. if(EVEN(dz->mode)) {
  1901. forwards = 0; // case(EVEN): RRRR.....
  1902. reversals = 0;
  1903. } else {
  1904. forwards = 1; // case(ODD): FRFR.....
  1905. reversals = 1;
  1906. }
  1907. break;
  1908. }
  1909. // RECONSTRUCT
  1910. buf1 = bufa;
  1911. buf2 = bufb;
  1912. obufpos = 0;
  1913. // Copy initial segment into buffer 1
  1914. stt = 0; // Start and endtimes of segs are in double-length int-array
  1915. sttsamp = sttend[stt];
  1916. endsamp = sttend[stt+1];
  1917. sampcnt1 = endsamp - sttsamp;
  1918. sndseekEx(dz->ifd[0],sttsamp,0);
  1919. if((exit_status = read_samps(ibuf,dz))<0)
  1920. return(exit_status);
  1921. memcpy((char *)buf1,(char *)ibuf,sampcnt1 * sizeof(float)); // Copy src chunk to buf1
  1922. if(!forwards)
  1923. reversebuf(buf1,sampcnt1);
  1924. if(reversals)
  1925. forwards = !forwards;
  1926. for(k = 0; k < splicelen; k++)
  1927. buf1[k] = (float)(buf1[k] * ((double)k/(double)splicelen)); // DO start and end splices
  1928. for(k = 0, j = sampcnt1-1; k < splicelen; k++,j--)
  1929. buf1[j] = (float)(buf1[j] * ((double)k/(double)splicelen));
  1930. // Write the upsplice portion of 1st segment to obuf
  1931. for(m=0; m < splicelen; m++) {
  1932. obuf[obufpos++] = buf1[m];
  1933. //PROBABLY REDUNDANT
  1934. if(obufpos >= dz->buflen) {
  1935. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1936. return(exit_status);
  1937. obufpos = 0;
  1938. }
  1939. }
  1940. // Copy next segment into buffer 2
  1941. for(n=1;n < dz->itemcnt;n++) {
  1942. stt += 2;
  1943. sttsamp = sttend[stt];
  1944. endsamp = sttend[stt+1];
  1945. sampcnt2 = endsamp - sttsamp;
  1946. sndseekEx(dz->ifd[0],sttsamp,0);
  1947. if((exit_status = read_samps(ibuf,dz))<0)
  1948. return(exit_status);
  1949. memcpy((char *)buf2,(char *)ibuf,sampcnt2 * sizeof(float));
  1950. if(!forwards)
  1951. reversebuf(buf2,sampcnt2);
  1952. if(reversals)
  1953. forwards = !forwards;
  1954. for(k = 0; k < splicelen; k++)
  1955. buf2[k] = (float)(buf2[k] * ((double)k/(double)splicelen));
  1956. for(k = 0, j = sampcnt2-1; k < splicelen; k++,j--)
  1957. buf2[j] = (float)(buf2[j] * ((double)k/(double)splicelen));
  1958. // Write buf1 apart from the splice-brackets, to obuf
  1959. for(m=splicelen; m < sampcnt1 - splicelen;m++) {
  1960. obuf[obufpos++] = buf1[m];
  1961. if(obufpos >= dz->buflen) {
  1962. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1963. return(exit_status);
  1964. obufpos = 0;
  1965. }
  1966. }
  1967. // Write the cross-splice
  1968. for(z = 0;z < splicelen; z++,m++) {
  1969. obuf[obufpos++] = (float)(buf1[m] + buf2[z]);
  1970. if(obufpos >= dz->buflen) {
  1971. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1972. return(exit_status);
  1973. obufpos = 0;
  1974. }
  1975. }
  1976. // Swap the buffers, and buffer-data
  1977. tempbuf = buf1;
  1978. buf1 = buf2;
  1979. buf2 = tempbuf;
  1980. sampcnt1 = sampcnt2;
  1981. }
  1982. // Write all of the remaining segment
  1983. for(m=splicelen; m < sampcnt1; m++) {
  1984. obuf[obufpos++] = buf1[m];
  1985. if(obufpos >= dz->buflen) {
  1986. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1987. return(exit_status);
  1988. obufpos = 0;
  1989. }
  1990. }
  1991. // Flush the output buffer
  1992. if(obufpos > 0) {
  1993. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1994. return(exit_status);
  1995. }
  1996. return FINISHED;
  1997. }
  1998. /************************************ REVERSEBUF ************************************/
  1999. void reversebuf(float *buf,int sampcnt)
  2000. {
  2001. int n,m,k;
  2002. float temp;
  2003. k = sampcnt/2; // ODD LEN(eg5) k = 5/2 -> 2 EVEN LEN(eg6) k = 6/2 -> 3
  2004. for(n = 0,m = sampcnt-1;n < k; n++, m--) { // len = 5 k = 2 0 1 2 3 4 len = 6 k = 3 0 1 2 3 4 5
  2005. temp = buf[n]; // |_______| |_________|
  2006. buf[n] = buf[m]; // |___| |_____|
  2007. buf[m] = temp; // n = 0 1 |_|
  2008. } // n = 0 1 2
  2009. }
  2010. /************************************ REVERSEBUF2 ************************************/
  2011. void reversebuf2(float *buf1,float *buf2,int sampcnt)
  2012. {
  2013. int n,m;
  2014. for(n = 0,m = sampcnt-1;n < sampcnt; n++, m--)
  2015. buf2[m] = buf1[n];
  2016. }
  2017. /************************************ SEGSZIG ************************************/
  2018. int segszig(dataptr dz)
  2019. {
  2020. int exit_status, n, m, repets, done;
  2021. double srate = (double)dz->infile->srate, stepratio = 1.0;
  2022. double *time=NULL, thistime = 0.0;
  2023. int step, cutlen;
  2024. float *ibuf = dz->sampbuf[0], *obuf=NULL, *buf1=NULL, *buf2=NULL, *bufr=NULL;
  2025. int k, j, z, obufpos = 0, stt, sttsamp = 0, endsamp = 0, sampcnt1, sampcnt2;
  2026. int *sttend = NULL;
  2027. int splicelen = (int)round(SSPLICELEN * MS_TO_SECS * srate);
  2028. if(dz->mode == 0) {
  2029. bufr = dz->sampbuf[1];
  2030. buf1 = dz->sampbuf[2];
  2031. buf2 = dz->sampbuf[3];
  2032. obuf = dz->sampbuf[4];
  2033. time = dz->parray[0];
  2034. time[0] = 0.0; // Stretch initial time to start of file
  2035. time[dz->itemcnt] = dz->duration; // Complete times array with the duration of the src
  2036. sttend = dz->lparray[0];
  2037. for(n=0,m=0;n < dz->itemcnt;n++,m+=2) {
  2038. sttend[m] = (int)round(time[n] * srate); // sample-starttime of segment
  2039. if(sttend[m] > splicelen)
  2040. sttend[m] -= splicelen;
  2041. if(flteq(time[n+1],dz->duration))
  2042. sttend[m+1] = dz->insams[0];
  2043. else { // sample-endtime of segment
  2044. sttend[m+1] = (int)round(time[n+1] * srate); // including splice fade-down time
  2045. sttend[m+1] += splicelen;
  2046. sttend[m+1] = min(sttend[m+1],dz->insams[0]);
  2047. }
  2048. }
  2049. } else {
  2050. bufr = dz->sampbuf[1];
  2051. obuf = dz->sampbuf[2];
  2052. }
  2053. switch(dz->mode) {
  2054. case(0):
  2055. done = 0;
  2056. n = 0;
  2057. stt = 0; // Start and endtimes of segs are in double-length int-array
  2058. sttsamp = sttend[stt];
  2059. endsamp = sttend[stt+1];
  2060. sampcnt1 = endsamp - sttsamp;
  2061. sndseekEx(dz->ifd[0],sttsamp,0);
  2062. if((exit_status = read_samps(ibuf,dz))<0)
  2063. return(exit_status);
  2064. // Read 1st Head (or whole file) and splice ends
  2065. memcpy((char *)buf1,(char *)ibuf,sampcnt1 * sizeof(float)); // Copy src chunk to buf1
  2066. for(k = 0; k < splicelen; k++)
  2067. buf1[k] = (float)(buf1[k] * ((double)k/(double)splicelen)); // DO start and end splices
  2068. for(k = 0, j = sampcnt1-1; k < splicelen; k++,j--)
  2069. buf1[j] = (float)(buf1[j] * ((double)k/(double)splicelen));
  2070. // Write the upsplice portion of 1st segment to obuf
  2071. for(m=0; m < splicelen; m++) {
  2072. obuf[obufpos++] = buf1[m];
  2073. if(obufpos >= dz->buflen) {
  2074. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2075. return(exit_status);
  2076. obufpos = 0;
  2077. }
  2078. }
  2079. n++;
  2080. while(n < dz->itemcnt) {
  2081. thistime = time[n];
  2082. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  2083. return exit_status;
  2084. stt += 2;
  2085. sttsamp = sttend[stt];
  2086. endsamp = sttend[stt+1];
  2087. sampcnt2 = endsamp - sttsamp;
  2088. sndseekEx(dz->ifd[0],sttsamp,0);
  2089. if(dz->param[ZFRAC] < 1.0)
  2090. sampcnt2 = (int)ceil((double)sampcnt2 * dz->param[ZFRAC]);
  2091. if(dz->vflag[0])
  2092. stepratio = 1.0;
  2093. step = 0;
  2094. // If the zigzag is to repeat (dz->iparam[ZREPETS] > 1) then it must shrink
  2095. // If shrink MINSIZ IS set as 0, this flags NO shrinkage
  2096. // If shrink MINSIZ <= size of segment, shrinkage is impossible
  2097. if (dz->iparam[ZREPETS] > 1 && (dz->iparam[ZMINSIZ] > 0) && (dz->iparam[ZMINSIZ] <= sampcnt2)) { //RWD added braces, hope this is what is intended!
  2098. if(dz->vflag[0]) {
  2099. stepratio = 1.0/(pow(((double)sampcnt2/(double)dz->iparam[ZMINSIZ]),(1.0/((double)dz->iparam[ZREPETS] * 2.0))));
  2100. step = 1;
  2101. } else {
  2102. step = (int)floor((double)(sampcnt2 - dz->iparam[ZMINSIZ])/((double)dz->iparam[ZREPETS] * 2.0));
  2103. }
  2104. }
  2105. // Copy Tail segment into buffer 2 and splice ends
  2106. if((exit_status = read_samps(ibuf,dz))<0)
  2107. return(exit_status);
  2108. memcpy((char *)buf2,(char *)ibuf,sampcnt2 * sizeof(float));
  2109. for(k = 0; k < splicelen; k++)
  2110. buf2[k] = (float)(buf2[k] * ((double)k/(double)splicelen));
  2111. for(k = 0, j = sampcnt2-1; k < splicelen; k++,j--)
  2112. buf2[j] = (float)(buf2[j] * ((double)k/(double)splicelen));
  2113. // Copy Reversed Tailsegment into buffer r
  2114. reversebuf2(buf2,bufr,sampcnt2);
  2115. // Write buf1 (Head) apart from the splice-brackets, to obuf
  2116. for(m=splicelen; m < sampcnt1 - splicelen;m++) {
  2117. obuf[obufpos++] = buf1[m];
  2118. if(obufpos >= dz->buflen) {
  2119. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2120. return(exit_status);
  2121. obufpos = 0;
  2122. }
  2123. }
  2124. // Write the cross-splice from Head to Tail
  2125. for(z = 0;z < splicelen; z++,m++) {
  2126. obuf[obufpos++] = (float)(buf1[m] + buf2[z]);
  2127. if(obufpos >= dz->buflen) {
  2128. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2129. return(exit_status);
  2130. obufpos = 0;
  2131. }
  2132. }
  2133. repets = 0;
  2134. while(repets < dz->iparam[ZREPETS]) {
  2135. // Write buf2 apart from the splice-brackets, to obuf
  2136. for(m=splicelen; m < sampcnt2 - splicelen;m++) {
  2137. obuf[obufpos++] = buf2[m];
  2138. if(obufpos >= dz->buflen) {
  2139. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2140. return(exit_status);
  2141. obufpos = 0;
  2142. }
  2143. }
  2144. // Write the cross-splice to the reversed version
  2145. if(step > 0) {
  2146. reversebuf2(buf2,bufr,sampcnt2);// Get the reversed version from the possibly shortened normal version
  2147. if(dz->vflag[0])
  2148. cutlen = (int)ceil((double)sampcnt2 * stepratio);
  2149. else
  2150. cutlen = sampcnt2 - step; // Cut short the reversed version
  2151. cutend_and_splicend(bufr,cutlen,sampcnt2,splicelen);
  2152. sampcnt2 = cutlen;
  2153. }
  2154. for(z = 0;z < splicelen; z++,m++) {
  2155. obuf[obufpos++] = (float)(buf2[m] + bufr[z]);
  2156. if(obufpos >= dz->buflen) {
  2157. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2158. return(exit_status);
  2159. obufpos = 0;
  2160. }
  2161. }
  2162. // Write bufr (reversed version) apart from the splice-brackets, to obuf
  2163. for(m=splicelen; m < sampcnt2 - splicelen;m++) {
  2164. obuf[obufpos++] = bufr[m];
  2165. if(obufpos >= dz->buflen) {
  2166. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2167. return(exit_status);
  2168. obufpos = 0;
  2169. }
  2170. }
  2171. repets++;
  2172. if(repets < dz->iparam[ZREPETS]) {
  2173. // Write the cross-splice FROM the reversed version to the forward version
  2174. if(step > 0) {
  2175. reversebuf2(bufr,buf2,sampcnt2); // Get the forwards version from the shortened reversed version
  2176. if(dz->vflag[0])
  2177. cutlen = (int)ceil((double)sampcnt2 * stepratio);
  2178. else
  2179. cutlen = sampcnt2 - step; // Cut it short
  2180. cutend_and_splicend(buf2,cutlen,sampcnt2,splicelen);
  2181. sampcnt2 = cutlen;
  2182. }
  2183. for(z = 0;z < splicelen; z++,m++) {
  2184. obuf[obufpos++] = (float)(bufr[m] + buf2[z]);
  2185. if(obufpos >= dz->buflen) {
  2186. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2187. return(exit_status);
  2188. obufpos = 0;
  2189. }
  2190. }
  2191. }
  2192. }
  2193. n++;
  2194. if(n >= dz->itemcnt) {
  2195. // If no more Heads: Write remainder of reversed version to output and quit
  2196. while(m < sampcnt2) {
  2197. obuf[obufpos++] = bufr[m++];
  2198. if(obufpos >= dz->buflen) {
  2199. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2200. return(exit_status);
  2201. obufpos = 0;
  2202. }
  2203. }
  2204. done = 1;
  2205. break;
  2206. }
  2207. stt += 2;
  2208. sttsamp = sttend[stt];
  2209. endsamp = sttend[stt+1];
  2210. sampcnt1 = endsamp - sttsamp;
  2211. sndseekEx(dz->ifd[0],sttsamp,0);
  2212. // Read Next Head, and splice ends
  2213. if((exit_status = read_samps(ibuf,dz))<0)
  2214. return(exit_status);
  2215. memcpy((char *)buf1,(char *)ibuf,sampcnt1 * sizeof(float));
  2216. for(k = 0; k < splicelen; k++)
  2217. buf1[k] = (float)(buf1[k] * ((double)k/(double)splicelen));
  2218. for(k = 0, j = sampcnt1-1; k < splicelen; k++,j--)
  2219. buf1[j] = (float)(buf1[j] * ((double)k/(double)splicelen));
  2220. // Write the cross-splice FROM the reversed version to the Head
  2221. for(z = 0;z < splicelen; z++,m++) {
  2222. obuf[obufpos++] = (float)(bufr[m] + buf1[z]);
  2223. if(obufpos >= dz->buflen) {
  2224. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2225. return(exit_status);
  2226. obufpos = 0;
  2227. }
  2228. }
  2229. n++;
  2230. }
  2231. if(!done) { // Can only be "done" if ended on a Tail
  2232. // If not done, Write remainder of (FINAL) head to output
  2233. for(m=splicelen; m < sampcnt1;m++) {
  2234. obuf[obufpos++] = buf1[m];
  2235. if(obufpos >= dz->buflen) {
  2236. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2237. return(exit_status);
  2238. obufpos = 0;
  2239. }
  2240. }
  2241. }
  2242. break;
  2243. case(1):
  2244. case(2):
  2245. sampcnt1 = dz->insams[0];
  2246. if(dz->param[ZFRAC] < 1.0)
  2247. sampcnt1 = (int)round(sampcnt1 * dz->param[ZFRAC]);
  2248. step = 0;
  2249. if(dz->mode == 2 || dz->vflag[0])
  2250. stepratio = 1.0;
  2251. if (dz->iparam[ZREPETS] > 1 && (dz->iparam[ZMINSIZ] > 0) && (dz->iparam[ZMINSIZ] <= sampcnt1)) {
  2252. if(dz->mode ==1) {
  2253. if(dz->vflag[0]) {
  2254. stepratio = 1.0/(pow(((double)sampcnt1/(double)dz->iparam[ZMINSIZ]),(1.0/((double)dz->iparam[ZREPETS] * 2.0))));
  2255. step = 1;
  2256. } else
  2257. step = (int)floor((double)(sampcnt1 - dz->iparam[ZMINSIZ])/((double)dz->iparam[ZREPETS] * 2.0));
  2258. } else {
  2259. stepratio = getstepratio(dz);
  2260. step = 1;
  2261. }
  2262. }
  2263. // Write buf1 (forwards) apart from the endsplice-len, to obuf
  2264. if((exit_status = read_samps(ibuf,dz))<0)
  2265. return(exit_status);
  2266. if(dz->param[ZFRAC] < 1.0) {
  2267. for(k = 0,j = sampcnt1 - 1;k < splicelen; k++,j--)
  2268. ibuf[j] = (float)(ibuf[j] * ((double)k/(double)splicelen));
  2269. }
  2270. for(m=0; m < sampcnt1 - splicelen;m++) {
  2271. obuf[obufpos++] = ibuf[m];
  2272. if(obufpos >= dz->buflen) {
  2273. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2274. return(exit_status);
  2275. obufpos = 0;
  2276. }
  2277. }
  2278. // Copy segment (reversing it) into buffer r
  2279. reversebuf2(ibuf,bufr,sampcnt1);
  2280. if(step > 0) {
  2281. if(dz->mode == 2 || dz->vflag[0]) {
  2282. cutlen = (int)ceil((double)sampcnt1 * stepratio);
  2283. cutlen += splicelen;
  2284. if(cutlen > dz->insams[0])
  2285. cutlen = dz->insams[0];
  2286. } else
  2287. cutlen = sampcnt1 - step; // Cut short the reversed version if ness
  2288. cutend_and_splicend(bufr,cutlen,sampcnt1,splicelen); // and splice the end
  2289. sampcnt1 = cutlen;
  2290. }
  2291. // Write the cross-splice from Forwards to Reverse
  2292. for(z = 0;z < splicelen; z++,m++) {
  2293. obuf[obufpos++] = (float)(ibuf[m] + bufr[z]);
  2294. if(obufpos >= dz->buflen) {
  2295. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2296. return(exit_status);
  2297. obufpos = 0;
  2298. }
  2299. }
  2300. // Write the body of the Reverse file
  2301. for(m=splicelen; m < sampcnt1 - splicelen;m++) {
  2302. obuf[obufpos++] = bufr[m];
  2303. if(obufpos >= dz->buflen) {
  2304. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2305. return(exit_status);
  2306. obufpos = 0;
  2307. }
  2308. }
  2309. repets = 1;
  2310. while(repets < dz->iparam[ZREPETS]) {
  2311. // Copy reversed segment (possibly shortened) (righting it) into buffer 1
  2312. reversebuf2(bufr,ibuf,sampcnt1);
  2313. if(step > 0) {
  2314. if(dz->mode == 2 || dz->vflag[0]) {
  2315. sampcnt1 -= splicelen;
  2316. cutlen = (int)ceil((double)sampcnt1 * stepratio);
  2317. cutlen += splicelen;
  2318. if(cutlen > dz->insams[0])
  2319. cutlen = dz->insams[0];
  2320. } else
  2321. cutlen = sampcnt1 - step; // Cut short the righted version
  2322. cutend_and_splicend(ibuf,cutlen,sampcnt1,splicelen);
  2323. sampcnt1 = cutlen;
  2324. }
  2325. // Write the cross-splice to the righted version
  2326. for(z = 0;z < splicelen; z++,m++) {
  2327. obuf[obufpos++] = (float)(bufr[m] + ibuf[z]);
  2328. if(obufpos >= dz->buflen) {
  2329. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2330. return(exit_status);
  2331. obufpos = 0;
  2332. }
  2333. }
  2334. // Write the body of the Righted file
  2335. for(m=splicelen; m < sampcnt1 - splicelen;m++) {
  2336. obuf[obufpos++] = ibuf[m];
  2337. if(obufpos >= dz->buflen) {
  2338. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2339. return(exit_status);
  2340. obufpos = 0;
  2341. }
  2342. }
  2343. // Copy righted segment (possibly shortened) (reversing it) into buffer r
  2344. reversebuf2(ibuf,bufr,sampcnt1);
  2345. if(step > 0) {
  2346. if(dz->mode == 2 || dz->vflag[0]) {
  2347. sampcnt1 -= splicelen;
  2348. cutlen = (int)ceil((double)sampcnt1 * stepratio);
  2349. cutlen += splicelen;
  2350. if(cutlen > dz->insams[0])
  2351. cutlen = dz->insams[0];
  2352. } else
  2353. cutlen = sampcnt1 - step; // Cut short the reversed version
  2354. cutend_and_splicend(bufr,cutlen,sampcnt1,splicelen);
  2355. sampcnt1 = cutlen;
  2356. }
  2357. // Write the cross-splice to the reversed version
  2358. for(z = 0;z < splicelen; z++,m++) {
  2359. obuf[obufpos++] = (float)(ibuf[m] + bufr[z]);
  2360. if(obufpos >= dz->buflen) {
  2361. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2362. return(exit_status);
  2363. obufpos = 0;
  2364. }
  2365. }
  2366. // Write the body of the Reversed file
  2367. for(m=splicelen; m < sampcnt1 - splicelen;m++) {
  2368. obuf[obufpos++] = bufr[m];
  2369. if(obufpos >= dz->buflen) {
  2370. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2371. return(exit_status);
  2372. obufpos = 0;
  2373. }
  2374. }
  2375. repets++;
  2376. }
  2377. // Write the remainder of the last reversed file
  2378. while(m < sampcnt1) {
  2379. obuf[obufpos++] = bufr[m++];
  2380. if(obufpos >= dz->buflen) {
  2381. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2382. return(exit_status);
  2383. obufpos = 0;
  2384. }
  2385. }
  2386. break;
  2387. }
  2388. // Flush the output buffer
  2389. if(obufpos > 0) {
  2390. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  2391. return(exit_status);
  2392. }
  2393. return FINISHED;
  2394. }
  2395. /************************************ CUTEND_AND_SPLICEND ************************************/
  2396. void cutend_and_splicend(float *buf,int cutlen,int sampcnt,int splicelen)
  2397. {
  2398. int k, j;
  2399. for(k = 0,j=cutlen-1;k < splicelen;k++,j--)
  2400. buf[j] = (float)(buf[j] * ((double)k/(double)splicelen));
  2401. for(j=cutlen;j < sampcnt;j++)
  2402. buf[j] = 0.0;
  2403. }
  2404. /******************************** GETSTEPRATIO **********************
  2405. *
  2406. * Start length A: endlen B
  2407. * If k = 2 * repets (counts every zig and zag), and "r" = stepratio
  2408. * Outsamps = A + (A*r) + (A*r*r) + (A*r*r*r) ....+ B
  2409. * 0 1 2 (k-1)
  2410. * = Ar + Ar + Ar + ....Ar + B
  2411. */
  2412. double getstepratio(dataptr dz)
  2413. {
  2414. int n, k = dz->iparam[ZREPETS] * 2, increasing, decreasing;
  2415. double splicedur = SSPLICELEN * MS_TO_SECS;
  2416. double r, outlen, outlenbas = dz->param[ZMINSIZ] * MS_TO_SECS;
  2417. double miss, lastmiss, flterr = FLTERR, duration;
  2418. duration = dz->duration;
  2419. duration *= dz->param[ZFRAC];
  2420. while(duration + (outlenbas * (k-1)) >= dz->param[ZDUR]) { // If required output dur too SHORT for no of repets
  2421. if(k == 2) { // reduce number of repets
  2422. r = duration/(dz->param[ZDUR] + splicedur);
  2423. dz->iparam[ZREPETS] = k/2;
  2424. return r;
  2425. }
  2426. k -= 2;
  2427. }
  2428. outlen = -1;
  2429. while(outlen <= dz->param[ZDUR]) { // If required output dur too long for no of repets
  2430. outlen = outlenbas; // increase number of repets
  2431. for(n = 0; n < k-1; n++)
  2432. outlen += duration;
  2433. if(outlen < dz->param[ZDUR] * 2.0) // i.e. start with an overshoot estimate, to shrink from
  2434. k += 2;
  2435. }
  2436. r = pow((outlenbas/duration),(1.0/(double)(k-1)));
  2437. outlen = -1.0;
  2438. lastmiss = HUGE;
  2439. increasing = 0;
  2440. decreasing = 0;
  2441. // Find the number of repetitions which gives a ratio approaching closest to min value
  2442. for(;;) {
  2443. r = pow((outlenbas/duration),(1.0/(double)(k-1)));
  2444. outlen = outlenbas;
  2445. for(n = 0; n < k-1; n++) // 2 3 (k-1)
  2446. outlen += duration * pow(r,n); // dur(1) + dur*r + dur*r + dur*r .... +dur*r
  2447. miss = fabs(outlen - dz->param[ZDUR]);
  2448. if(miss < lastmiss) {
  2449. if(decreasing)
  2450. break;
  2451. k++;
  2452. increasing = 1;
  2453. } else {
  2454. if(increasing)
  2455. break;
  2456. k--;
  2457. decreasing = 1;
  2458. }
  2459. lastmiss = miss;
  2460. }
  2461. k--;
  2462. r = pow((outlenbas/duration),(1.0/(double)(k-1)));
  2463. if(outlen > dz->param[ZDUR])
  2464. increasing = 0;
  2465. else
  2466. increasing = 1;
  2467. // Hone ratio to give exaxct output duration
  2468. while(!flteq(outlen,dz->param[ZDUR])) {
  2469. if(outlen > dz->param[ZDUR]) {
  2470. if(increasing) // i.e. outlen increasing but now too big
  2471. flterr /= 2.0; // Start to step down, by smaller steps
  2472. r -= flterr;
  2473. increasing = 0;
  2474. } else {
  2475. if(!increasing) // i.e. outlen decreasing but now too small
  2476. flterr /= 2.0; // Start to step up, by smaller steps
  2477. r += flterr;
  2478. increasing = 1;
  2479. }
  2480. outlen = outlenbas;
  2481. for(n = 0; n < k-1; n++) // 2 3 (k-1)
  2482. outlen += duration * pow(r,n); // dur(1) + dur*r + dur*r + dur*r .... +dur*r
  2483. }
  2484. dz->iparam[ZREPETS] = k/2;
  2485. return r;
  2486. }