distmark.c 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <structures.h>
  24. #include <tkglobals.h>
  25. #include <pnames.h>
  26. #include <filetype.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <logic.h>
  30. #include <globcon.h>
  31. #include <cdpmain.h>
  32. #include <math.h>
  33. #include <mixxcon.h>
  34. #include <osbind.h>
  35. #include <standalone.h>
  36. #include <ctype.h>
  37. #include <sfsys.h>
  38. #include <string.h>
  39. #include <srates.h>
  40. #ifdef unix
  41. #define round(x) lround((x))
  42. #endif
  43. #ifndef HUGE
  44. #define HUGE 3.40282347e+38F
  45. #endif
  46. #define minstep scalefact
  47. #define stepstorecnt rampbrksize
  48. #define maxstep is_sharp
  49. char errstr[2400];
  50. int anal_infiles = 1;
  51. int sloom = 0;
  52. int sloombatch = 0;
  53. #define DMARK_CNT 0
  54. #define DMARK_STR 1
  55. #define DMARK_RND 2
  56. #define DMARK_GAIN 3
  57. #define DMARK_FLIP 0
  58. #define DMARK_TAIL 1
  59. #define SAFETY 16
  60. const char* cdp_version = "6.1.0";
  61. //CDP LIB REPLACEMENTS
  62. static int check_distmark_param_validity_and_consistency(dataptr dz);
  63. static int setup_distmark_application(dataptr dz);
  64. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  65. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  66. static int setup_distmark_param_ranges_and_defaults(dataptr dz);
  67. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  68. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  69. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  70. static int establish_application(dataptr dz);
  71. static int initialise_vflags(dataptr dz);
  72. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  73. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  74. static int mark_parameter_types(dataptr dz,aplptr ap);
  75. static int assign_file_data_storage(int infilecnt,dataptr dz);
  76. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  77. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  78. //static int get_the_mode_from_cmdline(char *str,dataptr dz);
  79. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  80. static int create_distmark_sndbufs(dataptr dz);
  81. static int create_distmark_sndbufs2(dataptr dz);
  82. static int preprocess_distmark(dataptr dz);
  83. static int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz);
  84. static int read_mark_data(char *filename,dataptr dz);
  85. static int get_timeinterpcnt(int lastgplen,int gplen,int markstep,double time,dataptr dz);
  86. static int distmark(dataptr dz);
  87. static int distmark2(dataptr dz);
  88. static int get_the_mode_no(char *str, dataptr dz);
  89. /**************************************** MAIN *********************************************/
  90. int main(int argc,char *argv[])
  91. {
  92. int exit_status;
  93. dataptr dz = NULL;
  94. char **cmdline;
  95. int cmdlinecnt;
  96. int n;
  97. aplptr ap;
  98. int is_launched = FALSE;
  99. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  100. fprintf(stdout,"%s\n",cdp_version);
  101. fflush(stdout);
  102. return 0;
  103. }
  104. /* CHECK FOR SOUNDLOOM */
  105. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  106. sloom = 0;
  107. sloombatch = 1;
  108. }
  109. if(sflinit("cdp")){
  110. sfperror("cdp: initialisation\n");
  111. return(FAILED);
  112. }
  113. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  114. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  115. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  116. return(FAILED);
  117. }
  118. if(!sloom) {
  119. if(argc == 1) {
  120. usage1();
  121. return(FAILED);
  122. } else if(argc == 2) {
  123. usage2(argv[1]);
  124. return(FAILED);
  125. }
  126. }
  127. if(!sloom) {
  128. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  129. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  130. return(FAILED);
  131. }
  132. cmdline = argv;
  133. cmdlinecnt = argc;
  134. if((get_the_process_no(argv[0],dz))<0)
  135. return(FAILED);
  136. cmdline++;
  137. cmdlinecnt--;
  138. dz->maxmode = 2;
  139. if(cmdlinecnt <= 0) {
  140. sprintf(errstr,"Too few commandline parameters.\n");
  141. return(FAILED);
  142. }
  143. if((get_the_mode_no(cmdline[0],dz))<0)
  144. return(FAILED);
  145. cmdline++;
  146. cmdlinecnt--;
  147. // setup_particular_application =
  148. if((exit_status = setup_distmark_application(dz))<0) {
  149. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  150. return(FAILED);
  151. }
  152. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  153. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  154. return(FAILED);
  155. }
  156. } else {
  157. //parse_TK_data() =
  158. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  159. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  160. return(exit_status);
  161. }
  162. }
  163. ap = dz->application;
  164. // parse_infile_and_hone_type() =
  165. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  166. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  167. return(FAILED);
  168. }
  169. // setup_param_ranges_and_defaults() =
  170. if((exit_status = setup_distmark_param_ranges_and_defaults(dz))<0) {
  171. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  172. return(FAILED);
  173. }
  174. // open_first_infile CDP LIB
  175. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  176. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  177. return(FAILED);
  178. }
  179. cmdlinecnt--;
  180. cmdline++;
  181. // handle_extra_infiles() : redundant
  182. // handle_outfile() =
  183. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  184. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  185. return(FAILED);
  186. }
  187. // handle_formants() redundant
  188. // handle_formant_quiksearch() redundant
  189. // handle_special_data ............
  190. if((exit_status = handle_the_special_data(&cmdlinecnt,&cmdline,dz))<0) {
  191. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  192. return(FAILED);
  193. }
  194. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  195. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  196. return(FAILED);
  197. }
  198. // check_param_validity_and_consistency .......
  199. if((exit_status = check_distmark_param_validity_and_consistency(dz))<0) {
  200. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  201. return(FAILED);
  202. }
  203. is_launched = TRUE;
  204. dz->bufcnt = 7;
  205. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  206. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  207. return(MEMORY_ERROR);
  208. }
  209. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  210. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  211. return(MEMORY_ERROR);
  212. }
  213. for(n = 0;n <dz->bufcnt; n++)
  214. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  215. dz->sampbuf[n] = (float *)0;
  216. if((exit_status = create_distmark_sndbufs(dz))<0) {
  217. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  218. return(FAILED);
  219. }
  220. //param_preprocess ......
  221. if((exit_status = preprocess_distmark(dz))<0) {
  222. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  223. return(FAILED);
  224. }
  225. if((exit_status = create_distmark_sndbufs2(dz))<0) {
  226. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  227. return(FAILED);
  228. }
  229. switch(dz->mode) {
  230. case(0):
  231. if((exit_status = distmark(dz))<0) {
  232. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  233. return(FAILED);
  234. }
  235. break;
  236. case(1):
  237. if((exit_status = distmark2(dz))<0) {
  238. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  239. return(FAILED);
  240. }
  241. break;
  242. }
  243. if((exit_status = complete_output(dz))<0) { // CDP LIB
  244. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  245. return(FAILED);
  246. }
  247. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  248. free(dz);
  249. return(SUCCEEDED);
  250. }
  251. /**********************************************
  252. REPLACED CDP LIB FUNCTIONS
  253. **********************************************/
  254. /****************************** SET_PARAM_DATA *********************************/
  255. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  256. {
  257. ap->special_data = (char)special_data;
  258. ap->param_cnt = (char)paramcnt;
  259. ap->max_param_cnt = (char)maxparamcnt;
  260. if(ap->max_param_cnt>0) {
  261. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  262. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  263. return(MEMORY_ERROR);
  264. }
  265. strcpy(ap->param_list,paramlist);
  266. }
  267. return(FINISHED);
  268. }
  269. /****************************** SET_VFLGS *********************************/
  270. int set_vflgs
  271. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  272. {
  273. ap->option_cnt = (char) optcnt; /*RWD added cast */
  274. if(optcnt) {
  275. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  276. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  277. return(MEMORY_ERROR);
  278. }
  279. strcpy(ap->option_list,optlist);
  280. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  281. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  282. return(MEMORY_ERROR);
  283. }
  284. strcpy(ap->option_flags,optflags);
  285. }
  286. ap->vflag_cnt = (char) vflagcnt;
  287. ap->variant_param_cnt = (char) vparamcnt;
  288. if(vflagcnt) {
  289. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  290. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  291. return(MEMORY_ERROR);
  292. }
  293. strcpy(ap->variant_list,varlist);
  294. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  295. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  296. return(MEMORY_ERROR);
  297. }
  298. strcpy(ap->variant_flags,varflags);
  299. }
  300. return(FINISHED);
  301. }
  302. /***************************** APPLICATION_INIT **************************/
  303. int application_init(dataptr dz)
  304. {
  305. int exit_status;
  306. int storage_cnt;
  307. int tipc, brkcnt;
  308. aplptr ap = dz->application;
  309. if(ap->vflag_cnt>0)
  310. initialise_vflags(dz);
  311. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  312. ap->total_input_param_cnt = (char)tipc;
  313. if(tipc>0) {
  314. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  315. return(exit_status);
  316. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  317. return(exit_status);
  318. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  319. return(exit_status);
  320. }
  321. brkcnt = tipc;
  322. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  323. if(brkcnt>0) {
  324. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  325. return(exit_status);
  326. }
  327. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  328. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  329. return(exit_status);
  330. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  331. return(exit_status);
  332. }
  333. if((exit_status = mark_parameter_types(dz,ap))<0)
  334. return(exit_status);
  335. // establish_infile_constants() replaced by
  336. dz->infilecnt = 1;
  337. //establish_bufptrs_and_extra_buffers():
  338. return(FINISHED);
  339. }
  340. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  341. /* RWD mallo changed to calloc; helps debug verison run as release! */
  342. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  343. {
  344. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  345. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  346. return(MEMORY_ERROR);
  347. }
  348. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  349. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  350. return(MEMORY_ERROR);
  351. }
  352. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  353. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  354. return(MEMORY_ERROR);
  355. }
  356. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  357. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  358. return(MEMORY_ERROR);
  359. }
  360. return(FINISHED);
  361. }
  362. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  363. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  364. {
  365. int n;
  366. for(n=0;n<storage_cnt;n++) {
  367. dz->is_int[n] = (char)0;
  368. dz->no_brk[n] = (char)0;
  369. }
  370. return(FINISHED);
  371. }
  372. /***************************** MARK_PARAMETER_TYPES **************************/
  373. int mark_parameter_types(dataptr dz,aplptr ap)
  374. {
  375. int n, m; /* PARAMS */
  376. for(n=0;n<ap->max_param_cnt;n++) {
  377. switch(ap->param_list[n]) {
  378. case('0'): break; /* dz->is_active[n] = 0 is default */
  379. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  380. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  381. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  382. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  383. default:
  384. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  385. return(PROGRAM_ERROR);
  386. }
  387. } /* OPTIONS */
  388. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  389. switch(ap->option_list[n]) {
  390. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  391. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  392. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  393. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  394. default:
  395. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  396. return(PROGRAM_ERROR);
  397. }
  398. } /* VARIANTS */
  399. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  400. switch(ap->variant_list[n]) {
  401. case('0'): break;
  402. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  403. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  404. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  405. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  406. default:
  407. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  408. return(PROGRAM_ERROR);
  409. }
  410. } /* INTERNAL */
  411. for(n=0,
  412. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  413. switch(ap->internal_param_list[n]) {
  414. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  415. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  416. case('d'): dz->no_brk[m] = (char)1; break;
  417. default:
  418. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  419. return(PROGRAM_ERROR);
  420. }
  421. }
  422. return(FINISHED);
  423. }
  424. /************************ HANDLE_THE_OUTFILE *********************/
  425. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  426. {
  427. int exit_status;
  428. char *filename = (*cmdline)[0];
  429. if(filename[0]=='-' && filename[1]=='f') {
  430. dz->floatsam_output = 1;
  431. dz->true_outfile_stype = SAMP_FLOAT;
  432. filename+= 2;
  433. }
  434. if(!sloom) {
  435. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  436. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  437. return(DATA_ERROR);
  438. }
  439. }
  440. strcpy(dz->outfilename,filename);
  441. if((exit_status = create_sized_outfile(filename,dz))<0)
  442. return(exit_status);
  443. (*cmdline)++;
  444. (*cmdlinecnt)--;
  445. return(FINISHED);
  446. }
  447. /***************************** ESTABLISH_APPLICATION **************************/
  448. int establish_application(dataptr dz)
  449. {
  450. aplptr ap;
  451. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  452. sprintf(errstr,"establish_application()\n");
  453. return(MEMORY_ERROR);
  454. }
  455. ap = dz->application;
  456. memset((char *)ap,0,sizeof(struct applic));
  457. return(FINISHED);
  458. }
  459. /************************* INITIALISE_VFLAGS *************************/
  460. int initialise_vflags(dataptr dz)
  461. {
  462. int n;
  463. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  464. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  465. return(MEMORY_ERROR);
  466. }
  467. for(n=0;n<dz->application->vflag_cnt;n++)
  468. dz->vflag[n] = FALSE;
  469. return FINISHED;
  470. }
  471. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  472. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  473. {
  474. int n;
  475. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  476. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  477. return(MEMORY_ERROR);
  478. }
  479. for(n=0;n<tipc;n++)
  480. ap->default_val[n] = 0.0;
  481. return(FINISHED);
  482. }
  483. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  484. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  485. {
  486. int n;
  487. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  488. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  489. return(MEMORY_ERROR);
  490. }
  491. for(n=0;n<tipc;n++)
  492. dz->is_active[n] = (char)0;
  493. return(FINISHED);
  494. }
  495. /************************* SETUP_DISTMARK_APPLICATION *******************/
  496. int setup_distmark_application(dataptr dz)
  497. {
  498. int exit_status;
  499. aplptr ap;
  500. if((exit_status = establish_application(dz))<0) // GLOBAL
  501. return(FAILED);
  502. ap = dz->application;
  503. // SEE parstruct FOR EXPLANATION of next 2 functions
  504. if((exit_status = set_param_data(ap,MARKLIST ,1,1,"D"))<0)
  505. return(FAILED);
  506. switch(dz->mode) {
  507. case(0): exit_status = set_vflgs(ap,"sr",2,"DD","ft",2,0,"00"); break;
  508. case(1): exit_status = set_vflgs(ap,"srg",3,"DDD","fa" ,2,0,"00"); break;
  509. }
  510. // set_legal_infile_structure -->
  511. if(exit_status <0)
  512. return(FAILED);
  513. dz->has_otherfile = FALSE;
  514. // assign_process_logic -->
  515. dz->input_data_type = SNDFILES_ONLY;
  516. dz->process_type = UNEQUAL_SNDFILE;
  517. dz->outfiletype = SNDFILE_OUT;
  518. return application_init(dz); //GLOBAL
  519. }
  520. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  521. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  522. {
  523. int exit_status;
  524. infileptr infile_info;
  525. if(!sloom) {
  526. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  527. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  528. return(MEMORY_ERROR);
  529. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  530. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  531. return(PROGRAM_ERROR);
  532. } else if(infile_info->filetype != SNDFILE) {
  533. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  534. return(DATA_ERROR);
  535. } else if(infile_info->channels != 1) {
  536. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  537. return(DATA_ERROR);
  538. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  539. sprintf(errstr,"Failed to copy file parsing information\n");
  540. return(PROGRAM_ERROR);
  541. }
  542. free(infile_info);
  543. }
  544. return(FINISHED);
  545. }
  546. /************************* SETUP_DISTMARK_PARAM_RANGES_AND_DEFAULTS *******************/
  547. int setup_distmark_param_ranges_and_defaults(dataptr dz)
  548. {
  549. int exit_status;
  550. aplptr ap = dz->application;
  551. // set_param_ranges()
  552. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  553. // NB total_input_param_cnt is > 0 !!!
  554. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  555. return(FAILED);
  556. // get_param_ranges()
  557. ap->lo[DMARK_CNT] = .5;
  558. ap->hi[DMARK_CNT] = 1000;
  559. ap->default_val[DMARK_CNT] = 5;
  560. ap->lo[DMARK_STR] = 1;
  561. ap->hi[DMARK_STR] = 256;
  562. ap->default_val[DMARK_STR] = 1;
  563. ap->lo[DMARK_RND] = 0;
  564. ap->hi[DMARK_RND] = 1;
  565. ap->default_val[DMARK_RND] = 0;
  566. if(dz->mode == 1) {
  567. ap->lo[DMARK_GAIN] = 0.0;
  568. ap->hi[DMARK_GAIN] = 1.0;
  569. ap->default_val[DMARK_GAIN] = 1.0;
  570. }
  571. dz->maxmode = 2;
  572. if(!sloom)
  573. put_default_vals_in_all_params(dz);
  574. return(FINISHED);
  575. }
  576. /********************************* PARSE_SLOOM_DATA *********************************/
  577. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  578. {
  579. int exit_status;
  580. int cnt = 1, infilecnt;
  581. int filesize, insams, inbrksize;
  582. double dummy;
  583. int true_cnt = 0;
  584. aplptr ap;
  585. while(cnt<=PRE_CMDLINE_DATACNT) {
  586. if(cnt > argc) {
  587. sprintf(errstr,"Insufficient data sent from TK\n");
  588. return(DATA_ERROR);
  589. }
  590. switch(cnt) {
  591. case(1):
  592. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  593. sprintf(errstr,"Cannot read process no. sent from TK\n");
  594. return(DATA_ERROR);
  595. }
  596. break;
  597. case(2):
  598. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  599. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  600. return(DATA_ERROR);
  601. }
  602. if(dz->mode > 0)
  603. dz->mode--;
  604. //setup_particular_application() =
  605. if((exit_status = setup_distmark_application(dz))<0)
  606. return(exit_status);
  607. ap = dz->application;
  608. break;
  609. case(3):
  610. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  611. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  612. return(DATA_ERROR);
  613. }
  614. if(infilecnt < 1) {
  615. true_cnt = cnt + 1;
  616. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  617. }
  618. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  619. return(exit_status);
  620. break;
  621. case(INPUT_FILETYPE+4):
  622. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  623. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  624. return(DATA_ERROR);
  625. }
  626. break;
  627. case(INPUT_FILESIZE+4):
  628. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  629. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  630. return(DATA_ERROR);
  631. }
  632. dz->insams[0] = filesize;
  633. break;
  634. case(INPUT_INSAMS+4):
  635. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  636. sprintf(errstr,"Cannot read insams sent from TK\n");
  637. return(DATA_ERROR);
  638. }
  639. dz->insams[0] = insams;
  640. break;
  641. case(INPUT_SRATE+4):
  642. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  643. sprintf(errstr,"Cannot read srate sent from TK\n");
  644. return(DATA_ERROR);
  645. }
  646. break;
  647. case(INPUT_CHANNELS+4):
  648. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  649. sprintf(errstr,"Cannot read channels sent from TK\n");
  650. return(DATA_ERROR);
  651. }
  652. break;
  653. case(INPUT_STYPE+4):
  654. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  655. sprintf(errstr,"Cannot read stype sent from TK\n");
  656. return(DATA_ERROR);
  657. }
  658. break;
  659. case(INPUT_ORIGSTYPE+4):
  660. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  661. sprintf(errstr,"Cannot read origstype sent from TK\n");
  662. return(DATA_ERROR);
  663. }
  664. break;
  665. case(INPUT_ORIGRATE+4):
  666. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  667. sprintf(errstr,"Cannot read origrate sent from TK\n");
  668. return(DATA_ERROR);
  669. }
  670. break;
  671. case(INPUT_MLEN+4):
  672. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  673. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  674. return(DATA_ERROR);
  675. }
  676. break;
  677. case(INPUT_DFAC+4):
  678. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  679. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  680. return(DATA_ERROR);
  681. }
  682. break;
  683. case(INPUT_ORIGCHANS+4):
  684. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  685. sprintf(errstr,"Cannot read origchans sent from TK\n");
  686. return(DATA_ERROR);
  687. }
  688. break;
  689. case(INPUT_SPECENVCNT+4):
  690. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  691. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  692. return(DATA_ERROR);
  693. }
  694. dz->specenvcnt = dz->infile->specenvcnt;
  695. break;
  696. case(INPUT_WANTED+4):
  697. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  698. sprintf(errstr,"Cannot read wanted sent from TK\n");
  699. return(DATA_ERROR);
  700. }
  701. break;
  702. case(INPUT_WLENGTH+4):
  703. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  704. sprintf(errstr,"Cannot read wlength sent from TK\n");
  705. return(DATA_ERROR);
  706. }
  707. break;
  708. case(INPUT_OUT_CHANS+4):
  709. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  710. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  711. return(DATA_ERROR);
  712. }
  713. break;
  714. /* RWD these chanegs to samps - tk will have to deal with that! */
  715. case(INPUT_DESCRIPTOR_BYTES+4):
  716. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  717. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  718. return(DATA_ERROR);
  719. }
  720. break;
  721. case(INPUT_IS_TRANSPOS+4):
  722. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  723. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  724. return(DATA_ERROR);
  725. }
  726. break;
  727. case(INPUT_COULD_BE_TRANSPOS+4):
  728. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  729. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  730. return(DATA_ERROR);
  731. }
  732. break;
  733. case(INPUT_COULD_BE_PITCH+4):
  734. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  735. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  736. return(DATA_ERROR);
  737. }
  738. break;
  739. case(INPUT_DIFFERENT_SRATES+4):
  740. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  741. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  742. return(DATA_ERROR);
  743. }
  744. break;
  745. case(INPUT_DUPLICATE_SNDS+4):
  746. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  747. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  748. return(DATA_ERROR);
  749. }
  750. break;
  751. case(INPUT_BRKSIZE+4):
  752. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  753. sprintf(errstr,"Cannot read brksize sent from TK\n");
  754. return(DATA_ERROR);
  755. }
  756. if(inbrksize > 0) {
  757. switch(dz->input_data_type) {
  758. case(WORDLIST_ONLY):
  759. break;
  760. case(PITCH_AND_PITCH):
  761. case(PITCH_AND_TRANSPOS):
  762. case(TRANSPOS_AND_TRANSPOS):
  763. dz->tempsize = inbrksize;
  764. break;
  765. case(BRKFILES_ONLY):
  766. case(UNRANGED_BRKFILE_ONLY):
  767. case(DB_BRKFILES_ONLY):
  768. case(ALL_FILES):
  769. case(ANY_NUMBER_OF_ANY_FILES):
  770. if(dz->extrabrkno < 0) {
  771. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  772. return(DATA_ERROR);
  773. }
  774. if(dz->brksize == NULL) {
  775. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  776. return(PROGRAM_ERROR);
  777. }
  778. dz->brksize[dz->extrabrkno] = inbrksize;
  779. break;
  780. default:
  781. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  782. dz->input_data_type);
  783. return(PROGRAM_ERROR);
  784. }
  785. break;
  786. }
  787. break;
  788. case(INPUT_NUMSIZE+4):
  789. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  790. sprintf(errstr,"Cannot read numsize sent from TK\n");
  791. return(DATA_ERROR);
  792. }
  793. break;
  794. case(INPUT_LINECNT+4):
  795. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  796. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  797. return(DATA_ERROR);
  798. }
  799. break;
  800. case(INPUT_ALL_WORDS+4):
  801. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  802. sprintf(errstr,"Cannot read all_words sent from TK\n");
  803. return(DATA_ERROR);
  804. }
  805. break;
  806. case(INPUT_ARATE+4):
  807. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  808. sprintf(errstr,"Cannot read arate sent from TK\n");
  809. return(DATA_ERROR);
  810. }
  811. break;
  812. case(INPUT_FRAMETIME+4):
  813. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  814. sprintf(errstr,"Cannot read frametime sent from TK\n");
  815. return(DATA_ERROR);
  816. }
  817. dz->frametime = (float)dummy;
  818. break;
  819. case(INPUT_WINDOW_SIZE+4):
  820. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  821. sprintf(errstr,"Cannot read window_size sent from TK\n");
  822. return(DATA_ERROR);
  823. }
  824. break;
  825. case(INPUT_NYQUIST+4):
  826. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  827. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  828. return(DATA_ERROR);
  829. }
  830. break;
  831. case(INPUT_DURATION+4):
  832. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  833. sprintf(errstr,"Cannot read duration sent from TK\n");
  834. return(DATA_ERROR);
  835. }
  836. break;
  837. case(INPUT_MINBRK+4):
  838. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  839. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  840. return(DATA_ERROR);
  841. }
  842. break;
  843. case(INPUT_MAXBRK+4):
  844. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  845. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  846. return(DATA_ERROR);
  847. }
  848. break;
  849. case(INPUT_MINNUM+4):
  850. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  851. sprintf(errstr,"Cannot read minnum sent from TK\n");
  852. return(DATA_ERROR);
  853. }
  854. break;
  855. case(INPUT_MAXNUM+4):
  856. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  857. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  858. return(DATA_ERROR);
  859. }
  860. break;
  861. default:
  862. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  863. return(PROGRAM_ERROR);
  864. }
  865. cnt++;
  866. }
  867. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  868. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  869. return(DATA_ERROR);
  870. }
  871. if(true_cnt)
  872. cnt = true_cnt;
  873. *cmdlinecnt = 0;
  874. while(cnt < argc) {
  875. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  876. return(exit_status);
  877. cnt++;
  878. }
  879. return(FINISHED);
  880. }
  881. /********************************* GET_TK_CMDLINE_WORD *********************************/
  882. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  883. {
  884. if(*cmdlinecnt==0) {
  885. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  886. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  887. return(MEMORY_ERROR);
  888. }
  889. } else {
  890. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  891. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  892. return(MEMORY_ERROR);
  893. }
  894. }
  895. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  896. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  897. return(MEMORY_ERROR);
  898. }
  899. strcpy((*cmdline)[*cmdlinecnt],q);
  900. (*cmdlinecnt)++;
  901. return(FINISHED);
  902. }
  903. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  904. int assign_file_data_storage(int infilecnt,dataptr dz)
  905. {
  906. int exit_status;
  907. int no_sndfile_system_files = FALSE;
  908. dz->infilecnt = infilecnt;
  909. if((exit_status = allocate_filespace(dz))<0)
  910. return(exit_status);
  911. if(no_sndfile_system_files)
  912. dz->infilecnt = 0;
  913. return(FINISHED);
  914. }
  915. /************************* redundant functions: to ensure libs compile OK *******************/
  916. int assign_process_logic(dataptr dz)
  917. {
  918. return(FINISHED);
  919. }
  920. void set_legal_infile_structure(dataptr dz)
  921. {}
  922. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  923. {
  924. return(FINISHED);
  925. }
  926. int setup_internal_arrays_and_array_pointers(dataptr dz)
  927. {
  928. return(FINISHED);
  929. }
  930. int establish_bufptrs_and_extra_buffers(dataptr dz)
  931. {
  932. return(FINISHED);
  933. }
  934. int read_special_data(char *str,dataptr dz)
  935. {
  936. return(FINISHED);
  937. }
  938. int inner_loop
  939. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  940. {
  941. return(FINISHED);
  942. }
  943. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  944. {
  945. return(FINISHED);
  946. }
  947. /******************************** USAGE1 ********************************/
  948. int usage1(void)
  949. {
  950. usage2("distmark");
  951. return(USAGE_ONLY);
  952. }
  953. /********************************************************************************************/
  954. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  955. {
  956. if(!strcmp(prog_identifier_from_cmdline,"distmark")) dz->process = DISTMARK;
  957. else {
  958. fprintf(stderr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  959. return(USAGE_ONLY);
  960. }
  961. return(FINISHED);
  962. }
  963. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  964. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  965. {
  966. int n;
  967. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  968. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  969. return(MEMORY_ERROR);
  970. }
  971. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  972. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  973. return(MEMORY_ERROR);
  974. }
  975. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  976. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  977. return(MEMORY_ERROR);
  978. }
  979. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  980. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  981. return(MEMORY_ERROR);
  982. }
  983. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  984. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  985. return(MEMORY_ERROR);
  986. }
  987. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  988. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  989. return(MEMORY_ERROR);
  990. }
  991. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  992. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  993. return(MEMORY_ERROR);
  994. }
  995. for(n=0;n<brkcnt;n++) {
  996. dz->brk[n] = NULL;
  997. dz->brkptr[n] = NULL;
  998. dz->brkinit[n] = 0;
  999. dz->brksize[n] = 0;
  1000. }
  1001. return(FINISHED);
  1002. }
  1003. /******************************** USAGE2 ********************************/
  1004. int usage2(char *str)
  1005. {
  1006. if(!strcmp(str,"distmark")) {
  1007. fprintf(stderr,
  1008. "USAGE:\n"
  1009. "distmark distmark 1 infile outfile marklist unitlen [-ststretch] [-rrand] [-f] [-t]\n"
  1010. "distmark distmark 2 infile outfile marklist unitlen [-ststretch] [-rrand] [-f]\n"
  1011. "\n"
  1012. "Interpolate between waveset-groups at marked points in MONO soundfile.\n"
  1013. "In Mode 2 interpolate within ALTERNATE marked blocks.\n"
  1014. "\n"
  1015. "MARKLIST List of times within source at which to find waveset-groups.\n"
  1016. "UNITLEN (approx) size of waveset group to find (mS). Can vary over time.\n"
  1017. " Min UNITLEN < 1/2 of min step between Times in MARKLIST.\n"
  1018. "TSTRETCH Timestretch distances between marks, in making output.\n"
  1019. "RAND Randomise duration of interpolated wavesets (Range 0 - 1).\n"
  1020. " Randomisation decreases waveset lengths (heard \"pitch\" higher).\n"
  1021. "-f Flip phase of alternate wavesets.\n"
  1022. "-t Add original (remaining) tail of source sound to output.\n"
  1023. "\n");
  1024. } else
  1025. fprintf(stdout,"Unknown option '%s'\n",str);
  1026. return(USAGE_ONLY);
  1027. }
  1028. int usage3(char *str1,char *str2)
  1029. {
  1030. fprintf(stderr,"Insufficient parameters on command line.\n");
  1031. return(USAGE_ONLY);
  1032. }
  1033. /*************************** PREPROCESS_DISTMARK **************************/
  1034. int preprocess_distmark(dataptr dz)
  1035. {
  1036. int exit_status, seek_forward;
  1037. float *ibuf = dz->sampbuf[0];
  1038. double *times = dz->parray[0], mindur, time;
  1039. int *wavesetbloks, n, m, sampcnt, seccnt, nusampcnt, offset, bufpos, stt, wgstt, wavsetgplen;
  1040. double srate = (double)dz->infile->srate;
  1041. if((dz->lparray = (int **)malloc(2 * sizeof(int *)))==NULL) {
  1042. sprintf(errstr,"INSUFFICIENT MEMORY for Waveset samplecnt stores.\n");
  1043. return(MEMORY_ERROR);
  1044. }
  1045. // Create array big enough to store sizes of each intermediate time-interpd waveset-gp as we step from one mark to next
  1046. if(dz->brksize[DMARK_CNT]) { // Get smallest waveset-gp size
  1047. if((exit_status = get_minvalue_in_brktable(&mindur,DMARK_CNT,dz))<0)
  1048. return exit_status;
  1049. } else
  1050. mindur = dz->param[DMARK_CNT];
  1051. mindur *= MS_TO_SECS;
  1052. dz->stepstorecnt = (int)ceil(dz->maxstep/mindur);
  1053. dz->stepstorecnt *= 8; // SAFETY
  1054. if((dz->lparray[1] = (int *)malloc(dz->stepstorecnt * sizeof(int)))==NULL) {
  1055. sprintf(errstr,"INSUFFICIENT MEMORY for Waveset startsample store (2).\n");
  1056. return(MEMORY_ERROR);
  1057. }
  1058. // Set up store for true startsample and samplelen of waveset-gp at each time-mark
  1059. if((dz->lparray[0] = (int *)malloc(dz->itemcnt * 2 * sizeof(int)))==NULL) {
  1060. sprintf(errstr,"INSUFFICIENT MEMORY for Waveset startsample store (2).\n");
  1061. return(MEMORY_ERROR);
  1062. }
  1063. wavesetbloks = dz->lparray[0];
  1064. // Find exact locations and sizes of wavset-gps to be used
  1065. for(n=0,m=0;n < dz->itemcnt;n++,m+=2) {
  1066. time = times[n]; // Go to next timemark in sndfile
  1067. sampcnt = (int)round(time * srate);
  1068. seccnt = sampcnt/F_SECSIZE;
  1069. nusampcnt = seccnt * F_SECSIZE; // Curtal to nearest sector boundary (may be unness)
  1070. offset = sampcnt - nusampcnt;
  1071. if((sndseekEx(dz->ifd[0],nusampcnt,0))<0) {
  1072. sprintf(errstr,"sndseek 1 failed.\n");
  1073. return GOAL_FAILED;
  1074. }
  1075. if((exit_status = read_samps(ibuf,dz))<0)
  1076. return(exit_status);
  1077. bufpos = offset;
  1078. while(ibuf[bufpos] < 0.0) { // Search for 1st downward-going waveset start, after "time"
  1079. if(++bufpos > dz->ssampsread) {
  1080. sprintf(errstr,"No waveset-group start found (1) at time %lf (Buffer too short?)\n",time);
  1081. return(GOAL_FAILED);
  1082. }
  1083. }
  1084. while(ibuf[bufpos] >= 0.0) {
  1085. if(++bufpos > dz->ssampsread) {
  1086. sprintf(errstr,"No waveset-group start found (2) at time %lf (Buffer too short?)\n",time);
  1087. return(GOAL_FAILED);
  1088. }
  1089. }
  1090. stt = bufpos;
  1091. wgstt = nusampcnt + bufpos; // Note absolute sample-cnt at start of waveset-gp
  1092. if(dz->brksize[DMARK_CNT]) { // Get size of required waveset group at this "time"
  1093. if((exit_status = read_value_from_brktable(time,DMARK_CNT,dz))<0)
  1094. return(exit_status); // (either fixed param dz->param[0] mS or read brktable val)
  1095. }
  1096. wavsetgplen = (int)round(dz->param[DMARK_CNT] * MS_TO_SECS * srate);
  1097. bufpos += wavsetgplen;
  1098. if(bufpos >= dz->ssampsread) {
  1099. sprintf(errstr,"Anomaly in buffer sizing looking for end of waveset-group at time %lf (1)\n",time);
  1100. return(PROGRAM_ERROR);
  1101. }
  1102. seek_forward = 1;
  1103. while(seek_forward) {
  1104. while(ibuf[bufpos] < 0.0) { // Skip over samples below zero
  1105. if(++bufpos > dz->ssampsread) {
  1106. seek_forward = 0; // IF run off buf end, try backward seek instead
  1107. break;
  1108. }
  1109. }
  1110. if(!seek_forward)
  1111. break;
  1112. while(ibuf[bufpos] >= 0.0) { // Search for 1st downward-going waveset end, after "time"
  1113. if(++bufpos > dz->ssampsread) {
  1114. seek_forward = 0; // IF run off buf end, try backward seek instead
  1115. break;
  1116. }
  1117. }
  1118. break; // If reached 1st subzero sample after zero-crossing (still seeking forward) break
  1119. }
  1120. if(!seek_forward) { // Else, seek backwards
  1121. bufpos = stt + wavsetgplen;
  1122. while(ibuf[bufpos] >= 0.0) { // Searching bkwds, if samps above zero, skip over samples above zero
  1123. if(--bufpos < stt) {
  1124. sprintf(errstr,"No waveset-group end found (1) after time %lf\n",time);
  1125. return(GOAL_FAILED);
  1126. }
  1127. }
  1128. while(ibuf[bufpos] < 0.0) { // Search bkwds, skip over samples below zero
  1129. if(--bufpos < stt) {
  1130. sprintf(errstr,"No waveset-group end found (2) after time %lf\n",time);
  1131. return(GOAL_FAILED);
  1132. }
  1133. }
  1134. bufpos++; // Go back to last below-zero sample found
  1135. }
  1136. wavesetbloks[m] = wgstt; // Absolute sample position of start of waveset-group
  1137. wavesetbloks[m+1] = bufpos - stt; // Size of waveset group
  1138. }
  1139. return FINISHED;
  1140. }
  1141. /*************************** CREATE_DISTMARK_SNDBUFS **************************/
  1142. int create_distmark_sndbufs(dataptr dz)
  1143. {
  1144. int framesize = F_SECSIZE;
  1145. int bigbufsize, doubleframe, seccnt, n;
  1146. doubleframe = framesize * 2;
  1147. if(dz->sbufptr == 0 || dz->sampbuf==0) {
  1148. sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n");
  1149. return(PROGRAM_ERROR);
  1150. }
  1151. seccnt = dz->buflen/framesize;
  1152. if(seccnt * framesize < dz->buflen)
  1153. seccnt++;
  1154. dz->buflen = seccnt * framesize; // Input/output bufs are a multiple of framesize
  1155. if(dz->buflen2 < doubleframe) // Waveset-group processing buffers must be at least 2 framesizes int
  1156. dz->buflen2 = doubleframe; // because of the way seek approximates to framesize boundaries
  1157. bigbufsize = dz->buflen * 3;
  1158. if((dz->bigbuf = (float *)malloc(bigbufsize * sizeof(float))) == NULL) {
  1159. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1160. return(PROGRAM_ERROR);
  1161. }
  1162. for(n=0; n<3; n++)
  1163. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (n * dz->buflen);
  1164. return(FINISHED);
  1165. }
  1166. int create_distmark_sndbufs2(dataptr dz)
  1167. {
  1168. int framesize = F_SECSIZE;
  1169. int bigbufsize, doubleframe, n, m;
  1170. int *wavesetlens = dz->lparray[0];
  1171. doubleframe = framesize * 2;
  1172. dz->buflen2 = 0;
  1173. for(n = 0,m = 1; n < dz->itemcnt; n++,m+=2)
  1174. dz->buflen2 = max(dz->buflen2,wavesetlens[m]);
  1175. dz->buflen2 += SAFETY;
  1176. if(dz->buflen2 < doubleframe) // Waveset-group processing buffers must be at least 2 framesizes int
  1177. dz->buflen2 = doubleframe; // because of the way seek approximates to framesize boundaries
  1178. bigbufsize = dz->buflen2 * 4;
  1179. if((dz->bigfbuf = (float *)malloc(bigbufsize * sizeof(float))) == NULL) {
  1180. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1181. return(PROGRAM_ERROR);
  1182. }
  1183. for(m = 0,n=3; n<7; m++,n++) // This creates buffers 4 to 7 out of dz->bigFFFbuf
  1184. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigfbuf + (m * dz->buflen2);
  1185. return(FINISHED);
  1186. }
  1187. /*************************** DISTMARK **************************
  1188. *
  1189. * 1st waveset-group is read into BUFA
  1190. * 2nd waveset-group is read into BUFB
  1191. * The smaller waveset-group is stretched to length of larger, and written into STRETCHBUF
  1192. * Sample-by-sample amplitude interpolation is initially between the larger waveset-group and the stretched waveset-group ...
  1193. * These are labelled BUF1 and BUF2 and the output goes to INTERPBUF
  1194. * The output in interpbuf is now Time-interpolated into the OBUF
  1195. *
  1196. */
  1197. int distmark(dataptr dz)
  1198. {
  1199. int exit_status, n, m, j, k, invertphase;
  1200. int gpstt, gplen, lastgpstt = 0, lastgplen = 0, seekto, bufpos, thispos, nextpos, biglen, timinterpcnt, samplen, obufpos, rbufpos = 0, presamps;
  1201. float *ibuf = dz->sampbuf[0],*obuf = dz->sampbuf[1];
  1202. float *bufa = dz->sampbuf[2],*bufb = dz->sampbuf[3],*stretchbuf = dz->sampbuf[4],*interpbuf = dz->sampbuf[5], *revbuf = dz->sampbuf[6];
  1203. float *buf1,*buf2;
  1204. int *wavgpdata = dz->lparray[0], *intplens = dz->lparray[1];
  1205. double time, fracpos, thisval, valdiff, val, val1, val2, fpos, advnc = 0.0, rndval;
  1206. double *times = dz->parray[0];
  1207. obufpos = 0;
  1208. for(n=0,m=0;n < dz->itemcnt;n++,m+=2) {
  1209. invertphase = 0;
  1210. gpstt = wavgpdata[m];
  1211. gplen = wavgpdata[m+1];
  1212. time = times[n];
  1213. memset((char *)bufa,0,dz->buflen2 * sizeof(float));
  1214. if(n==0) { // If 1st waveset-grp
  1215. if(gpstt != 0) {
  1216. if((sndseekEx(dz->ifd[0],0,0))<0) { // If 1st mark not at file start
  1217. sprintf(errstr,"sndseek 2 failed.\n"); // Copy sound before 1st mark direct to output
  1218. return GOAL_FAILED;
  1219. }
  1220. if((exit_status = read_samps(ibuf,dz))<0)
  1221. return(exit_status);
  1222. presamps = gpstt;
  1223. while(presamps > dz->buflen) { // Copy any complete buflens of this material, directly to output file
  1224. if((exit_status = write_samps(ibuf,dz->ofd,dz))<0)
  1225. return(exit_status);
  1226. presamps -= dz->buflen;
  1227. if((exit_status = read_samps(ibuf,dz))<0)
  1228. return(exit_status);
  1229. }
  1230. if(presamps > 0) { // and if there's any incomplete buffer, copy this into the output buffer
  1231. memcpy((char *)obuf,(char *)ibuf,presamps * sizeof(float));
  1232. obufpos = presamps;
  1233. }
  1234. }
  1235. seekto = (gpstt/F_SECSIZE) * F_SECSIZE; // Seek to nearest sector boundary below desired location
  1236. if((sndseekEx(dz->ifd[0],seekto,0))<0) {
  1237. sprintf(errstr,"sndseek 3 failed.\n");
  1238. return GOAL_FAILED;
  1239. }
  1240. if((exit_status = read_samps(ibuf,dz))<0)
  1241. return(exit_status);
  1242. bufpos = gpstt - seekto; // Copy wavesetgroup to buffer B
  1243. memcpy((char *)bufb,(char *)(ibuf + bufpos),gplen * sizeof(float));
  1244. } else { // If NOT 1st waveset-grp, copy contents of buf B to buf A
  1245. memcpy((char *)bufa,(char *)bufb,lastgplen * sizeof(float));
  1246. // After 1st waveset group, look for next waveset-group and put in buffer B
  1247. seekto = (gpstt/F_SECSIZE) * F_SECSIZE; // Seek to nearest sector boundary below desired location
  1248. if((sndseekEx(dz->ifd[0],seekto,0))<0) {
  1249. sprintf(errstr,"sndseek 4 failed.\n");
  1250. return GOAL_FAILED;
  1251. }
  1252. if((exit_status = read_samps(ibuf,dz))<0)
  1253. return(exit_status);
  1254. bufpos = gpstt - seekto; // Copy wavesetgroup to buffer B
  1255. memcpy((char *)bufb,(char *)(ibuf + bufpos),gplen * sizeof(float));
  1256. if(gplen > lastgplen) { // If new waveset-gp (in bufB) longer than previous waveset-gp (in bufA)
  1257. bufa[lastgplen] = 0.0f; // Add wrap-around point to buffer A
  1258. advnc = (double)lastgplen/(double)gplen; // Set read-incr. Expanding, so incr < 1.0
  1259. fpos = 0.0; // Stretch contents of bufA into bufC
  1260. k = 0;
  1261. while(fpos < lastgplen) {
  1262. thispos = (int)floor(fpos);
  1263. nextpos = thispos+1;
  1264. fracpos = fpos - (double)thispos;
  1265. thisval = bufa[thispos];
  1266. valdiff = bufa[nextpos] - thisval;
  1267. val = thisval + (valdiff * fracpos);
  1268. stretchbuf[k++] = (float)val;
  1269. fpos += advnc;
  1270. }
  1271. buf1 = stretchbuf; // Interp is from tstretched bufa (in stretchbuf)
  1272. buf2 = bufb; // to bufb
  1273. biglen = gplen; // Length of samples whos values to be interpd (biggest waveset-gp)
  1274. } else if(gplen < lastgplen) { // If new waveset-gp (bufB) shorter than previous waveset-gp (bugA)
  1275. bufb[gplen] = 0.0f; // Add wrap-around point to buffer B
  1276. advnc = (double)gplen/(double)lastgplen; // Set read-incr. Expanding ... so incr < 1.0
  1277. fpos = 0.0; // Stretch contents of bufB into bufC
  1278. k = 0;
  1279. while(fpos < gplen) {
  1280. thispos = (int)floor(fpos);
  1281. nextpos = thispos+1;
  1282. fracpos = fpos - (double)thispos;
  1283. thisval = bufb[thispos];
  1284. valdiff = bufb[nextpos] - thisval;
  1285. val = thisval + (valdiff * fracpos);
  1286. stretchbuf[k++] = (float)val;
  1287. fpos += advnc;
  1288. }
  1289. buf1 = bufa; // Interp is from bufa
  1290. buf2 = stretchbuf; // to tstretched version of bufb (in stretchbuf)
  1291. biglen = lastgplen;
  1292. } else { // ELSE buffers are same length
  1293. buf1 = bufa; // Interp is from bufa to bufb
  1294. buf2 = bufb;
  1295. biglen = gplen;
  1296. }
  1297. // Calculate number of waveset-gp copies needed for time-interpolation, and store the lengths of the copies
  1298. if((timinterpcnt = get_timeinterpcnt(lastgplen,gplen,gpstt-lastgpstt,time,dz))<0) {
  1299. exit_status = timinterpcnt;
  1300. return exit_status;
  1301. }
  1302. for(k=0;k<lastgplen;k++) { // Copy unchanged previous waveset to output
  1303. obuf[obufpos++] = bufa[k];
  1304. if(obufpos >= dz->buflen) {
  1305. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1306. return(exit_status);
  1307. obufpos = 0;
  1308. }
  1309. }
  1310. for(j=1;j < timinterpcnt;j++) { // For each intervening waveset-gp
  1311. for(k=0;k<biglen;k++) { // Interp between sample vals in buf1 and buf2 to get new waveset shape
  1312. val1 = buf1[k] * (double)(timinterpcnt - j)/(double)timinterpcnt;
  1313. val2 = buf2[k] * (double)j/(double)timinterpcnt;
  1314. interpbuf[k] = (float)(val1 + val2);
  1315. } // and add wrap-around zero at end
  1316. interpbuf[k] = 0.0;
  1317. samplen = intplens[j]; // Timestretch new shape appropriately, and put in obuf
  1318. if(dz->brksize[DMARK_RND]) {
  1319. if((exit_status = read_value_from_brktable(time,DMARK_RND,dz))<0)
  1320. return exit_status;
  1321. }
  1322. if(dz->param[DMARK_RND] > 0.0) {
  1323. rndval = drand48() * 0.5 * dz->param[DMARK_RND]; // Randval in range 0 to 1/2, if dmark_rnd param = (max) 1.0
  1324. rndval = 1.0 - rndval; // Randval in range 1 to 1/2, if dmark_rnd param = (max) 1.0 : otherwise in range 1 to > 1/2
  1325. samplen = (int)round((double)samplen * rndval);
  1326. }
  1327. advnc = (double)biglen/(double)samplen;
  1328. if(dz->vflag[DMARK_FLIP])
  1329. invertphase = !invertphase;
  1330. fpos = 0.0;
  1331. if(invertphase) {
  1332. rbufpos = 0;
  1333. while(fpos < biglen) {
  1334. thispos = (int)floor(fpos);
  1335. nextpos = thispos+1;
  1336. fracpos = fpos - (double)thispos;
  1337. thisval = interpbuf[thispos];
  1338. valdiff = interpbuf[nextpos] - thisval;
  1339. val = thisval + (valdiff * fracpos);
  1340. revbuf[rbufpos++] = (float)val;
  1341. fpos += advnc;
  1342. }
  1343. rbufpos--;
  1344. while(rbufpos >= 0) {
  1345. obuf[obufpos++] = -(revbuf[rbufpos]); // Time-reverse and invert phase
  1346. if(obufpos >= dz->buflen) {
  1347. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1348. return(exit_status);
  1349. obufpos = 0;
  1350. }
  1351. rbufpos--;
  1352. }
  1353. } else {
  1354. while(fpos < biglen) {
  1355. thispos = (int)floor(fpos);
  1356. nextpos = thispos+1;
  1357. fracpos = fpos - (double)thispos;
  1358. thisval = interpbuf[thispos];
  1359. valdiff = interpbuf[nextpos] - thisval;
  1360. val = thisval + (valdiff * fracpos);
  1361. obuf[obufpos++] = (float)val;
  1362. if(obufpos >= dz->buflen) {
  1363. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1364. return(exit_status);
  1365. obufpos = 0;
  1366. }
  1367. fpos += advnc;
  1368. }
  1369. }
  1370. }
  1371. }
  1372. lastgpstt = gpstt;
  1373. lastgplen = gplen;
  1374. }
  1375. // Write tail of file
  1376. seekto = (lastgpstt/F_SECSIZE) * F_SECSIZE;
  1377. if((sndseekEx(dz->ifd[0],seekto,0))<0) {
  1378. sprintf(errstr,"sndseek 5 failed.\n");
  1379. return GOAL_FAILED;
  1380. }
  1381. if((exit_status = read_samps(ibuf,dz))<0)
  1382. return(exit_status);
  1383. bufpos = lastgpstt - seekto; // Copy wavesetgroup to buffer B
  1384. if(dz->vflag[DMARK_TAIL]) {
  1385. while(dz->ssampsread > 0) {
  1386. while(bufpos < dz->ssampsread) {
  1387. obuf[obufpos++] = ibuf[bufpos++];
  1388. if(obufpos >= dz->buflen) {
  1389. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1390. return(exit_status);
  1391. obufpos = 0;
  1392. }
  1393. }
  1394. if((exit_status = read_samps(ibuf,dz))<0)
  1395. return(exit_status);
  1396. bufpos = 0;
  1397. }
  1398. } else {
  1399. for(n=0;n < lastgplen;n++) {
  1400. obuf[obufpos++] = ibuf[bufpos++];
  1401. if(obufpos >= dz->buflen) {
  1402. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1403. return(exit_status);
  1404. obufpos = 0;
  1405. }
  1406. }
  1407. }
  1408. if(obufpos > 0) {
  1409. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1410. return(exit_status);
  1411. }
  1412. return FINISHED;
  1413. }
  1414. /************************ HANDLE_THE_SPECIAL_DATA *********************/
  1415. int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz)
  1416. {
  1417. int exit_status;
  1418. if(!sloom) {
  1419. if(*cmdlinecnt <= 0) {
  1420. sprintf(errstr,"Insufficient parameters on command line.\n");
  1421. return(USAGE_ONLY);
  1422. }
  1423. }
  1424. if((exit_status = read_mark_data((*cmdline)[0],dz))<0)
  1425. return(exit_status);
  1426. (*cmdline)++;
  1427. (*cmdlinecnt)--;
  1428. return(FINISHED);
  1429. }
  1430. /************************************ READ_MARK_DATA ************************************/
  1431. int read_mark_data(char *filename,dataptr dz)
  1432. {
  1433. double *time, lasttime, dummy, timestep;
  1434. int cnt, warned = 0;
  1435. char temp[200], *q;
  1436. aplptr ap;
  1437. FILE *fp;
  1438. ap = dz->application;
  1439. if((fp = fopen(filename,"r"))==NULL) {
  1440. sprintf(errstr, "Can't open file %s to read data.\n",filename);
  1441. return(DATA_ERROR);
  1442. }
  1443. cnt = 0;
  1444. while(fgets(temp,200,fp)==temp) {
  1445. q = temp;
  1446. if(*q == ';') // Allow comments in file
  1447. continue;
  1448. while(get_float_from_within_string(&q,&dummy)) {
  1449. cnt++;
  1450. }
  1451. }
  1452. if(cnt == 0) {
  1453. sprintf(errstr,"No data in file %s\n",filename);
  1454. return(DATA_ERROR);
  1455. }
  1456. if((dz->parray = (double **)malloc(sizeof(double *)))==NULL) {
  1457. sprintf(errstr,"INSUFFICIENT MEMORY for data in file %s. (1)\n",filename);
  1458. return(MEMORY_ERROR);
  1459. }
  1460. if((dz->parray[0] = (double *)malloc(cnt * sizeof(double)))==NULL) {
  1461. sprintf(errstr,"INSUFFICIENT MEMORY for data in file %s. (2)\n",filename);
  1462. return(MEMORY_ERROR);
  1463. }
  1464. time = dz->parray[0];
  1465. rewind(fp);
  1466. lasttime = -1.0;
  1467. cnt = 0;
  1468. dz->minstep = HUGE;
  1469. dz->maxstep = 0.0;
  1470. while(fgets(temp,200,fp)==temp) {
  1471. q = temp;
  1472. if(*q == ';') // Allow comments in file
  1473. continue;
  1474. while(get_float_from_within_string(&q,&dummy)) {
  1475. if(dummy < 0.0 || dummy <= lasttime) {
  1476. sprintf(errstr,"Times do not advance correctly in file %s.\n",filename);
  1477. return(DATA_ERROR);
  1478. }
  1479. if(dummy >= dz->duration) {
  1480. if (!warned) {
  1481. fprintf(stdout,"WARNING: Times beyond end of sndfile (%lf) in file %s. Ignoring them.\n",dz->duration,filename);
  1482. fflush(stdout);
  1483. warned = 1;
  1484. }
  1485. break;
  1486. }
  1487. *time = dummy;
  1488. if(cnt > 0) {
  1489. timestep = *time - lasttime;
  1490. if(timestep < dz->minstep)
  1491. dz->minstep = timestep;
  1492. if(timestep > dz->maxstep)
  1493. dz->maxstep = timestep;
  1494. }
  1495. lasttime = *time;
  1496. time++;
  1497. cnt++;
  1498. }
  1499. }
  1500. timestep = dz->duration - lasttime;
  1501. if(timestep < dz->minstep)
  1502. dz->minstep = timestep;
  1503. if(timestep > dz->maxstep)
  1504. dz->maxstep = timestep;
  1505. if(fclose(fp)<0) {
  1506. fprintf(stdout,"WARNING: Failed to close file %s.\n",filename);
  1507. fflush(stdout);
  1508. }
  1509. dz->itemcnt = cnt;
  1510. return(FINISHED);
  1511. }
  1512. /**************************** CHECK_DISTMARK_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  1513. int check_distmark_param_validity_and_consistency(dataptr dz)
  1514. {
  1515. int exit_status;
  1516. double maxdur, maxstr, srate = (double)dz->infile->srate;
  1517. if(dz->brksize[DMARK_CNT]) { // Find maximum duration of waveset-gps (param in mS)
  1518. if((exit_status = get_maxvalue_in_brktable(&maxdur,DMARK_CNT,dz))<0)
  1519. return exit_status;
  1520. } else
  1521. maxdur = dz->param[DMARK_CNT];
  1522. maxdur *= MS_TO_SECS;
  1523. if(maxdur >= dz->minstep/2.0) {
  1524. sprintf(errstr,"Max dur of waveset-units (%lf secs) greater than 1/2 of min step between marks (%lf secs).\n",maxdur,dz->minstep);
  1525. return(DATA_ERROR);
  1526. }
  1527. if(dz->brksize[DMARK_STR]) { // Find maximum tmestretch value
  1528. if((exit_status = get_maxvalue_in_brktable(&maxstr,DMARK_STR,dz))<0)
  1529. return exit_status;
  1530. } else
  1531. maxstr = dz->param[DMARK_STR];
  1532. dz->buflen = (int)ceil(dz->maxstep * maxstr * srate) * 2; // Larger than largest step in infile * largest tstretch val
  1533. dz->buflen2 = (int)ceil(maxdur * (double)dz->infile->srate) * 2; // Larger than largest waveset-gp unit
  1534. return FINISHED;
  1535. }
  1536. /************************************** GET_TIMEINTERPCNT **********************************************
  1537. *
  1538. * Calculate number, and sizes, of intermediate time-interpd waveset-gps
  1539. */
  1540. int get_timeinterpcnt(int lastgplen,int gplen,int markstep,double time,dataptr dz)
  1541. {
  1542. int exit_status;
  1543. int *unitlens = dz->lparray[1];
  1544. double avlen;
  1545. int timeinterpcnt, totallen, lendiff, n, thislen, offset, lastoffset = 0, outmarkstep;
  1546. avlen = (double)(lastgplen + gplen)/2.0; // Average unit length
  1547. if(dz->brksize[DMARK_STR]) {
  1548. if((exit_status = read_value_from_brktable(time,DMARK_STR,dz))<0)
  1549. return exit_status;
  1550. }
  1551. outmarkstep = (int)round((double)markstep * dz->param[DMARK_STR]);
  1552. timeinterpcnt = (int)round((double)outmarkstep/avlen); // Number of average units in total length
  1553. totallen = 0;
  1554. lendiff = gplen - lastgplen;
  1555. for(n=0;n < timeinterpcnt;n++) { // Using this 1st estimated value, sum sample-duration of all the interpd waveset-gps between 1 mark and next
  1556. thislen = lastgplen + (int)round(lendiff * (double)n/(double)timeinterpcnt);
  1557. totallen += thislen;
  1558. }
  1559. offset = outmarkstep - totallen; // Compare this with the desired samplelen
  1560. if(offset > 0) {
  1561. while(offset > 0) { // IF sum falls below desired value
  1562. lastoffset = offset; // try incrementing "timeinterpcnt"
  1563. totallen = 0; // until sum falls ABOVE desired value.
  1564. timeinterpcnt++;
  1565. for(n=0;n < timeinterpcnt;n++) {
  1566. thislen = lastgplen + (int)round(lendiff * (double)n/(double)timeinterpcnt);
  1567. totallen += thislen;
  1568. }
  1569. offset = outmarkstep - totallen;
  1570. }
  1571. if(abs(offset) > abs(lastoffset)) // choose the timeinterpcnt which gives closest approx to outmarkstep
  1572. timeinterpcnt--;
  1573. } else if(offset < 0) { // ELSE of sum falls above desired value
  1574. while(offset < 0) { // try decrementing "timeinterpcnt"
  1575. lastoffset = offset; // until sum falls BELOW desired value.
  1576. totallen = 0;
  1577. timeinterpcnt--;
  1578. if(timeinterpcnt == 0)
  1579. break;
  1580. for(n=0;n < timeinterpcnt;n++) {
  1581. thislen = lastgplen + (int)round(lendiff * (double)n/(double)timeinterpcnt);
  1582. totallen += thislen;
  1583. }
  1584. offset = outmarkstep - totallen;
  1585. }
  1586. if(abs(offset) > abs(lastoffset)) // choose the timeinterpcnt which gives closest approx to outmarkstep
  1587. timeinterpcnt++;
  1588. }
  1589. if(timeinterpcnt < 2) { // Force at least 2 interp steps (1 = orig waveset-gp, 2 = interp towards next waveset-gp)
  1590. fprintf(stdout,"WARNING: Less than 2 interpolation steps before time %lf\n",time);
  1591. fflush(stdout);
  1592. timeinterpcnt = 2;
  1593. } else if(dz->vflag[DMARK_FLIP] && !EVEN(timeinterpcnt))
  1594. timeinterpcnt++;
  1595. if(timeinterpcnt >= dz->stepstorecnt) {
  1596. sprintf(errstr,"Memory store for sizes of intermediate waveset-groups (%d), not large enough (%d needed).\n",dz->stepstorecnt,timeinterpcnt);
  1597. return PROGRAM_ERROR;
  1598. }
  1599. for(n=0;n < timeinterpcnt;n++) {
  1600. thislen = lastgplen + (int)round(lendiff * (double)n/(double)timeinterpcnt);
  1601. unitlens[n] = thislen;
  1602. }
  1603. return timeinterpcnt;
  1604. }
  1605. int distmark2(dataptr dz)
  1606. {
  1607. int exit_status, n, m, j, k, invertphase, done = 0;
  1608. int gpstt, gplen, lastgpstt = 0, lastgplen = 0, seekto, bufpos, thispos, nextpos, biglen, timinterpcnt, samplen, obufpos, rbufpos = 0, presamps;
  1609. float *ibuf = dz->sampbuf[0],*obuf = dz->sampbuf[1];
  1610. float *bufa = dz->sampbuf[2],*bufb = dz->sampbuf[3],*stretchbuf = dz->sampbuf[4],*interpbuf = dz->sampbuf[5], *revbuf = dz->sampbuf[6];
  1611. float *buf1,*buf2;
  1612. int *wavgpdata = dz->lparray[0], *intplens = dz->lparray[1];
  1613. double time, fracpos, thisval, valdiff, val, val1, val2, fpos, advnc = 0.0, rndval, thistime;
  1614. double *times = dz->parray[0];
  1615. int lastbufpos = 0, samps_to_copy;
  1616. obufpos = 0;
  1617. for(n=0,m=0;n < dz->itemcnt;n++,m+=2) {
  1618. invertphase = 0;
  1619. gpstt = wavgpdata[m];
  1620. gplen = wavgpdata[m+1];
  1621. time = times[n];
  1622. if((dz->vflag[1] == 0 && EVEN(n)) || (dz->vflag[1] == 1 && ODD(n))) {
  1623. memset((char *)bufa,0,dz->buflen2 * sizeof(float));
  1624. if (n > 0) { // If not the first marked-waveset-group (0 is EVEN)
  1625. lastbufpos = lastbufpos + lastgplen; // copy from end of last interp-block to current interp-block start
  1626. j = lastbufpos;
  1627. samps_to_copy = wavgpdata[m] - wavgpdata[m-2];
  1628. for(k = 0; k < samps_to_copy;k++) {
  1629. obuf[obufpos++] = ibuf[j++];
  1630. if(obufpos >= dz->buflen) {
  1631. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1632. return(exit_status);
  1633. obufpos = 0;
  1634. }
  1635. if(j >= dz->buflen) {
  1636. if((exit_status = read_samps(ibuf,dz))<0)
  1637. return(exit_status);
  1638. if(dz->ssampsread == 0) {
  1639. done = 1;
  1640. break;
  1641. }
  1642. j = 0;
  1643. }
  1644. }
  1645. if(done)
  1646. break;
  1647. }
  1648. if(n == 0 && gpstt != 0) {
  1649. if((sndseekEx(dz->ifd[0],0,0))<0) { // If 1st mark not at file start
  1650. sprintf(errstr,"sndseek 2 failed.\n"); // Copy sound before 1st mark direct to output
  1651. return GOAL_FAILED;
  1652. }
  1653. if((exit_status = read_samps(ibuf,dz))<0)
  1654. return(exit_status);
  1655. presamps = gpstt;
  1656. while(presamps > dz->buflen) { // Copy any complete buflens of this material, directly to output file
  1657. if((exit_status = write_samps(ibuf,dz->ofd,dz))<0)
  1658. return(exit_status);
  1659. presamps -= dz->buflen;
  1660. if((exit_status = read_samps(ibuf,dz))<0)
  1661. return(exit_status);
  1662. }
  1663. if(presamps > 0) { // and if there's any incomplete buffer, copy this into the output buffer
  1664. memcpy((char *)obuf,(char *)ibuf,presamps * sizeof(float));
  1665. obufpos = presamps;
  1666. }
  1667. }
  1668. seekto = (gpstt/F_SECSIZE) * F_SECSIZE; // Seek to nearest sector boundary below desired location
  1669. if((sndseekEx(dz->ifd[0],seekto,0))<0) {
  1670. sprintf(errstr,"sndseek 3 failed.\n");
  1671. return GOAL_FAILED;
  1672. }
  1673. if((exit_status = read_samps(ibuf,dz))<0)
  1674. return(exit_status);
  1675. bufpos = gpstt - seekto; // Copy wavesetgroup to buffer B
  1676. memcpy((char *)bufb,(char *)(ibuf + bufpos),gplen * sizeof(float));
  1677. } else { // If NOT 1st waveset-grp, copy contents of buf B to buf A
  1678. memcpy((char *)bufa,(char *)bufb,lastgplen * sizeof(float));
  1679. // After 1st waveset group, look for next waveset-group and put in buffer B
  1680. seekto = (gpstt/F_SECSIZE) * F_SECSIZE; // Seek to nearest sector boundary below desired location
  1681. if((sndseekEx(dz->ifd[0],seekto,0))<0) {
  1682. sprintf(errstr,"sndseek 4 failed.\n");
  1683. return GOAL_FAILED;
  1684. }
  1685. if((exit_status = read_samps(ibuf,dz))<0)
  1686. return(exit_status);
  1687. bufpos = gpstt - seekto; // Copy wavesetgroup to buffer B
  1688. lastbufpos = bufpos;
  1689. lastgplen = gplen;
  1690. memcpy((char *)bufb,(char *)(ibuf + bufpos),gplen * sizeof(float));
  1691. if(gplen > lastgplen) { // If new waveset-gp (in bufB) longer than previous waveset-gp (in bufA)
  1692. bufa[lastgplen] = 0.0f; // Add wrap-around point to buffer A
  1693. advnc = (double)lastgplen/(double)gplen; // Set read-incr. Expanding, so incr < 1.0
  1694. fpos = 0.0; // Stretch contents of bufA into bufC
  1695. k = 0;
  1696. while(fpos < lastgplen) {
  1697. thispos = (int)floor(fpos);
  1698. nextpos = thispos+1;
  1699. fracpos = fpos - (double)thispos;
  1700. thisval = bufa[thispos];
  1701. valdiff = bufa[nextpos] - thisval;
  1702. val = thisval + (valdiff * fracpos);
  1703. stretchbuf[k++] = (float)val;
  1704. fpos += advnc;
  1705. }
  1706. buf1 = stretchbuf; // Interp is from tstretched bufa (in stretchbuf)
  1707. buf2 = bufb; // to bufb
  1708. biglen = gplen; // Length of samples whos values to be interpd (biggest waveset-gp)
  1709. } else if(gplen < lastgplen) { // If new waveset-gp (bufB) shorter than previous waveset-gp (bugA)
  1710. bufb[gplen] = 0.0f; // Add wrap-around point to buffer B
  1711. advnc = (double)gplen/(double)lastgplen; // Set read-incr. Expanding ... so incr < 1.0
  1712. fpos = 0.0; // Stretch contents of bufB into bufC
  1713. k = 0;
  1714. while(fpos < gplen) {
  1715. thispos = (int)floor(fpos);
  1716. nextpos = thispos+1;
  1717. fracpos = fpos - (double)thispos;
  1718. thisval = bufb[thispos];
  1719. valdiff = bufb[nextpos] - thisval;
  1720. val = thisval + (valdiff * fracpos);
  1721. stretchbuf[k++] = (float)val;
  1722. fpos += advnc;
  1723. }
  1724. buf1 = bufa; // Interp is from bufa
  1725. buf2 = stretchbuf; // to tstretched version of bufb (in stretchbuf)
  1726. biglen = lastgplen;
  1727. } else { // ELSE buffers are same length
  1728. buf1 = bufa; // Interp is from bufa to bufb
  1729. buf2 = bufb;
  1730. biglen = gplen;
  1731. }
  1732. // Calculate number of waveset-gp copies needed for time-interpolation, and store the lengths of the copies
  1733. if((timinterpcnt = get_timeinterpcnt(lastgplen,gplen,gpstt-lastgpstt,time,dz))<0) {
  1734. exit_status = timinterpcnt;
  1735. return exit_status;
  1736. }
  1737. if(dz->brksize[DMARK_GAIN]) {
  1738. thistime = (dz->total_samps_written + obufpos)/(double)dz->infile->srate;
  1739. if((exit_status = read_value_from_brktable(thistime,DMARK_GAIN,dz)) < 0)
  1740. return exit_status;
  1741. }
  1742. for(k=0;k<lastgplen;k++) { // Copy unchanged previous waveset to output
  1743. obuf[obufpos++] = (float)(bufa[k] * dz->param[DMARK_GAIN]);
  1744. if(obufpos >= dz->buflen) {
  1745. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1746. return(exit_status);
  1747. obufpos = 0;
  1748. }
  1749. }
  1750. for(j=1;j < timinterpcnt;j++) { // For each intervening waveset-gp
  1751. for(k=0;k<biglen;k++) { // Interp between sample vals in buf1 and buf2 to get new waveset shape
  1752. val1 = buf1[k] * (double)(timinterpcnt - j)/(double)timinterpcnt;
  1753. val2 = buf2[k] * (double)j/(double)timinterpcnt;
  1754. interpbuf[k] = (float)(val1 + val2);
  1755. } // and add wrap-around zero at end
  1756. interpbuf[k] = 0.0;
  1757. samplen = intplens[j]; // Timestretch new shape appropriately, and put in obuf
  1758. if(dz->brksize[DMARK_RND]) {
  1759. if((exit_status = read_value_from_brktable(time,DMARK_RND,dz))<0)
  1760. return exit_status;
  1761. }
  1762. if(dz->param[DMARK_RND] > 0.0) {
  1763. rndval = drand48() * 0.5 * dz->param[DMARK_RND]; // Randval in range 0 to 1/2, if dmark_rnd param = (max) 1.0
  1764. rndval = 1.0 - rndval; // Randval in range 1 to 1/2, if dmark_rnd param = (max) 1.0 : otherwise in range 1 to > 1/2
  1765. samplen = (int)round((double)samplen * rndval);
  1766. }
  1767. advnc = (double)biglen/(double)samplen;
  1768. if(dz->vflag[DMARK_FLIP])
  1769. invertphase = !invertphase;
  1770. fpos = 0.0;
  1771. if(invertphase) {
  1772. rbufpos = 0;
  1773. while(fpos < biglen) {
  1774. thispos = (int)floor(fpos);
  1775. nextpos = thispos+1;
  1776. fracpos = fpos - (double)thispos;
  1777. thisval = interpbuf[thispos];
  1778. valdiff = interpbuf[nextpos] - thisval;
  1779. val = thisval + (valdiff * fracpos);
  1780. revbuf[rbufpos++] = (float)val;
  1781. fpos += advnc;
  1782. }
  1783. rbufpos--;
  1784. while(rbufpos >= 0) {
  1785. obuf[obufpos++] = (float)(-revbuf[rbufpos] * dz->param[DMARK_GAIN]); // Time-reverse and invert phase
  1786. if(obufpos >= dz->buflen) {
  1787. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1788. return(exit_status);
  1789. obufpos = 0;
  1790. }
  1791. rbufpos--;
  1792. }
  1793. } else {
  1794. while(fpos < biglen) {
  1795. thispos = (int)floor(fpos);
  1796. nextpos = thispos+1;
  1797. fracpos = fpos - (double)thispos;
  1798. thisval = interpbuf[thispos];
  1799. valdiff = interpbuf[nextpos] - thisval;
  1800. val = thisval + (valdiff * fracpos);
  1801. obuf[obufpos++] = (float)(val * dz->param[DMARK_GAIN]);
  1802. if(obufpos >= dz->buflen) {
  1803. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1804. return(exit_status);
  1805. obufpos = 0;
  1806. }
  1807. fpos += advnc;
  1808. }
  1809. }
  1810. }
  1811. }
  1812. lastgpstt = gpstt;
  1813. lastgplen = gplen;
  1814. }
  1815. if(!done) {
  1816. seekto = (lastgpstt/F_SECSIZE) * F_SECSIZE;
  1817. if((sndseekEx(dz->ifd[0],seekto,0))<0) {
  1818. sprintf(errstr,"sndseek 5 failed.\n");
  1819. return GOAL_FAILED;
  1820. }
  1821. if((exit_status = read_samps(ibuf,dz))<0)
  1822. return(exit_status);
  1823. bufpos = lastgpstt - seekto; // Copy wavesetgroup to buffer B
  1824. while(dz->ssampsread > 0) {
  1825. while(bufpos < dz->ssampsread) {
  1826. obuf[obufpos++] = ibuf[bufpos++];
  1827. if(obufpos >= dz->buflen) {
  1828. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1829. return(exit_status);
  1830. obufpos = 0;
  1831. }
  1832. }
  1833. if((exit_status = read_samps(ibuf,dz))<0)
  1834. return(exit_status);
  1835. bufpos = 0;
  1836. }
  1837. }
  1838. if(obufpos > 0) {
  1839. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1840. return(exit_status);
  1841. }
  1842. return FINISHED;
  1843. }
  1844. /************************ GET_THE_MODE_NO *********************/
  1845. int get_the_mode_no(char *str, dataptr dz)
  1846. {
  1847. if(sscanf(str,"%d",&dz->mode)!=1) {
  1848. sprintf(errstr,"Cannot read mode of program.\n");
  1849. return(USAGE_ONLY);
  1850. }
  1851. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1852. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1853. return(USAGE_ONLY);
  1854. }
  1855. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1856. return(FINISHED);
  1857. }