isolate.c 107 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <structures.h>
  24. #include <tkglobals.h>
  25. #include <pnames.h>
  26. #include <filetype.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <logic.h>
  30. #include <globcon.h>
  31. #include <cdpmain.h>
  32. #include <math.h>
  33. #include <mixxcon.h>
  34. #include <osbind.h>
  35. #include <standalone.h>
  36. #include <ctype.h>
  37. #include <sfsys.h>
  38. #include <string.h>
  39. #include <srates.h>
  40. #define ISO_WINLEN 10 // envelope search-window 10 mS
  41. #ifdef unix
  42. #define round(x) lround((x))
  43. #endif
  44. char errstr[2400];
  45. int anal_infiles = 1;
  46. int sloom = 0;
  47. int sloombatch = 0;
  48. const char* cdp_version = "7.1.0";
  49. //CDP LIB REPLACEMENTS
  50. static int setup_isolate_application(dataptr dz);
  51. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  52. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  53. static int setup_isolate_param_ranges_and_defaults(dataptr dz);
  54. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  55. static int open_the_outfile(dataptr dz);
  56. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  57. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  58. static int establish_application(dataptr dz);
  59. static int initialise_vflags(dataptr dz);
  60. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  61. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  62. static int mark_parameter_types(dataptr dz,aplptr ap);
  63. static int assign_file_data_storage(int infilecnt,dataptr dz);
  64. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  65. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  66. static int get_the_mode_no(char *str,dataptr dz);
  67. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  68. static int handle_the_special_data(char *str,dataptr dz);
  69. static int check_the_param_validity_and_consistency(dataptr dz);
  70. static int isolate(dataptr dz);
  71. static int do_a_cut(int *cuts,int n,double spliceincr,dataptr dz);
  72. static int eliminate_abutted_cuts(int *cuts,dataptr dz);
  73. static int do_remnant_cut(int fileno,int *cuts,double spliceincr,dataptr dz);
  74. static int do_a_multicut(int n,double spliceincr,dataptr dz);
  75. static int convert_brkvals_db_to_gain(int paramno,dataptr dz);
  76. static int isolate_param_preprocess(dataptr dz);
  77. static double convert_gain_to_dB_from_minus96(double val);
  78. static int reverse_cuts(int *array,int itemcnt,dataptr dz);
  79. static int reverse_sndread(float *buf,int n, dataptr dz);
  80. /**************************************** MAIN *********************************************/
  81. int main(int argc,char *argv[])
  82. {
  83. int exit_status;
  84. dataptr dz = NULL;
  85. char **cmdline;
  86. int cmdlinecnt;
  87. int n;
  88. // aplptr ap;
  89. int is_launched = FALSE;
  90. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  91. fprintf(stdout,"%s\n",cdp_version);
  92. fflush(stdout);
  93. return 0;
  94. }
  95. /* CHECK FOR SOUNDLOOM */
  96. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  97. sloom = 0;
  98. sloombatch = 1;
  99. }
  100. if(sflinit("cdp")){
  101. sfperror("cdp: initialisation\n");
  102. return(FAILED);
  103. }
  104. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  105. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  106. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  107. return(FAILED);
  108. }
  109. if(!sloom) {
  110. if(argc == 1) {
  111. usage1();
  112. return(FAILED);
  113. } else if(argc == 2) {
  114. usage2(argv[1]);
  115. return(FAILED);
  116. }
  117. }
  118. if(!sloom) {
  119. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  120. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  121. return(FAILED);
  122. }
  123. cmdline = argv;
  124. cmdlinecnt = argc;
  125. if((get_the_process_no(argv[0],dz))<0) {
  126. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  127. return(FAILED);
  128. }
  129. cmdline++;
  130. cmdlinecnt--;
  131. dz->maxmode = 5;
  132. if((get_the_mode_no(cmdline[0],dz))<0) {
  133. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  134. return(FAILED);
  135. }
  136. cmdline++;
  137. cmdlinecnt--;
  138. // setup_particular_application =
  139. if((exit_status = setup_isolate_application(dz))<0) {
  140. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  141. return(FAILED);
  142. }
  143. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  144. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  145. return(FAILED);
  146. }
  147. } else {
  148. //parse_TK_data() =
  149. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  150. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  151. return(exit_status);
  152. }
  153. }
  154. // ap = dz->application;
  155. // parse_infile_and_hone_type() =
  156. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  157. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  158. return(FAILED);
  159. }
  160. // setup_param_ranges_and_defaults() =
  161. if((exit_status = setup_isolate_param_ranges_and_defaults(dz))<0) {
  162. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  163. return(FAILED);
  164. }
  165. // open_first_infile CDP LIB
  166. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  167. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  168. return(FAILED);
  169. }
  170. cmdlinecnt--;
  171. cmdline++;
  172. // handle_extra_infiles() : redundant
  173. // handle_outfile() =
  174. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  175. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  176. return(FAILED);
  177. }
  178. // handle_formants() redundant
  179. // handle_formant_quiksearch() redundant
  180. // handle_special_data()
  181. if(dz->mode != ISO_THRESH) {
  182. if((exit_status = handle_the_special_data(cmdline[0],dz))<0) {
  183. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  184. return(FAILED);
  185. }
  186. cmdlinecnt--;
  187. cmdline++;
  188. }
  189. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  190. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  191. return(FAILED);
  192. }
  193. // check_param_validity_and_consistency....
  194. if((exit_status = check_the_param_validity_and_consistency(dz))<0) {
  195. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  196. return(FAILED);
  197. }
  198. is_launched = TRUE;
  199. dz->bufcnt = 2;
  200. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  201. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  202. return(MEMORY_ERROR);
  203. }
  204. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  205. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  206. return(MEMORY_ERROR);
  207. }
  208. for(n = 0;n <dz->bufcnt; n++)
  209. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  210. dz->sampbuf[n] = (float *)0;
  211. if((exit_status = create_sndbufs(dz))<0) { // CDP LIB
  212. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  213. return(FAILED);
  214. }
  215. //param_preprocess()
  216. if(dz->mode == ISO_THRESH) {
  217. if((exit_status = isolate_param_preprocess(dz))<0) {
  218. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  219. return(FAILED);
  220. }
  221. }
  222. //spec_process_file =
  223. if((exit_status = open_the_outfile(dz))<0) {
  224. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  225. return(FAILED);
  226. }
  227. if((exit_status = isolate(dz))<0) {
  228. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  229. return(FAILED);
  230. }
  231. if((exit_status = complete_output(dz))<0) { // CDP LIB
  232. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  233. return(FAILED);
  234. }
  235. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  236. free(dz);
  237. return(SUCCEEDED);
  238. }
  239. /**********************************************
  240. REPLACED CDP LIB FUNCTIONS
  241. **********************************************/
  242. /****************************** SET_PARAM_DATA *********************************/
  243. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  244. {
  245. ap->special_data = (char)special_data;
  246. ap->param_cnt = (char)paramcnt;
  247. ap->max_param_cnt = (char)maxparamcnt;
  248. if(ap->max_param_cnt>0) {
  249. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  250. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  251. return(MEMORY_ERROR);
  252. }
  253. strcpy(ap->param_list,paramlist);
  254. }
  255. return(FINISHED);
  256. }
  257. /****************************** SET_VFLGS *********************************/
  258. int set_vflgs
  259. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  260. {
  261. ap->option_cnt = (char) optcnt; /*RWD added cast */
  262. if(optcnt) {
  263. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  264. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  265. return(MEMORY_ERROR);
  266. }
  267. strcpy(ap->option_list,optlist);
  268. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  269. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  270. return(MEMORY_ERROR);
  271. }
  272. strcpy(ap->option_flags,optflags);
  273. }
  274. ap->vflag_cnt = (char) vflagcnt;
  275. ap->variant_param_cnt = (char) vparamcnt;
  276. if(vflagcnt) {
  277. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  278. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  279. return(MEMORY_ERROR);
  280. }
  281. strcpy(ap->variant_list,varlist);
  282. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  283. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  284. return(MEMORY_ERROR);
  285. }
  286. strcpy(ap->variant_flags,varflags);
  287. }
  288. return(FINISHED);
  289. }
  290. /***************************** APPLICATION_INIT **************************/
  291. int application_init(dataptr dz)
  292. {
  293. int exit_status;
  294. int storage_cnt;
  295. int tipc, brkcnt;
  296. aplptr ap = dz->application;
  297. if(ap->vflag_cnt>0)
  298. initialise_vflags(dz);
  299. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  300. ap->total_input_param_cnt = (char)tipc;
  301. if(tipc>0) {
  302. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  303. return(exit_status);
  304. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  305. return(exit_status);
  306. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  307. return(exit_status);
  308. }
  309. brkcnt = tipc;
  310. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  311. if(brkcnt>0) {
  312. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  313. return(exit_status);
  314. }
  315. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  316. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  317. return(exit_status);
  318. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  319. return(exit_status);
  320. }
  321. if((exit_status = mark_parameter_types(dz,ap))<0)
  322. return(exit_status);
  323. // establish_infile_constants() replaced by
  324. dz->infilecnt = 1;
  325. //establish_bufptrs_and_extra_buffers():
  326. if((exit_status = setup_internal_arrays_and_array_pointers(dz))<0)
  327. return(exit_status);
  328. return(FINISHED);
  329. }
  330. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  331. /* RWD mallo changed to calloc; helps debug verison run as release! */
  332. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  333. {
  334. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  335. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  336. return(MEMORY_ERROR);
  337. }
  338. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  339. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  340. return(MEMORY_ERROR);
  341. }
  342. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  343. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  344. return(MEMORY_ERROR);
  345. }
  346. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  347. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  348. return(MEMORY_ERROR);
  349. }
  350. return(FINISHED);
  351. }
  352. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  353. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  354. {
  355. int n;
  356. for(n=0;n<storage_cnt;n++) {
  357. dz->is_int[n] = (char)0;
  358. dz->no_brk[n] = (char)0;
  359. }
  360. return(FINISHED);
  361. }
  362. /***************************** MARK_PARAMETER_TYPES **************************/
  363. int mark_parameter_types(dataptr dz,aplptr ap)
  364. {
  365. int n, m; /* PARAMS */
  366. for(n=0;n<ap->max_param_cnt;n++) {
  367. switch(ap->param_list[n]) {
  368. case('0'): break; /* dz->is_active[n] = 0 is default */
  369. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  370. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  371. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  372. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  373. default:
  374. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  375. return(PROGRAM_ERROR);
  376. }
  377. } /* OPTIONS */
  378. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  379. switch(ap->option_list[n]) {
  380. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  381. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  382. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  383. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  384. default:
  385. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  386. return(PROGRAM_ERROR);
  387. }
  388. } /* VARIANTS */
  389. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  390. switch(ap->variant_list[n]) {
  391. case('0'): break;
  392. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  393. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  394. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  395. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  396. default:
  397. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  398. return(PROGRAM_ERROR);
  399. }
  400. } /* INTERNAL */
  401. for(n=0,
  402. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  403. switch(ap->internal_param_list[n]) {
  404. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  405. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  406. case('d'): dz->no_brk[m] = (char)1; break;
  407. default:
  408. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  409. return(PROGRAM_ERROR);
  410. }
  411. }
  412. return(FINISHED);
  413. }
  414. /************************ HANDLE_THE_OUTFILE *********************/
  415. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  416. {
  417. int n;
  418. char *filename = (*cmdline)[0], *p;
  419. if(filename[0]=='-' && filename[1]=='f') {
  420. dz->floatsam_output = 1;
  421. dz->true_outfile_stype = SAMP_FLOAT;
  422. filename+= 2;
  423. }
  424. if(!sloom) {
  425. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  426. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  427. return(DATA_ERROR);
  428. }
  429. }
  430. p = filename; // Drop file extension
  431. while(*p != ENDOFSTR) {
  432. if(*p == '.') {
  433. *p = ENDOFSTR;
  434. break;
  435. }
  436. p++;
  437. }
  438. strcpy(dz->outfilename,filename);
  439. if(sloom) { // IF sloom, drop trailing zero
  440. n = strlen(dz->outfilename);
  441. n--;
  442. dz->outfilename[n] = ENDOFSTR;
  443. }
  444. (*cmdline)++;
  445. (*cmdlinecnt)--;
  446. return(FINISHED);
  447. }
  448. /************************ OPEN_THE_OUTFILE *********************/
  449. int open_the_outfile(dataptr dz)
  450. {
  451. int exit_status;
  452. char filename[200], temp[8];
  453. strcpy(filename,dz->outfilename);
  454. switch(dz->mode) {
  455. case(ISO_SEGMNT):
  456. case(ISO_SLICED):
  457. case(ISO_OVRLAP):
  458. if(dz->vflag[1]) {
  459. sprintf(temp,"%d",(dz->itemcnt/2) - 1);
  460. strcat(filename,temp);
  461. } else
  462. strcat(filename,"0");
  463. break;
  464. default:
  465. strcat(filename,"0");
  466. break;
  467. }
  468. if((exit_status = create_sized_outfile(filename,dz))<0)
  469. return(exit_status);
  470. return(FINISHED);
  471. }
  472. /***************************** ESTABLISH_APPLICATION **************************/
  473. int establish_application(dataptr dz)
  474. {
  475. aplptr ap;
  476. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  477. sprintf(errstr,"establish_application()\n");
  478. return(MEMORY_ERROR);
  479. }
  480. ap = dz->application;
  481. memset((char *)ap,0,sizeof(struct applic));
  482. return(FINISHED);
  483. }
  484. /************************* INITIALISE_VFLAGS *************************/
  485. int initialise_vflags(dataptr dz)
  486. {
  487. int n;
  488. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  489. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  490. return(MEMORY_ERROR);
  491. }
  492. for(n=0;n<dz->application->vflag_cnt;n++)
  493. dz->vflag[n] = FALSE;
  494. return FINISHED;
  495. }
  496. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  497. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  498. {
  499. int n;
  500. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  501. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  502. return(MEMORY_ERROR);
  503. }
  504. for(n=0;n<tipc;n++)
  505. ap->default_val[n] = 0.0;
  506. return(FINISHED);
  507. }
  508. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  509. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  510. {
  511. int n;
  512. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  513. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  514. return(MEMORY_ERROR);
  515. }
  516. for(n=0;n<tipc;n++)
  517. dz->is_active[n] = (char)0;
  518. return(FINISHED);
  519. }
  520. /************************* SETUP_ISOLATE_APPLICATION *******************/
  521. int setup_isolate_application(dataptr dz)
  522. {
  523. int exit_status;
  524. aplptr ap;
  525. if((exit_status = establish_application(dz))<0) // GLOBAL
  526. return(FAILED);
  527. ap = dz->application;
  528. // SEE parstruct FOR EXPLANATION of next 2 functions
  529. switch(dz->mode) {
  530. case(ISO_SEGMNT):
  531. if((exit_status = set_param_data(ap,ISOLATES,2,0,"00"))<0)
  532. return(FAILED);
  533. if((exit_status = set_vflgs(ap,"s",1,"d","xr",2,0,"00"))<0)
  534. return(FAILED);
  535. break;
  536. case(ISO_GROUPS):
  537. if((exit_status = set_param_data(ap,ISOGROUPS,2,0,"00"))<0)
  538. return(FAILED);
  539. if((exit_status = set_vflgs(ap,"s",1,"d","xr",2,0,"00"))<0)
  540. return(FAILED);
  541. break;
  542. case(ISO_SLICED):
  543. if((exit_status = set_param_data(ap,ISOSLICES,2,0,"00"))<0)
  544. return(FAILED);
  545. if((exit_status = set_vflgs(ap,"s",1,"d","xr",2,0,"00"))<0)
  546. return(FAILED);
  547. break;
  548. case(ISO_OVRLAP):
  549. if((exit_status = set_param_data(ap,ISOSYLLS,2,0,"00"))<0)
  550. return(FAILED);
  551. if((exit_status = set_vflgs(ap,"sd",2,"dd","xr",2,0,"00"))<0)
  552. return(FAILED);
  553. break;
  554. case(ISO_THRESH):
  555. if((exit_status = set_param_data(ap,0 ,2,2,"DD"))<0)
  556. return(FAILED);
  557. if((exit_status = set_vflgs(ap,"sml",3,"ddd","xr",2,0,"00"))<0)
  558. return(FAILED);
  559. break;
  560. }
  561. // set_legal_infile_structure -->
  562. dz->has_otherfile = FALSE;
  563. // assign_process_logic -->
  564. dz->input_data_type = SNDFILES_ONLY;
  565. dz->process_type = UNEQUAL_SNDFILE;
  566. dz->outfiletype = SNDFILE_OUT;
  567. return application_init(dz); //GLOBAL
  568. }
  569. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  570. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  571. {
  572. int exit_status;
  573. infileptr infile_info;
  574. if(!sloom) {
  575. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  576. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  577. return(MEMORY_ERROR);
  578. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  579. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  580. return(PROGRAM_ERROR);
  581. } else if(infile_info->filetype != SNDFILE) {
  582. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  583. return(DATA_ERROR);
  584. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  585. sprintf(errstr,"Failed to copy file parsing information\n");
  586. return(PROGRAM_ERROR);
  587. }
  588. free(infile_info);
  589. }
  590. return(FINISHED);
  591. }
  592. /************************* SETUP_ISOLATE_PARAM_RANGES_AND_DEFAULTS *******************/
  593. int setup_isolate_param_ranges_and_defaults(dataptr dz)
  594. {
  595. int exit_status;
  596. aplptr ap = dz->application;
  597. // set_param_ranges()
  598. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  599. // NB total_input_param_cnt is > 0 !!!
  600. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  601. return(FAILED);
  602. // get_param_ranges()
  603. switch(dz->mode) {
  604. case(ISO_OVRLAP):
  605. ap->lo[ISO_SPL] = 0;
  606. ap->hi[ISO_SPL] = 500;
  607. ap->default_val[ISO_SPL] = 15;
  608. ap->lo[ISO_DOV] = 0;
  609. ap->hi[ISO_DOV] = 20;
  610. ap->default_val[ISO_DOV] = 5;
  611. break;
  612. case(ISO_THRESH):
  613. ap->lo[ISO_THRON] = -60;
  614. ap->hi[ISO_THRON] = 0;
  615. ap->default_val[ISO_THRON] = 0;
  616. ap->lo[ISO_THROFF] = -96;
  617. ap->hi[ISO_THROFF] = 0;
  618. ap->default_val[ISO_THROFF] = -96;
  619. ap->lo[ISO_SPL] = 0;
  620. ap->hi[ISO_SPL] = 500;
  621. ap->default_val[ISO_SPL] = 15;
  622. ap->lo[ISO_MIN] = 20;
  623. ap->hi[ISO_MIN] = 500;
  624. ap->default_val[ISO_MIN] = 50;
  625. ap->lo[ISO_LEN] = 0;
  626. ap->hi[ISO_LEN] = 500;
  627. ap->default_val[ISO_LEN] = 0;
  628. break;
  629. default:
  630. ap->lo[ISO_SPL] = 0;
  631. ap->hi[ISO_SPL] = 500;
  632. ap->default_val[ISO_SPL] = 15;
  633. break;
  634. }
  635. if(!sloom)
  636. put_default_vals_in_all_params(dz);
  637. return(FINISHED);
  638. }
  639. /********************************* PARSE_SLOOM_DATA *********************************/
  640. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  641. {
  642. int exit_status;
  643. int cnt = 1, infilecnt;
  644. int filesize, insams, inbrksize;
  645. double dummy;
  646. int true_cnt = 0;
  647. // aplptr ap;
  648. while(cnt<=PRE_CMDLINE_DATACNT) {
  649. if(cnt > argc) {
  650. sprintf(errstr,"Insufficient data sent from TK\n");
  651. return(DATA_ERROR);
  652. }
  653. switch(cnt) {
  654. case(1):
  655. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  656. sprintf(errstr,"Cannot read process no. sent from TK\n");
  657. return(DATA_ERROR);
  658. }
  659. break;
  660. case(2):
  661. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  662. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  663. return(DATA_ERROR);
  664. }
  665. if(dz->mode > 0)
  666. dz->mode--;
  667. //setup_particular_application() =
  668. if((exit_status = setup_isolate_application(dz))<0)
  669. return(exit_status);
  670. // ap = dz->application;
  671. break;
  672. case(3):
  673. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  674. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  675. return(DATA_ERROR);
  676. }
  677. if(infilecnt < 1) {
  678. true_cnt = cnt + 1;
  679. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  680. }
  681. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  682. return(exit_status);
  683. break;
  684. case(INPUT_FILETYPE+4):
  685. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  686. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  687. return(DATA_ERROR);
  688. }
  689. break;
  690. case(INPUT_FILESIZE+4):
  691. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  692. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  693. return(DATA_ERROR);
  694. }
  695. dz->insams[0] = filesize;
  696. break;
  697. case(INPUT_INSAMS+4):
  698. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  699. sprintf(errstr,"Cannot read insams sent from TK\n");
  700. return(DATA_ERROR);
  701. }
  702. dz->insams[0] = insams;
  703. break;
  704. case(INPUT_SRATE+4):
  705. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  706. sprintf(errstr,"Cannot read srate sent from TK\n");
  707. return(DATA_ERROR);
  708. }
  709. break;
  710. case(INPUT_CHANNELS+4):
  711. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  712. sprintf(errstr,"Cannot read channels sent from TK\n");
  713. return(DATA_ERROR);
  714. }
  715. break;
  716. case(INPUT_STYPE+4):
  717. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  718. sprintf(errstr,"Cannot read stype sent from TK\n");
  719. return(DATA_ERROR);
  720. }
  721. break;
  722. case(INPUT_ORIGSTYPE+4):
  723. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  724. sprintf(errstr,"Cannot read origstype sent from TK\n");
  725. return(DATA_ERROR);
  726. }
  727. break;
  728. case(INPUT_ORIGRATE+4):
  729. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  730. sprintf(errstr,"Cannot read origrate sent from TK\n");
  731. return(DATA_ERROR);
  732. }
  733. break;
  734. case(INPUT_MLEN+4):
  735. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  736. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  737. return(DATA_ERROR);
  738. }
  739. break;
  740. case(INPUT_DFAC+4):
  741. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  742. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  743. return(DATA_ERROR);
  744. }
  745. break;
  746. case(INPUT_ORIGCHANS+4):
  747. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  748. sprintf(errstr,"Cannot read origchans sent from TK\n");
  749. return(DATA_ERROR);
  750. }
  751. break;
  752. case(INPUT_SPECENVCNT+4):
  753. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  754. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  755. return(DATA_ERROR);
  756. }
  757. dz->specenvcnt = dz->infile->specenvcnt;
  758. break;
  759. case(INPUT_WANTED+4):
  760. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  761. sprintf(errstr,"Cannot read wanted sent from TK\n");
  762. return(DATA_ERROR);
  763. }
  764. break;
  765. case(INPUT_WLENGTH+4):
  766. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  767. sprintf(errstr,"Cannot read wlength sent from TK\n");
  768. return(DATA_ERROR);
  769. }
  770. break;
  771. case(INPUT_OUT_CHANS+4):
  772. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  773. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  774. return(DATA_ERROR);
  775. }
  776. break;
  777. /* RWD these chanegs to samps - tk will have to deal with that! */
  778. case(INPUT_DESCRIPTOR_BYTES+4):
  779. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  780. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  781. return(DATA_ERROR);
  782. }
  783. break;
  784. case(INPUT_IS_TRANSPOS+4):
  785. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  786. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  787. return(DATA_ERROR);
  788. }
  789. break;
  790. case(INPUT_COULD_BE_TRANSPOS+4):
  791. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  792. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  793. return(DATA_ERROR);
  794. }
  795. break;
  796. case(INPUT_COULD_BE_PITCH+4):
  797. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  798. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  799. return(DATA_ERROR);
  800. }
  801. break;
  802. case(INPUT_DIFFERENT_SRATES+4):
  803. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  804. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  805. return(DATA_ERROR);
  806. }
  807. break;
  808. case(INPUT_DUPLICATE_SNDS+4):
  809. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  810. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  811. return(DATA_ERROR);
  812. }
  813. break;
  814. case(INPUT_BRKSIZE+4):
  815. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  816. sprintf(errstr,"Cannot read brksize sent from TK\n");
  817. return(DATA_ERROR);
  818. }
  819. if(inbrksize > 0) {
  820. switch(dz->input_data_type) {
  821. case(WORDLIST_ONLY):
  822. break;
  823. case(PITCH_AND_PITCH):
  824. case(PITCH_AND_TRANSPOS):
  825. case(TRANSPOS_AND_TRANSPOS):
  826. dz->tempsize = inbrksize;
  827. break;
  828. case(BRKFILES_ONLY):
  829. case(UNRANGED_BRKFILE_ONLY):
  830. case(DB_BRKFILES_ONLY):
  831. case(ALL_FILES):
  832. case(ANY_NUMBER_OF_ANY_FILES):
  833. if(dz->extrabrkno < 0) {
  834. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  835. return(DATA_ERROR);
  836. }
  837. if(dz->brksize == NULL) {
  838. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  839. return(PROGRAM_ERROR);
  840. }
  841. dz->brksize[dz->extrabrkno] = inbrksize;
  842. break;
  843. default:
  844. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  845. dz->input_data_type);
  846. return(PROGRAM_ERROR);
  847. }
  848. break;
  849. }
  850. break;
  851. case(INPUT_NUMSIZE+4):
  852. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  853. sprintf(errstr,"Cannot read numsize sent from TK\n");
  854. return(DATA_ERROR);
  855. }
  856. break;
  857. case(INPUT_LINECNT+4):
  858. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  859. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  860. return(DATA_ERROR);
  861. }
  862. break;
  863. case(INPUT_ALL_WORDS+4):
  864. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  865. sprintf(errstr,"Cannot read all_words sent from TK\n");
  866. return(DATA_ERROR);
  867. }
  868. break;
  869. case(INPUT_ARATE+4):
  870. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  871. sprintf(errstr,"Cannot read arate sent from TK\n");
  872. return(DATA_ERROR);
  873. }
  874. break;
  875. case(INPUT_FRAMETIME+4):
  876. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  877. sprintf(errstr,"Cannot read frametime sent from TK\n");
  878. return(DATA_ERROR);
  879. }
  880. dz->frametime = (float)dummy;
  881. break;
  882. case(INPUT_WINDOW_SIZE+4):
  883. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  884. sprintf(errstr,"Cannot read window_size sent from TK\n");
  885. return(DATA_ERROR);
  886. }
  887. break;
  888. case(INPUT_NYQUIST+4):
  889. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  890. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  891. return(DATA_ERROR);
  892. }
  893. break;
  894. case(INPUT_DURATION+4):
  895. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  896. sprintf(errstr,"Cannot read duration sent from TK\n");
  897. return(DATA_ERROR);
  898. }
  899. break;
  900. case(INPUT_MINBRK+4):
  901. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  902. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  903. return(DATA_ERROR);
  904. }
  905. break;
  906. case(INPUT_MAXBRK+4):
  907. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  908. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  909. return(DATA_ERROR);
  910. }
  911. break;
  912. case(INPUT_MINNUM+4):
  913. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  914. sprintf(errstr,"Cannot read minnum sent from TK\n");
  915. return(DATA_ERROR);
  916. }
  917. break;
  918. case(INPUT_MAXNUM+4):
  919. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  920. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  921. return(DATA_ERROR);
  922. }
  923. break;
  924. default:
  925. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  926. return(PROGRAM_ERROR);
  927. }
  928. cnt++;
  929. }
  930. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  931. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  932. return(DATA_ERROR);
  933. }
  934. if(true_cnt)
  935. cnt = true_cnt;
  936. *cmdlinecnt = 0;
  937. while(cnt < argc) {
  938. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  939. return(exit_status);
  940. cnt++;
  941. }
  942. return(FINISHED);
  943. }
  944. /********************************* GET_TK_CMDLINE_WORD *********************************/
  945. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  946. {
  947. if(*cmdlinecnt==0) {
  948. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  949. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  950. return(MEMORY_ERROR);
  951. }
  952. } else {
  953. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  954. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  955. return(MEMORY_ERROR);
  956. }
  957. }
  958. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  959. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  960. return(MEMORY_ERROR);
  961. }
  962. strcpy((*cmdline)[*cmdlinecnt],q);
  963. (*cmdlinecnt)++;
  964. return(FINISHED);
  965. }
  966. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  967. int assign_file_data_storage(int infilecnt,dataptr dz)
  968. {
  969. int exit_status;
  970. int no_sndfile_system_files = FALSE;
  971. dz->infilecnt = infilecnt;
  972. if((exit_status = allocate_filespace(dz))<0)
  973. return(exit_status);
  974. if(no_sndfile_system_files)
  975. dz->infilecnt = 0;
  976. return(FINISHED);
  977. }
  978. /************************* redundant functions: to ensure libs compile OK *******************/
  979. int assign_process_logic(dataptr dz)
  980. {
  981. return(FINISHED);
  982. }
  983. void set_legal_infile_structure(dataptr dz)
  984. {}
  985. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  986. {
  987. return(FINISHED);
  988. }
  989. int setup_internal_arrays_and_array_pointers(dataptr dz)
  990. {
  991. return(FINISHED);
  992. }
  993. int establish_bufptrs_and_extra_buffers(dataptr dz)
  994. {
  995. return(FINISHED);
  996. }
  997. int read_special_data(char *str,dataptr dz)
  998. {
  999. return(FINISHED);
  1000. }
  1001. int inner_loop
  1002. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1003. {
  1004. return(FINISHED);
  1005. }
  1006. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1007. {
  1008. return(FINISHED);
  1009. }
  1010. /******************************** USAGE1 ********************************/
  1011. int usage1(void)
  1012. {
  1013. usage2("isolate");
  1014. return(USAGE_ONLY);
  1015. }
  1016. /********************************************************************************************/
  1017. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1018. {
  1019. if(!strcmp(prog_identifier_from_cmdline,"isolate")) dz->process = ISOLATE;
  1020. else {
  1021. fprintf(stderr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1022. return(USAGE_ONLY);
  1023. }
  1024. return(FINISHED);
  1025. }
  1026. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1027. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1028. {
  1029. int n;
  1030. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1031. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1032. return(MEMORY_ERROR);
  1033. }
  1034. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1035. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1036. return(MEMORY_ERROR);
  1037. }
  1038. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1039. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1040. return(MEMORY_ERROR);
  1041. }
  1042. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1043. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1044. return(MEMORY_ERROR);
  1045. }
  1046. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1047. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1048. return(MEMORY_ERROR);
  1049. }
  1050. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1051. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1052. return(MEMORY_ERROR);
  1053. }
  1054. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1055. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1056. return(MEMORY_ERROR);
  1057. }
  1058. for(n=0;n<brkcnt;n++) {
  1059. dz->brk[n] = NULL;
  1060. dz->brkptr[n] = NULL;
  1061. dz->brkinit[n] = 0;
  1062. dz->brksize[n] = 0;
  1063. }
  1064. return(FINISHED);
  1065. }
  1066. /******************************** USAGE2 ********************************/
  1067. int usage2(char *str)
  1068. {
  1069. if(!strcmp(str,"isolate")) {
  1070. fprintf(stdout,
  1071. "USAGE:\n"
  1072. "isolate isolate 1-2 inf outnam cutsfile [-ssplice] [-x] [-r]\n"
  1073. "isolate isolate 3 inf outnam dBon dBoff [-ssplice] [-mmin] [-llen] [-x] [-r]\n"
  1074. "isolate isolate 4 inf outnam slicefile [-ssplice] [-x] [-r]\n"
  1075. "isolate isolate 5 inf outnam slicefile [-ssplice] [-ddovetail] [-x] [-r]\n"
  1076. "\n"
  1077. "Cut specified segments from input file, but retain silent surrounds\n"
  1078. "so chunks occur at same time in the outfiles, as in the input file.\n"
  1079. "Modes 1, 2 & 3 also generate file of all material left over after the cutting.\n"
  1080. "Original file reconstructible by mixing all these components.\n"
  1081. "INF Input soundfile\n"
  1082. "OUTNAM Generic outfile name. Outfiles numbered from 0\n"
  1083. "CUTSFILE/SLICEFILE \n"
  1084. "Mode 1 Creates SEVERAL output files each containing ONE segment of src. \n"
  1085. " Cutsfile is list of time-pairs,(start and end of each segment)\n"
  1086. " in time order, and not time-overlapped.\n"
  1087. "Mode 2 Can create output files each containing SEVERAL segment of src.\n"
  1088. " If a cutsfile line lists several time-pairs (start+end of segs),\n"
  1089. " ALL segments on that line will be output in a single file.\n"
  1090. " No time-pairs must overlap. Time-pairs on a line must be in time order.\n"
  1091. "Mode 3 Creates ONE output file consisting of SEVERAL disjunct segments.\n"
  1092. " Segment starts and ends located using threshold-on and -off parameters.\n"
  1093. " if \"len\" set, only start portion of segment (length \"len\") is kept.\n"
  1094. "\n"
  1095. " In modes 1-3, an EXTRA FILE OF REMNANTS (if any) is created.\n"
  1096. " Also, if cuts abutt or are so close that end+start splices overlap,\n"
  1097. " end of first cut moved back, and start of 2nd moved forward\n"
  1098. " so that they overlap by a single splicelength.\n"
  1099. "\n"
  1100. "Mode 4 Cuts the ENTIRE file into disjunct segments\n"
  1101. " Creating SEVERAL output files each containing ONE segment of src.\n"
  1102. " Slicefile is list of (increasing) times where sound is to be cut.\n"
  1103. "Mode 5 As mode 4: segments overlapped slightly (separates speech syllables).\n"
  1104. "\n"
  1105. "SPLICE Length of splice in mS (range 0 - 500 default 15)\n"
  1106. "DBON (Mode 3) dB level at which a segment is recognised to begin.\n"
  1107. "DBOFF (Mode 3) dB level where recognised seg triggered to end (less than DBON).\n"
  1108. "MIN (Mode 3) min duration in mS of segs to accept (> 2 * splicelen)\n"
  1109. "LEN (Mode 3) duration in mS of (part-)segment to actually keep (> 0)\n"
  1110. " If \"len\" not set, or set to zero, entire original segments are kept.\n"
  1111. "DOVETAIL (Mode 5) overlap of cut segments in mS (range 0 -20 default 5)\n"
  1112. "-x Add silence to ends of segments files, so they are same length as src\n"
  1113. "-r Reverse all cut-segment files (but not the remnant file)\n"
  1114. "\n");
  1115. } else
  1116. fprintf(stdout,"Unknown option '%s'\n",str);
  1117. return(USAGE_ONLY);
  1118. }
  1119. int usage3(char *str1,char *str2)
  1120. {
  1121. fprintf(stderr,"Insufficient parameters on command line.\n");
  1122. return(USAGE_ONLY);
  1123. }
  1124. /******************************** ISOLATE *********************************/
  1125. int isolate(dataptr dz)
  1126. {
  1127. int exit_status = CONTINUE, itemincr;
  1128. int *cuts = dz->lparray[0];
  1129. int n = 0, k, fileno, filefirst;
  1130. double spliceincr = 1.0/(double)dz->iparam[ISO_SPL];
  1131. char filename[200], thisnum[8];
  1132. switch(dz->mode) {
  1133. case(ISO_SEGMNT):
  1134. case(ISO_SLICED):
  1135. case(ISO_OVRLAP):
  1136. if(dz->vflag[1])
  1137. filefirst = (dz->itemcnt/2) - 1;
  1138. else
  1139. filefirst = 0;
  1140. break;
  1141. default:
  1142. filefirst = 0;
  1143. break;
  1144. }
  1145. fileno = filefirst;
  1146. fprintf(stdout,"INFO: Cutting segments\n");
  1147. fflush(stdout);
  1148. while(n < dz->itemcnt) {
  1149. if(fileno != filefirst) {
  1150. if(sndcloseEx(dz->ofd) < 0) {
  1151. sprintf(errstr,"Failed to close output file %d\n",fileno+1);
  1152. return(SYSTEM_ERROR);
  1153. }
  1154. dz->ofd = -1;
  1155. strcpy(filename,dz->outfilename);
  1156. sprintf(thisnum,"%d",fileno);
  1157. strcat(filename,thisnum);
  1158. strcat(filename,".wav");
  1159. if((exit_status = create_sized_outfile(filename,dz))<0)
  1160. return(exit_status);
  1161. sndseekEx(dz->ifd[0],0,0);
  1162. reset_filedata_counters(dz);
  1163. } else if(dz->vflag[1]) { // If output cutfiles are to be time-reversed, reverse the cut-arrays
  1164. switch(dz->mode) {
  1165. case(ISO_GROUPS):
  1166. case(ISO_THRESH):
  1167. for(k=0;k<dz->itemcnt;k++) {
  1168. if((exit_status = reverse_cuts(dz->lparray[k],dz->iparray[0][k],dz))<0)
  1169. return(exit_status);
  1170. }
  1171. break;
  1172. default:
  1173. if((exit_status = reverse_cuts(dz->lparray[0],dz->itemcnt,dz))<0)
  1174. return(exit_status);
  1175. break;
  1176. }
  1177. }
  1178. switch(dz->mode) {
  1179. case(ISO_GROUPS):
  1180. case(ISO_THRESH):
  1181. if((exit_status = do_a_multicut(n,spliceincr,dz))< 0)
  1182. return exit_status;
  1183. itemincr = 1; // Moves line by line up cut values
  1184. break;
  1185. default:
  1186. if((exit_status = do_a_cut(cuts,n,spliceincr,dz))< 0)
  1187. return exit_status;
  1188. itemincr = 2; // Moves pair by pair up cut values
  1189. break;
  1190. }
  1191. sndseekEx(dz->ifd[0],0,0);
  1192. reset_filedata_counters(dz);
  1193. switch(dz->mode) {
  1194. case(ISO_SEGMNT):
  1195. if(dz->vflag[1]) {
  1196. if(fileno > 0)
  1197. fileno--;
  1198. else
  1199. fileno = dz->itemcnt/2;
  1200. } else
  1201. fileno++;
  1202. break;
  1203. case(ISO_SLICED):
  1204. case(ISO_OVRLAP):
  1205. if(dz->vflag[1])
  1206. fileno--;
  1207. else
  1208. fileno++;
  1209. break;
  1210. default:
  1211. fileno++;
  1212. break;
  1213. }
  1214. n += itemincr;
  1215. if(exit_status == FINISHED)
  1216. break;
  1217. }
  1218. if(sndcloseEx(dz->ofd) < 0) {
  1219. sprintf(errstr,"Failed to close output file %d\n",fileno+1);
  1220. return(SYSTEM_ERROR);
  1221. }
  1222. dz->ofd = -1;
  1223. switch(dz->mode ) {
  1224. case(ISO_GROUPS): // As the array of ALL the cuts is never reversed, no need to re-reverse here.
  1225. cuts = dz->lparray[dz->itemcnt]; // This is the array with all the cuts sorted into order
  1226. dz->itemcnt = dz->specenvcnt; // itemcnt was the the cnt of arrays: replace it with the total count of cuts
  1227. return do_remnant_cut(fileno,cuts,spliceincr,dz);
  1228. break;
  1229. case(ISO_THRESH):
  1230. if(dz->vflag[1]) { // As array of cuts was reversed, need to re-reverse here
  1231. if((exit_status = reverse_cuts(dz->lparray[0],dz->specenvcnt,dz))<0)
  1232. return(exit_status);
  1233. }
  1234. cuts = dz->lparray[0]; // Do remnant cut on the initial (only) array
  1235. dz->itemcnt = dz->specenvcnt; // itemcnt was the the cnt of arrays (1): replace it with the count of cuts
  1236. return do_remnant_cut(fileno,cuts,spliceincr,dz);
  1237. break;
  1238. case(ISO_SEGMNT):
  1239. if(dz->vflag[1]) { // As array of cuts was reversed, need to re-reverse here
  1240. if((exit_status = reverse_cuts(dz->lparray[0],dz->itemcnt,dz))<0)
  1241. return(exit_status);
  1242. }
  1243. return do_remnant_cut(fileno,cuts,spliceincr,dz);
  1244. break;
  1245. }
  1246. return FINISHED;
  1247. }
  1248. /******************************** CHECK_THE_PARAM_VALIDITY_AND_CONSISTENCY *********************************
  1249. *
  1250. * If 2 cuts abutt, or their end-splice and start-splice overlap
  1251. * the cut times are moved to be a while splicelen apart.
  1252. */
  1253. int check_the_param_validity_and_consistency(dataptr dz)
  1254. {
  1255. int exit_status;
  1256. int *cuts, *allcuts, gap, halfgap, temp1, temp2, origcutstt, origcutend;
  1257. int *linecnts, gotit = 0;
  1258. int chans = dz->infile->channels, halfsplen, dblsplen, /*dblsplcnt,*/ n, m, j, cnt, totalcnt;
  1259. double srate = (double)dz->infile->srate;
  1260. dz->param[ISO_SPL] *= MS_TO_SECS;
  1261. dz->iparam[ISO_SPL] = (int)round(dz->param[ISO_SPL] * srate);
  1262. dz->iparam[ISO_SPL] = (dz->iparam[ISO_SPL] / 2) * 2; // splicelen must be divisible by 2, for seg separation algo to work
  1263. if(dz->mode == ISO_THRESH) {
  1264. dz->param[ISO_LEN] *= MS_TO_SECS;
  1265. dz->iparam[ISO_LEN] = (int)round(dz->param[ISO_LEN] * srate) * chans;
  1266. dz->param[ISO_MIN] *= MS_TO_SECS;
  1267. dz->iparam[ISO_MIN] = (int)round(dz->param[ISO_MIN] * srate) * chans;
  1268. if(dz->iparam[ISO_MIN] <= dz->iparam[ISO_SPL] * chans * 2) {
  1269. sprintf(errstr,"Minimum seglen (%lf) must be > 2 * splicelen (%lf)\n",dz->param[ISO_MIN],2 * dz->param[ISO_SPL]);
  1270. return(DATA_ERROR);
  1271. }
  1272. if(!(dz->brksize[ISO_THRON] || dz->brksize[ISO_THROFF])) {
  1273. if(dz->param[ISO_THRON] <= dz->param[ISO_THROFF]) {
  1274. sprintf(errstr,"On (%lf) and Off (%lf) thresholds are incompatible\n",dz->param[ISO_THRON],dz->param[ISO_THROFF]);
  1275. return(DATA_ERROR);
  1276. }
  1277. }
  1278. if(dz->brksize[ISO_THRON])
  1279. exit_status = convert_brkvals_db_to_gain(ISO_THRON,dz);
  1280. else
  1281. exit_status = convert_dB_at_or_below_zero_to_gain(&(dz->param[ISO_THRON]));
  1282. if(exit_status < 0)
  1283. return(exit_status);
  1284. if(dz->brksize[ISO_THROFF])
  1285. exit_status = convert_brkvals_db_to_gain(ISO_THROFF,dz);
  1286. else
  1287. exit_status = convert_dB_at_or_below_zero_to_gain(&(dz->param[ISO_THROFF]));
  1288. return exit_status;
  1289. }
  1290. cuts = dz->lparray[0];
  1291. halfsplen = dz->iparam[ISO_SPL]/2; // half number of sample-groups in splice
  1292. dblsplen = dz->iparam[ISO_SPL] * 2; // length of two splices in sample-groups
  1293. // dblsplcnt = dblsplen * chans; // length of two splices in samples
  1294. dz->iparam[ISO_SPL] = dz->iparam[ISO_SPL];
  1295. switch(dz->mode) {
  1296. case(ISO_SEGMNT):
  1297. for(n=2;n < dz->itemcnt;n+=2) {
  1298. gap = (cuts[n] - cuts[n-1])/chans;
  1299. if(gap < dblsplen) { // If cuts abutt, or their splices overlap
  1300. halfgap = gap/2; // Move them to the same position
  1301. cuts[n-1] += halfgap * chans; // midway between end of 1st and start of 2nd
  1302. cuts[n-1] -= halfsplen * chans; // Then move them apart, the 1st halfsplcelen back
  1303. cuts[n] -= halfgap * chans; // The 2nd halfsplicelen forward
  1304. cuts[n] += halfsplen * chans; // If the gap was an odd number of samples, adjust 2nd by 1 sample-group
  1305. if(ODD(gap))
  1306. cuts[n] -= chans;
  1307. if(cuts[n-1] - cuts[n-2] < 0) { // and check if either of shortened cuts is now reduced to <= zero
  1308. sprintf(errstr,"Adjusting position of abutted cuts %d and %d makes 1st cut disappear\n",(n/2 - 1),n/2);
  1309. return(DATA_ERROR);
  1310. }
  1311. if(cuts[n+1] - cuts[n] < 0) {
  1312. sprintf(errstr,"Adjusting position of abutted cuts %d and %d makes 2nd cut disappear\n",(n/2 - 1),n/2);
  1313. return(DATA_ERROR);
  1314. }
  1315. }
  1316. }
  1317. if(cuts[dz->itemcnt-1] > dz->insams[0]) // Ensure last cut is before end or at end
  1318. cuts[dz->itemcnt-1] = dz->insams[0];
  1319. break;
  1320. case(ISO_GROUPS):
  1321. linecnts = dz->iparray[0];
  1322. for(m=0;m < dz->itemcnt;m++) {
  1323. cuts = dz->lparray[m];
  1324. for(n=2;n < linecnts[m];n+=2) {
  1325. gap = (cuts[n] - cuts[n-1])/chans;
  1326. if(gap < dblsplen) { // If cuts abutt, or their splices overlap, error
  1327. sprintf(errstr,"Segments %d and %d on line %d overlap\n",(n/2),(n/2)+1,m+1);
  1328. return DATA_ERROR;
  1329. }
  1330. }
  1331. if(cuts[linecnts[m]-1] > dz->insams[0]) // Ensure last cut is before end or at end
  1332. cuts[linecnts[m]-1] = dz->insams[0];
  1333. }
  1334. allcuts = dz->lparray[dz->itemcnt]; // Copy all cuts to same array
  1335. totalcnt = 0;
  1336. for(m=0;m < dz->itemcnt;m++) {
  1337. cuts = dz->lparray[m];
  1338. cnt = linecnts[m];
  1339. memcpy((char *)(allcuts + totalcnt),(char *)cuts,cnt * sizeof(int));
  1340. totalcnt += cnt;
  1341. }
  1342. dz->specenvcnt = totalcnt;
  1343. for(n=0;n < totalcnt-2;n+=2) { // Sort into ascending order
  1344. for(m=n+2;m<totalcnt;m+=2) {
  1345. if(allcuts[m] < allcuts[n]) {
  1346. temp1 = allcuts[n];
  1347. temp2 = allcuts[n+1];
  1348. allcuts[n] = allcuts[m];
  1349. allcuts[n+1] = allcuts[m+1];
  1350. allcuts[m] = temp1;
  1351. allcuts[m+1] = temp2;
  1352. }
  1353. }
  1354. }
  1355. for(n=2;n < totalcnt;n+=2) { // Ensure cuts in different files do NOT overlap
  1356. gap = (allcuts[n] - allcuts[n-1])/chans;
  1357. if(gap < 0) {
  1358. sprintf(errstr,"Two of segments in different outfiles overlap one another.\n");
  1359. return(DATA_ERROR);
  1360. }
  1361. if(gap < dblsplen) {
  1362. origcutstt = allcuts[n];
  1363. origcutend = allcuts[n-1];
  1364. halfgap = gap/2; // Move them to the same position
  1365. allcuts[n-1] += halfgap * chans; // midway between end of 1st and start of 2nd
  1366. allcuts[n-1] -= halfsplen * chans; // Then move them apart, the 1st halfsplcelen back
  1367. allcuts[n] -= halfgap * chans; // The 2nd halfsplicelen forward
  1368. allcuts[n] += halfsplen * chans; // If the gap was an odd number of samples, adjust 2nd by 1 sample-group
  1369. if(ODD(gap))
  1370. allcuts[n] -= chans;
  1371. if(allcuts[n-1] - allcuts[n-2] < 0) { // and check if either of shortened cuts is shortened to < zero
  1372. sprintf(errstr,"Adjusting position of abutted cuts makes 1st cut disappear\n");
  1373. return(DATA_ERROR);
  1374. }
  1375. if(allcuts[n+1] - allcuts[n] < 0) {
  1376. sprintf(errstr,"Adjusting position of abutted makes 2nd cut disappear\n");
  1377. return(DATA_ERROR);
  1378. }
  1379. gotit = 0;
  1380. for(m = 0;m < dz->itemcnt;m++) { // Find cuts in original arrays and move them!!
  1381. cuts = dz->lparray[m];
  1382. for(j=0;j < linecnts[m];j+=2) {
  1383. if(cuts[j] == origcutstt) {
  1384. cuts[j] = allcuts[n];
  1385. gotit = 1;
  1386. break;
  1387. }
  1388. }
  1389. if(gotit)
  1390. break;
  1391. }
  1392. gotit = 0;
  1393. for(m = 0;m < dz->itemcnt;m++) {
  1394. cuts = dz->lparray[m];
  1395. for(j=1;j < linecnts[m];j+=2) {
  1396. if(cuts[j] == origcutend) {
  1397. cuts[j] = allcuts[n-1];
  1398. gotit = 1;
  1399. break;
  1400. }
  1401. }
  1402. if(gotit)
  1403. break;
  1404. }
  1405. }
  1406. }
  1407. break;
  1408. case(ISO_SLICED):
  1409. if(cuts[0] != 0) { // If no sliuce at zero time
  1410. for(n=dz->itemcnt;n > 0;n--) // Force a slice
  1411. cuts[n] = cuts[n-1]; // By shuffling values up
  1412. cuts[0] = 0; // and inserting 0 value at start
  1413. dz->itemcnt++;
  1414. }
  1415. if(cuts[dz->itemcnt-1] >= dz->insams[0]) // Ensure last cut is before end or at end
  1416. dz->itemcnt--;
  1417. m = (dz->itemcnt * 2) - 1;
  1418. cuts[m--] = dz->insams[0]; // Put end of last seg at end of file
  1419. for(n=dz->itemcnt-1;n>0;n--) {
  1420. cuts[m--] = cuts[n]; // Copy previous slice time to seg-start
  1421. cuts[m--] = cuts[n]; // Copy same slice time as previous segend
  1422. } // cuts[0] = 0, stays where it is
  1423. dz->itemcnt *= 2;
  1424. for(n=2;n < dz->itemcnt;n+=2) { // Dis-abutt, as above
  1425. if(dz->iparam[ISO_SPL] == 0) {
  1426. if(cuts[n-1] - cuts[n-2] == 0) {
  1427. sprintf(errstr,"With zero splice, abutted cuts %d and %d produce a zero length segment\n",(n/2)-1,n/2);
  1428. return(DATA_ERROR);
  1429. }
  1430. if(cuts[n+1] - cuts[n] == 0) {
  1431. sprintf(errstr,"With zero splice, abutted cuts %d and %d produce a zero length segment\n",(n/2),n/2+1);
  1432. return(DATA_ERROR);
  1433. }
  1434. } else {
  1435. cuts[n-1] -= halfsplen * chans;
  1436. cuts[n] += halfsplen * chans;
  1437. if(cuts[n-1] - cuts[n-2] < 0) {
  1438. sprintf(errstr,"Adjusting position of abutted cuts %d and %d makes 1st shrink to zero\n",(n/2)-1,n/2);
  1439. return(DATA_ERROR);
  1440. }
  1441. if(cuts[n+1] - cuts[n] < 0) {
  1442. sprintf(errstr,"Adjusting position of abutted cuts %d and %d makes 2nd shrink to zero\n",n/2,(n/2)+1);
  1443. return(DATA_ERROR);
  1444. }
  1445. }
  1446. }
  1447. break;
  1448. case(ISO_OVRLAP):
  1449. if(cuts[0] != 0) { // If no sliuce at zero time
  1450. for(n=dz->itemcnt;n > 0;n--) // Force a slice
  1451. cuts[n] = cuts[n-1]; // By shuffling values up
  1452. cuts[0] = 0; // and inserting 0 value at start
  1453. dz->itemcnt++;
  1454. }
  1455. if(cuts[dz->itemcnt-1] >= dz->insams[0]) // Remove endcut if its at or before soundend
  1456. dz->itemcnt--;
  1457. m = (dz->itemcnt * 2) - 1;
  1458. cuts[m--] = dz->insams[0]; // Put end of last seg at end of file
  1459. for(n=dz->itemcnt-1;n>0;n--) {
  1460. cuts[m--] = cuts[n]; // Copy previous slice time to seg-start
  1461. cuts[m--] = cuts[n]; // Copy same slice time as previous segend
  1462. } // cuts[0] = 0, stays where it is
  1463. dz->itemcnt *= 2; // For syllable separation, add dovetails
  1464. dz->param[ISO_DOV] *= MS_TO_SECS;
  1465. dz->iparam[ISO_DOV] = (int)round(dz->param[ISO_DOV] * srate * chans);
  1466. for(n=0;n < dz->itemcnt;n+=2) {
  1467. cuts[n] = max(0,cuts[n] - dz->iparam[ISO_DOV]);
  1468. cuts[n+1] = min(dz->insams[0],cuts[n+1] + dz->iparam[ISO_DOV]);
  1469. }
  1470. break;
  1471. }
  1472. return FINISHED;
  1473. }
  1474. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  1475. int handle_the_special_data(char *str,dataptr dz)
  1476. {
  1477. int done, iseven;
  1478. double dummy = 0.0, lasttime = 0.0;
  1479. int *q;
  1480. FILE *fp;
  1481. int cnt, origcnt, totalcnt, linecnt;
  1482. char temp[200], *p;
  1483. if((fp = fopen(str,"r"))==NULL) {
  1484. sprintf(errstr,"Cannot open file %s to read template.\n",str);
  1485. return(DATA_ERROR);
  1486. }
  1487. switch(dz->mode) {
  1488. case(ISO_SEGMNT):
  1489. case(ISO_SLICED):
  1490. case(ISO_OVRLAP):
  1491. cnt = 0;
  1492. done = 0;
  1493. lasttime = -1;
  1494. iseven = 1;
  1495. while(fgets(temp,200,fp)!=NULL) {
  1496. p = temp;
  1497. if(*p == ';') // Allow comments in file
  1498. continue;
  1499. while(get_float_from_within_string(&p,&dummy)) {
  1500. if(dummy < 0.0) {
  1501. sprintf(errstr,"Time (%lf)less than zero in cuts file.\n",dummy);
  1502. return(DATA_ERROR);
  1503. } else if(dummy >= dz->duration) {
  1504. if(cnt == 0) {
  1505. sprintf(errstr,"First cut is beyond end of file\n");
  1506. return(DATA_ERROR);
  1507. } else if(iseven) {
  1508. fprintf(stdout,"WARNING: some of cut times are beyond end of input file: ignoring these\n");
  1509. fflush(stdout);
  1510. done = 1;
  1511. break;
  1512. } else { // Keep any cut extending beyond file end, and break from loop
  1513. iseven = !iseven;
  1514. cnt++;
  1515. done = 1;
  1516. break;
  1517. }
  1518. }
  1519. if(dz->mode == ISO_SEGMNT) {
  1520. if(iseven) {
  1521. if(dummy < lasttime) {
  1522. sprintf(errstr,"End of cut %d (%lf) and start of cut %d (%lf) overlap.\n",cnt/2,lasttime,(cnt/2 + 1),dummy);
  1523. return(DATA_ERROR);
  1524. }
  1525. } else {
  1526. if(dummy <= lasttime) {
  1527. sprintf(errstr,"Cut portion %d (%lf %lf) length less than or equal to zero.\n",(cnt/2 + 1),lasttime,dummy);
  1528. return(DATA_ERROR);
  1529. }
  1530. }
  1531. } else {
  1532. if(dummy <= lasttime) {
  1533. sprintf(errstr,"Times (%lf & %lf) not in ascending order.\n",lasttime,dummy);
  1534. return(DATA_ERROR);
  1535. }
  1536. }
  1537. lasttime = dummy;
  1538. iseven = !iseven;
  1539. cnt++;
  1540. }
  1541. if(done)
  1542. break;
  1543. }
  1544. if(cnt == 0) {
  1545. sprintf(errstr,"No valid times in file.\n");
  1546. return(DATA_ERROR);
  1547. }
  1548. dz->itemcnt = cnt;
  1549. origcnt = cnt;
  1550. if(dz->mode == ISO_SEGMNT) { // Cut times must be paired
  1551. if(!iseven) {
  1552. sprintf(errstr,"Invalid time pairing (odd number of times) in file.\n");
  1553. return(DATA_ERROR);
  1554. }
  1555. } else {
  1556. cnt = (cnt + 1) * 2; // Each slice time will generate a pair of values, with an extra pair at end
  1557. }
  1558. dz->larray_cnt = 1;
  1559. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1560. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer arrays.\n");
  1561. return(MEMORY_ERROR);
  1562. }
  1563. if((dz->lparray[0] = (int *)malloc(cnt * sizeof(int)))==NULL) {
  1564. sprintf(errstr,"INSUFFICIENT MEMORY to store segment cuts.\n");
  1565. return(MEMORY_ERROR);
  1566. }
  1567. fseek(fp,0,0);
  1568. done = 0;
  1569. cnt = 0;
  1570. q = dz->lparray[0];
  1571. while(fgets(temp,200,fp)!=NULL) {
  1572. p = temp;
  1573. if(*p == ';') // Allow comments in file
  1574. continue;
  1575. while(get_float_from_within_string(&p,&dummy)) {
  1576. *q = (int)round(dummy * (double)(dz->infile->srate)) * dz->infile->channels;
  1577. q++;
  1578. if(++cnt >= origcnt) {
  1579. done = 1;
  1580. break;
  1581. }
  1582. }
  1583. if(done)
  1584. break;
  1585. }
  1586. break;
  1587. case(ISO_GROUPS):
  1588. totalcnt = 0;
  1589. linecnt = 0;
  1590. while(fgets(temp,200,fp)!=NULL) {
  1591. p = temp;
  1592. if(*p == ';') // Allow comments in file
  1593. continue;
  1594. iseven = 1;
  1595. done = 0;
  1596. cnt = 0;
  1597. lasttime = -1;
  1598. while(get_float_from_within_string(&p,&dummy)) {
  1599. if(dummy < 0.0) {
  1600. sprintf(errstr,"Time (%lf)less than zero in cuts file.\n",dummy);
  1601. return(DATA_ERROR);
  1602. } else if(dummy >= dz->duration) {
  1603. if(cnt == 0) {
  1604. sprintf(errstr,"First cut is beyond end of file\n");
  1605. return(DATA_ERROR);
  1606. } else if(iseven) {
  1607. fprintf(stdout,"WARNING: some of cut times are beyond end of input file: ignoring these\n");
  1608. fflush(stdout);
  1609. done = 1;
  1610. break;
  1611. } else { // Keep any cut extending beyond file end, and break from loop
  1612. cnt++;
  1613. iseven = !iseven;
  1614. done = 1;
  1615. break;
  1616. }
  1617. }
  1618. if(iseven) {
  1619. if(dummy < lasttime) {
  1620. sprintf(errstr,"End of cut %d (%lf) and start of cut %d (%lf) overlap.\n",cnt/2,lasttime,(cnt/2 + 1),dummy);
  1621. return(DATA_ERROR);
  1622. }
  1623. } else {
  1624. if(dummy <= lasttime) {
  1625. sprintf(errstr,"Cut portion %d (%lf %lf) length less than or equal to zero.\n",(cnt/2 + 1),lasttime,dummy);
  1626. return(DATA_ERROR);
  1627. }
  1628. }
  1629. lasttime = dummy;
  1630. iseven = !iseven;
  1631. cnt++;
  1632. }
  1633. if(cnt > 0) {
  1634. if(!iseven) {
  1635. sprintf(errstr,"Invalid time pairing (odd number of times) on line %d\n",linecnt);
  1636. return(DATA_ERROR);
  1637. }
  1638. totalcnt += cnt;
  1639. linecnt++;
  1640. }
  1641. }
  1642. if(linecnt == 0) {
  1643. sprintf(errstr,"No valid lines found in file\n");
  1644. return(DATA_ERROR);
  1645. }
  1646. dz->itemcnt = linecnt;
  1647. dz->iarray_cnt = 1;
  1648. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  1649. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer arrays.\n");
  1650. return(MEMORY_ERROR);
  1651. }
  1652. if((dz->iparray[0] = (int *)malloc(linecnt * sizeof(int)))==NULL) { // Store length of each cuts store
  1653. sprintf(errstr,"INSUFFICIENT MEMORY to store lengths of cut-groups.\n");
  1654. return(MEMORY_ERROR);
  1655. }
  1656. dz->larray_cnt = linecnt+1;
  1657. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  1658. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1659. return(MEMORY_ERROR);
  1660. }
  1661. if((dz->lparray[linecnt] = (int *)malloc(totalcnt * sizeof(int)))==NULL) { // This array used later to compare ALL cuts
  1662. sprintf(errstr,"INSUFFICIENT MEMORY so store cut-groups.\n");
  1663. return(MEMORY_ERROR);
  1664. }
  1665. linecnt = 0;
  1666. fseek(fp,0,0);
  1667. while(fgets(temp,200,fp)!=NULL) {
  1668. p = temp;
  1669. if(*p == ';') // Allow comments in file
  1670. continue;
  1671. iseven = 1;
  1672. done = 0;
  1673. cnt = 0;
  1674. lasttime = -1;
  1675. while(get_float_from_within_string(&p,&dummy)) {
  1676. if(dummy >= dz->duration) {
  1677. if(iseven) {
  1678. done = 1;
  1679. break;
  1680. } else { // Keep any cut extending beyond file end, and break from loop
  1681. cnt++;
  1682. iseven = !iseven;
  1683. done = 1;
  1684. break;
  1685. }
  1686. }
  1687. lasttime = dummy;
  1688. iseven = !iseven;
  1689. cnt++;
  1690. }
  1691. if(cnt > 0) {
  1692. dz->iparray[0][linecnt] = cnt;
  1693. if((dz->lparray[linecnt] = (int *)malloc(cnt * sizeof(int)))==NULL) {
  1694. sprintf(errstr,"INSUFFICIENT MEMORY count of line %d.\n",linecnt+1);
  1695. return(MEMORY_ERROR);
  1696. }
  1697. linecnt++;
  1698. }
  1699. }
  1700. fseek(fp,0,0);
  1701. linecnt = 0;
  1702. while(fgets(temp,200,fp)!=NULL) {
  1703. p = temp;
  1704. if(*p == ';') // Allow comments in file
  1705. continue;
  1706. iseven = 1;
  1707. done = 0;
  1708. cnt = 0;
  1709. lasttime = -1;
  1710. q = dz->lparray[linecnt];
  1711. while(get_float_from_within_string(&p,&dummy)) {
  1712. if(dummy >= dz->duration) {
  1713. if(iseven) {
  1714. done = 1;
  1715. break;
  1716. } else { // Keep any cut extending beyond file end, and break from loop
  1717. *q = (int)round(dummy * (double)(dz->infile->srate)) * dz->infile->channels;
  1718. cnt++;
  1719. iseven = !iseven;
  1720. done = 1;
  1721. break;
  1722. }
  1723. }
  1724. *q++ = (int)round(dummy * (double)(dz->infile->srate)) * dz->infile->channels;
  1725. lasttime = dummy;
  1726. iseven = !iseven;
  1727. cnt++;
  1728. }
  1729. if(cnt > 0)
  1730. linecnt++;
  1731. }
  1732. break;
  1733. }
  1734. if(fclose(fp)<0) {
  1735. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",str);
  1736. fflush(stdout);
  1737. }
  1738. return(FINISHED);
  1739. }
  1740. /******************************** DO_A_CUT *********************************/
  1741. int do_a_cut(int *cuts,int n,double spliceincr,dataptr dz)
  1742. {
  1743. int exit_status, do_continue = 1, bufcnt = 0;
  1744. int chans = dz->infile->channels, splicelen = dz->iparam[ISO_SPL], dostartsplice = 0, doendsplice = 0, k, j;
  1745. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  1746. int thisstart, thisend, tocopy, bufremain, last_total_samps_read, hereinbuf;
  1747. double splicer;
  1748. if(dz->vflag[1]) {
  1749. bufcnt = dz->insams[0]/dz->buflen;
  1750. if(bufcnt * dz->buflen == dz->insams[0])
  1751. bufcnt--;
  1752. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  1753. return(exit_status);
  1754. bufcnt--;
  1755. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  1756. return(exit_status);
  1757. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1758. thisstart = cuts[n];
  1759. if(cuts[n] >= splicelen * chans) { // If room to do splice, move to splice start, and flag startsplicing
  1760. thisstart -= (splicelen * chans);
  1761. dostartsplice = 1;
  1762. } else { // If no room to do splice
  1763. thisstart = 0; // extend cut-portion back to start of file
  1764. dostartsplice = 0; // and flag NO startsplice
  1765. }
  1766. thisend = cuts[n+1]; // If room to do splice, move to splice start, and flag endsplicing
  1767. if(dz->insams[0] - cuts[n+1] >= splicelen * chans)
  1768. doendsplice = 1;
  1769. else { // If no room to do splice
  1770. thisend = dz->insams[0]; // extend (or curtial) end of cut-portion to end of file
  1771. doendsplice = 0; // and flag NO endsplice
  1772. do_continue = 0; // and flag quit cuttings
  1773. }
  1774. while(thisstart >= dz->total_samps_read) {
  1775. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  1776. return(exit_status); // Write anything that's left in buffer & then
  1777. if(dz->vflag[1]) { // zeros in any space before start of cut
  1778. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  1779. return(exit_status);
  1780. bufcnt--;
  1781. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  1782. return(exit_status);
  1783. if(dz->ssampsread == 0) {
  1784. sprintf(errstr,"Error 1 in sample read accounting.\n");
  1785. return(PROGRAM_ERROR);
  1786. }
  1787. }
  1788. last_total_samps_read = dz->total_samps_read - dz->ssampsread;
  1789. hereinbuf = thisstart - last_total_samps_read;
  1790. if(dostartsplice) {
  1791. if(dz->vflag[1])
  1792. splicer = spliceincr;
  1793. else
  1794. splicer = 0.0;
  1795. for(k = 0;k < splicelen; k++) {
  1796. for(j = 0; j < chans; j++) {
  1797. obuf[hereinbuf] = (float)(ibuf[hereinbuf] * splicer);
  1798. hereinbuf++;
  1799. }
  1800. splicer += spliceincr;
  1801. splicer = min(splicer,1.0);
  1802. if(hereinbuf >= dz->buflen) {
  1803. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1804. return(exit_status);
  1805. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1806. if(dz->vflag[1]) {
  1807. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  1808. return(exit_status);
  1809. bufcnt--;
  1810. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  1811. return(exit_status);
  1812. if(dz->ssampsread == 0) {
  1813. sprintf(errstr,"Error 2 in sample read accounting.\n");
  1814. return(PROGRAM_ERROR);
  1815. }
  1816. hereinbuf = 0;
  1817. }
  1818. }
  1819. }
  1820. tocopy = thisend - cuts[n]; // Copy the chunk to output
  1821. bufremain = dz->ssampsread - hereinbuf;
  1822. while(bufremain <= tocopy) {
  1823. memcpy((char *)(obuf + hereinbuf),(char *)(ibuf + hereinbuf),bufremain * sizeof(float));
  1824. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  1825. return(exit_status);
  1826. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1827. tocopy -= bufremain;
  1828. if(dz->vflag[1]) {
  1829. if(bufcnt < 0) {
  1830. if(tocopy == 0 && !doendsplice) {
  1831. if(dz->total_samps_written == dz->insams[0])
  1832. break;
  1833. }
  1834. }
  1835. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  1836. return(exit_status);
  1837. bufcnt--;
  1838. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  1839. return(exit_status);
  1840. if((dz->ssampsread == 0) && doendsplice && dz->iparam[ISO_SPL] > 0) {
  1841. sprintf(errstr,"Error 3 in sample read accounting.\n");
  1842. return(PROGRAM_ERROR);
  1843. }
  1844. bufremain = dz->ssampsread;
  1845. hereinbuf = 0;
  1846. if(tocopy <= 0) {
  1847. if(doendsplice && dz->iparam[ISO_SPL] > 0) {
  1848. sprintf(errstr,"Error in read-write accounting 1\n");
  1849. return(PROGRAM_ERROR);
  1850. } else if(tocopy < 0) {
  1851. sprintf(errstr,"Error in read-write accounting 2\n");
  1852. return(PROGRAM_ERROR);
  1853. } else
  1854. break;
  1855. }
  1856. }
  1857. if(dz->total_samps_written == dz->insams[0]) {
  1858. if(tocopy || doendsplice) {
  1859. sprintf(errstr,"Error 3A in sample read accounting.\n");
  1860. return(PROGRAM_ERROR);
  1861. }
  1862. return(CONTINUE);
  1863. }
  1864. if(tocopy) {
  1865. if(!doendsplice && dz->iparam[ISO_SPL] != 0) {
  1866. sprintf(errstr,"Error in read-write accounting 3\n");
  1867. return(PROGRAM_ERROR);
  1868. }
  1869. memcpy((char *)(obuf + hereinbuf),(char *)(ibuf + hereinbuf),tocopy * sizeof(float));
  1870. hereinbuf += tocopy;
  1871. }
  1872. if(doendsplice && dz->iparam[ISO_SPL] != 0) {
  1873. if(dz->vflag[1])
  1874. splicer = 1.0 - spliceincr;
  1875. else
  1876. splicer = 1.0;
  1877. last_total_samps_read = dz->total_samps_read - dz->ssampsread;
  1878. for(k = 0;k < splicelen; k++) {
  1879. for(j = 0; j < chans; j++) {
  1880. obuf[hereinbuf] = (float)(ibuf[hereinbuf] * splicer);
  1881. hereinbuf++;
  1882. }
  1883. splicer -= spliceincr;
  1884. splicer = max(splicer,0.0);
  1885. if(hereinbuf >= dz->buflen) {
  1886. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1887. return(exit_status);
  1888. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1889. if(dz->vflag[1]) {
  1890. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  1891. return(exit_status);
  1892. bufcnt--;
  1893. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  1894. return(exit_status);
  1895. if(dz->ssampsread == 0) {
  1896. sprintf(errstr,"Error 4 in sample read accounting.\n");
  1897. return(PROGRAM_ERROR);
  1898. }
  1899. hereinbuf = 0;
  1900. }
  1901. }
  1902. }
  1903. if(dz->vflag[0]) {
  1904. while(dz->ssampsread > 0) {
  1905. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  1906. return(exit_status);
  1907. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1908. if(dz->vflag[1]) {
  1909. if(bufcnt < 0) {
  1910. if(dz->total_samps_written == dz->insams[0])
  1911. break;
  1912. }
  1913. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  1914. return(exit_status);
  1915. bufcnt--;
  1916. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  1917. return(exit_status);
  1918. }
  1919. } else if(hereinbuf) {
  1920. if((exit_status = write_samps(obuf,hereinbuf,dz))<0)
  1921. return(exit_status);
  1922. }
  1923. if(do_continue)
  1924. exit_status = CONTINUE;
  1925. else
  1926. exit_status = FINISHED;
  1927. return exit_status;
  1928. }
  1929. /******************************** DO_REMNANT_CUT *********************************/
  1930. int do_remnant_cut(int fileno,int *cuts,double spliceincr,dataptr dz)
  1931. {
  1932. int exit_status, docontinue = 1;
  1933. int chans = dz->infile->channels, splicelen = dz->iparam[ISO_SPL], dodownsplice = 0, doupsplice = 0, n, k, j;
  1934. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  1935. int tocopy, bufremain, hereinbuf, lastpassend, copyend, zeroend, tozero;
  1936. double splicer;
  1937. char filename[200], thisnum[8];
  1938. fprintf(stdout,"INFO: Cutting remnant\n");
  1939. fflush(stdout);
  1940. if((exit_status = read_samps(ibuf,dz)) < 0)
  1941. return(exit_status);
  1942. if((exit_status = eliminate_abutted_cuts(cuts,dz)) == FINISHED)
  1943. return exit_status;
  1944. strcpy(filename,dz->outfilename);
  1945. sprintf(thisnum,"%d",fileno);
  1946. strcat(filename,thisnum);
  1947. strcat(filename,".wav");
  1948. if((exit_status = create_sized_outfile(filename,dz))<0)
  1949. return(exit_status);
  1950. reset_filedata_counters(dz);
  1951. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1952. hereinbuf = 0;
  1953. lastpassend = 0; // Start copying samples from where last upsplice ended (or start of file)
  1954. for(n=0; n< dz->itemcnt;n += 2) {
  1955. copyend = cuts[n];
  1956. if(copyend < splicelen * chans) { // If there was no room to do splice on start of 1st segment originally cut
  1957. copyend = 0; // Nothing to copy at start of file
  1958. dodownsplice = 0;
  1959. } else { // Else copy only up to start of downsplice
  1960. copyend = cuts[n] - (splicelen * chans);
  1961. dodownsplice = 1; // and flag to then do downsplice
  1962. }
  1963. zeroend = cuts[n+1]; // If there was no room to do splice on end of (last) segment originally cut
  1964. if((dz->insams[0] - cuts[n+1] < splicelen * chans) \
  1965. || (dz->insams[0] - cuts[n+1] == 0)) { // or if splicelen is 0 and we're at end of file
  1966. zeroend = dz->insams[0]; // extend zeroed portion to end of file
  1967. doupsplice = 0; // and flag NO endsplice,
  1968. docontinue = 0; // PLUS flag quit cuttings
  1969. } else // Else, flag upsplice needed
  1970. doupsplice = 1;
  1971. tocopy = copyend - lastpassend; // Copy the chunk to output (if nothing to copy, this is 0 - 0)
  1972. bufremain = dz->ssampsread - hereinbuf;
  1973. while(tocopy >= bufremain) {
  1974. memcpy((char *)(obuf + hereinbuf),(char *)(ibuf + hereinbuf),bufremain * sizeof(float));
  1975. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  1976. return(exit_status); // copy chunk to output before start of cut
  1977. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1978. if((exit_status = read_samps(ibuf,dz)) < 0)
  1979. return(exit_status);
  1980. if(dz->ssampsread == 0) {
  1981. sprintf(errstr,"Error 5 in sample read accounting.\n");
  1982. return(PROGRAM_ERROR);
  1983. }
  1984. tocopy -= bufremain;
  1985. bufremain = dz->ssampsread;
  1986. hereinbuf = 0;
  1987. }
  1988. if(tocopy > 0) {
  1989. memcpy((char *)(obuf + hereinbuf),(char *)(ibuf + hereinbuf),tocopy * sizeof(float));
  1990. hereinbuf += tocopy;
  1991. }
  1992. if(dodownsplice && dz->iparam[ISO_SPL] != 0) {
  1993. splicer = 1.0;
  1994. for(k = 0;k < splicelen; k++) {
  1995. for(j = 0; j < chans; j++) {
  1996. obuf[hereinbuf] = (float)(ibuf[hereinbuf] * splicer);
  1997. hereinbuf++;
  1998. }
  1999. splicer -= spliceincr;
  2000. if(hereinbuf >= dz->buflen) {
  2001. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2002. return(exit_status);
  2003. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2004. if((exit_status = read_samps(ibuf,dz)) < 0)
  2005. return(exit_status);
  2006. if(dz->ssampsread == 0) {
  2007. sprintf(errstr,"Error 6 in sample read accounting.\n");
  2008. return(PROGRAM_ERROR);
  2009. }
  2010. hereinbuf = 0;
  2011. }
  2012. }
  2013. }
  2014. tozero = zeroend - cuts[n]; // Zero output where cut chunk has been taken
  2015. bufremain = dz->ssampsread - hereinbuf;
  2016. while(bufremain <= tozero) {
  2017. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  2018. return(exit_status); // Don't write anything extra into obuf
  2019. memset((char *)obuf,0,dz->buflen * sizeof(float)); // And refill new outbufs with zeros
  2020. if((exit_status = read_samps(ibuf,dz)) < 0)
  2021. return(exit_status);
  2022. if(dz->ssampsread == 0) {
  2023. if(doupsplice && dz->iparam[ISO_SPL] != 0) {
  2024. sprintf(errstr,"Error 7 in sample read accounting.\n");
  2025. return(PROGRAM_ERROR);
  2026. }
  2027. }
  2028. tozero -= bufremain;
  2029. bufremain = dz->ssampsread;
  2030. hereinbuf = 0;
  2031. if(bufremain == 0) {
  2032. if(tozero > 0) {
  2033. sprintf(errstr,"Error in read-write accounting 4\n");
  2034. return(PROGRAM_ERROR);
  2035. }
  2036. }
  2037. if(tozero == 0) {
  2038. break;
  2039. }
  2040. }
  2041. if(tozero > 0)
  2042. hereinbuf += tozero;
  2043. if(doupsplice && dz->iparam[ISO_SPL] != 0) {
  2044. splicer = 0;
  2045. for(k = 0;k < splicelen; k++) {
  2046. for(j = 0; j < chans; j++) {
  2047. obuf[hereinbuf] = (float)(ibuf[hereinbuf] * splicer);
  2048. hereinbuf++;
  2049. }
  2050. splicer += spliceincr;
  2051. if(hereinbuf >= dz->buflen) {
  2052. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2053. return(exit_status);
  2054. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2055. if((exit_status = read_samps(ibuf,dz)) < 0)
  2056. return(exit_status);
  2057. if(dz->ssampsread == 0) {
  2058. sprintf(errstr,"Error 8 in sample read accounting.\n");
  2059. return(PROGRAM_ERROR);
  2060. }
  2061. hereinbuf = 0;
  2062. }
  2063. }
  2064. }
  2065. if(!docontinue)
  2066. break;
  2067. lastpassend = cuts[n+1] + (splicelen * chans);
  2068. }
  2069. if(docontinue && dz->ssampsread != 0) { // There was a splice up at the end of last cut (so not at end of file)
  2070. // But if it was a zero splice, could be at end of file
  2071. tocopy = dz->insams[0] - (cuts[dz->itemcnt - 1] + (splicelen * chans));
  2072. bufremain = dz->ssampsread - hereinbuf;
  2073. while(bufremain <= tocopy) {
  2074. memcpy((char *)(obuf + hereinbuf),(char *)(ibuf + hereinbuf),bufremain * sizeof(float));
  2075. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  2076. return(exit_status);
  2077. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2078. if((exit_status = read_samps(ibuf,dz)) < 0)
  2079. return(exit_status);
  2080. tocopy -= bufremain;
  2081. hereinbuf = 0;
  2082. bufremain = dz->ssampsread;
  2083. if(tocopy <= 0) {
  2084. if(tocopy < 0) {
  2085. sprintf(errstr,"Error in read-write accounting 6\n");
  2086. return(PROGRAM_ERROR);
  2087. }
  2088. break;
  2089. }
  2090. }
  2091. if(tocopy) {
  2092. sprintf(errstr,"Error in read-write accounting 7\n");
  2093. return(PROGRAM_ERROR);
  2094. }
  2095. }
  2096. return exit_status;
  2097. }
  2098. /********************************** ELIMINATE_ABUTTED_CUTS ******************************
  2099. *
  2100. * Where cut chunks overlap each other, there is no remnant to save between them
  2101. * so the cutpoints at this point are eliminated before remnant is created.
  2102. */
  2103. int eliminate_abutted_cuts(int *cuts,dataptr dz)
  2104. {
  2105. int n, m, dlbspcnt = dz->iparam[ISO_SPL] * 2 * dz->infile->channels; // length of two splices in samples
  2106. for(n=2;n < dz->itemcnt;n+=2) {
  2107. if(cuts[n] - cuts[n-1] <= dlbspcnt) {
  2108. for(m = n+1;m < dz->itemcnt;m++)
  2109. cuts[m-2] = cuts[m];
  2110. dz->itemcnt -= 2;
  2111. n -= 2;
  2112. }
  2113. }
  2114. if(dz->itemcnt == 2 && cuts[0] == 0 && cuts[1] == dz->insams[0]) {
  2115. fprintf(stdout,"INFO: No remnant file\n");
  2116. fflush(stdout);
  2117. return FINISHED;
  2118. }
  2119. return CONTINUE;
  2120. }
  2121. /****************************** GET_MODE *********************************/
  2122. int get_the_mode_no(char *str, dataptr dz)
  2123. {
  2124. if(sscanf(str,"%d",&dz->mode)!=1) {
  2125. sprintf(errstr,"Cannot read mode of program.\n");
  2126. fprintf(stdout,"INFO: %s\n",errstr);
  2127. fflush(stdout);
  2128. return(USAGE_ONLY);
  2129. }
  2130. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  2131. sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  2132. fprintf(stdout,"INFO: %s\n",errstr);
  2133. fflush(stdout);
  2134. return(USAGE_ONLY);
  2135. }
  2136. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  2137. return(FINISHED);
  2138. }
  2139. /******************************** DO_A_MULTICUT *********************************/
  2140. int do_a_multicut(int jj,double spliceincr,dataptr dz)
  2141. {
  2142. int exit_status, bufcnt = 0;
  2143. int chans = dz->infile->channels, splicelen = dz->iparam[ISO_SPL], dodownsplice = 0, doupsplice = 0, n, k, j;
  2144. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  2145. int tocopy, bufremain, hereinbuf, lastpassend, copyend, zeroend, tozero;
  2146. double splicer;
  2147. int itemcnt = dz->iparray[0][jj];
  2148. int *cuts = dz->lparray[jj];
  2149. if(dz->vflag[1]) {
  2150. bufcnt = dz->insams[0]/dz->buflen;
  2151. if(bufcnt * dz->buflen == dz->insams[0])
  2152. bufcnt--;
  2153. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  2154. return(exit_status);
  2155. bufcnt--;
  2156. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  2157. return(exit_status);
  2158. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2159. hereinbuf = 0;
  2160. lastpassend = 0; // Start copying samples from where last upsplice ended (or start of file)
  2161. for(n=0; n< itemcnt;n += 2) {
  2162. zeroend = cuts[n];
  2163. if(zeroend < splicelen * chans) { // If there was no room to do splice on start of 1st segment originally cut
  2164. zeroend = 0; // Nothing to zero at start of file
  2165. doupsplice = 0;
  2166. } else { // Else zero up to start of upsplice
  2167. zeroend = cuts[n] - (splicelen * chans);
  2168. doupsplice = 1; // and flag to then do upsplice
  2169. }
  2170. copyend = cuts[n+1]; // If there is no room to do splice on end of (last) segment originally cut
  2171. if(dz->insams[0] - copyend < splicelen * chans) {
  2172. copyend = dz->insams[0]; // extend copied portion to end of file
  2173. dodownsplice = 0; // and flag NO endsplice,
  2174. } else // Else, flag downsplice needed
  2175. dodownsplice = 1;
  2176. tozero = zeroend - lastpassend; // Zero the chunk to output (if nothing to zero, this is 0 - 0)
  2177. bufremain = dz->ssampsread - hereinbuf;
  2178. while(tozero >= bufremain) {
  2179. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  2180. return(exit_status); // copy chunk to output before start of cut
  2181. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2182. if(dz->vflag[1]) {
  2183. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  2184. return(exit_status);
  2185. bufcnt--;
  2186. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  2187. return(exit_status);
  2188. if(dz->ssampsread == 0) {
  2189. sprintf(errstr,"Error 9 in sample read accounting at segment %d.\n",(n/2)+1);
  2190. return(PROGRAM_ERROR);
  2191. }
  2192. tozero -= bufremain;
  2193. bufremain = dz->ssampsread;
  2194. hereinbuf = 0;
  2195. }
  2196. if(tozero > 0)
  2197. hereinbuf += tozero;
  2198. if(doupsplice && dz->iparam[ISO_SPL] != 0) {
  2199. if(dz->vflag[1])
  2200. splicer = spliceincr;
  2201. else
  2202. splicer = 0.0;
  2203. for(k = 0;k < splicelen; k++) {
  2204. for(j = 0; j < chans; j++) {
  2205. obuf[hereinbuf] = (float)(ibuf[hereinbuf] * splicer);
  2206. hereinbuf++;
  2207. }
  2208. splicer += spliceincr;
  2209. splicer = min(splicer,1.0);
  2210. if(hereinbuf >= dz->buflen) {
  2211. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2212. return(exit_status);
  2213. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2214. if(dz->vflag[1]) {
  2215. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  2216. return(exit_status);
  2217. bufcnt--;
  2218. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  2219. return(exit_status);
  2220. if(dz->ssampsread == 0) {
  2221. sprintf(errstr,"Error 10 in sample read accounting.\n");
  2222. return(PROGRAM_ERROR);
  2223. }
  2224. hereinbuf = 0;
  2225. }
  2226. }
  2227. }
  2228. tocopy = copyend - cuts[n]; // Copy cut chunk to output
  2229. bufremain = dz->ssampsread - hereinbuf;
  2230. while(bufremain <= tocopy) {
  2231. memcpy((char *)(obuf + hereinbuf),(char *)(ibuf + hereinbuf),bufremain * sizeof(float));
  2232. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  2233. return(exit_status); // Don't write anything extra into obuf
  2234. memset((char *)obuf,0,dz->buflen * sizeof(float)); // And refill new outbufs with zeros
  2235. tocopy -= bufremain;
  2236. if(dz->vflag[1]) {
  2237. if(dz->total_samps_written == dz->insams[0]) {
  2238. if(tocopy == 0 && !dodownsplice)
  2239. break;
  2240. }
  2241. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  2242. return(exit_status);
  2243. bufcnt--;
  2244. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  2245. return(exit_status);
  2246. if(dz->ssampsread == 0) {
  2247. if(dodownsplice && dz->iparam[ISO_SPL] != 0) {
  2248. sprintf(errstr,"Error 11 in sample read accounting.\n");
  2249. return(PROGRAM_ERROR);
  2250. }
  2251. }
  2252. bufremain = dz->ssampsread;
  2253. hereinbuf = 0;
  2254. if(bufremain == 0) {
  2255. if(tocopy > 0) {
  2256. sprintf(errstr,"Error 12 in read-write accounting at segment %d.\n",(n/2)+1);
  2257. return(PROGRAM_ERROR);
  2258. }
  2259. }
  2260. if(tocopy == 0) {
  2261. break;
  2262. }
  2263. }
  2264. if(dz->total_samps_written == dz->insams[0]) {
  2265. if(tocopy || dodownsplice) {
  2266. sprintf(errstr,"Error 13A in sample read accounting.\n");
  2267. return(PROGRAM_ERROR);
  2268. }
  2269. return(CONTINUE);
  2270. }
  2271. if(tocopy > 0) {
  2272. memcpy((char *)(obuf + hereinbuf),(char *)(ibuf + hereinbuf),tocopy * sizeof(float));
  2273. hereinbuf += tocopy;
  2274. }
  2275. if(dodownsplice && dz->iparam[ISO_SPL] != 0) {
  2276. if(dz->vflag[1])
  2277. splicer = 1.0 - spliceincr;
  2278. else
  2279. splicer = 1.0;
  2280. for(k = 0;k < splicelen; k++) {
  2281. for(j = 0; j < chans; j++) {
  2282. obuf[hereinbuf] = (float)(ibuf[hereinbuf] * splicer);
  2283. hereinbuf++;
  2284. }
  2285. splicer -= spliceincr;
  2286. splicer = max(splicer,0.0);
  2287. if(hereinbuf >= dz->buflen) {
  2288. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  2289. return(exit_status);
  2290. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2291. if(dz->vflag[1]) {
  2292. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  2293. return(exit_status);
  2294. bufcnt--;
  2295. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  2296. return(exit_status);
  2297. if(dz->ssampsread == 0) {
  2298. sprintf(errstr,"Error 14 in sample read accounting.\n");
  2299. return(PROGRAM_ERROR);
  2300. }
  2301. hereinbuf = 0;
  2302. }
  2303. }
  2304. }
  2305. lastpassend = cuts[n+1] + (splicelen * chans);
  2306. }
  2307. if(dz->vflag[0]) {
  2308. while(dz->ssampsread > 0) {
  2309. if((exit_status = write_samps(obuf,dz->ssampsread,dz))<0)
  2310. return(exit_status);
  2311. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2312. if(dz->vflag[1]) {
  2313. if(bufcnt < 0) {
  2314. if(dz->total_samps_written == dz->insams[0])
  2315. break;
  2316. }
  2317. if((exit_status = reverse_sndread(ibuf,bufcnt,dz)) < 0)
  2318. return(exit_status);
  2319. bufcnt--;
  2320. } else if((exit_status = read_samps(ibuf,dz)) < 0)
  2321. return(exit_status);
  2322. }
  2323. } else if(hereinbuf > 0) {
  2324. if((exit_status = write_samps(obuf,hereinbuf,dz))<0)
  2325. return(exit_status);
  2326. }
  2327. return CONTINUE;
  2328. }
  2329. /******************************** CONVERT_BRKVALS_DB_TO_GAIN *************************/
  2330. int convert_brkvals_db_to_gain(int paramno,dataptr dz)
  2331. {
  2332. int exit_status;
  2333. double *p = dz->brk[paramno];
  2334. double *pend = p + (dz->brksize[paramno] * 2);
  2335. p++;
  2336. while(p < pend) {
  2337. if((exit_status = convert_dB_at_or_below_zero_to_gain(p))<0)
  2338. return(exit_status);
  2339. p += 2;
  2340. }
  2341. return(FINISHED);
  2342. }
  2343. /******************************** ISOLATE_PARAM_PREPROCESS *************************/
  2344. int isolate_param_preprocess(dataptr dz)
  2345. {
  2346. int exit_status, chans = dz->infile->channels, n;
  2347. int lastsampsread, winlen, winend, segstart = 0, maxloc, wincnt;
  2348. int *cuts;
  2349. float *ibuf = dz->sampbuf[0];
  2350. double time, srate = (double)dz->infile->srate, winmax, maxenvsamp = 0.0, minenvsamp = 0.0;
  2351. int gotmax, cutscnt, segcnt;
  2352. fprintf(stdout,"INFO: Finding and Counting segments\n");
  2353. fflush(stdout);
  2354. if((exit_status = read_samps(ibuf,dz)) < 0)
  2355. return(exit_status);
  2356. winlen = (int)round(ISO_WINLEN * MS_TO_SECS * srate) * chans;
  2357. segcnt = 0;
  2358. gotmax = 0;
  2359. maxloc = 0;
  2360. lastsampsread = 0;
  2361. wincnt = 0;
  2362. winend = winlen;
  2363. while(dz->ssampsread > 0) {
  2364. winmax = -1;
  2365. if(dz->brksize[ISO_THRON] || dz->brksize[ISO_THROFF]) {
  2366. time = (double)(lastsampsread + wincnt) * srate;
  2367. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2368. return(exit_status);
  2369. if(dz->param[ISO_THRON] >= dz->param[ISO_THROFF]) {
  2370. sprintf(errstr,"On (%lf) and Off (%lf) thresholds are incompatible at time %lf secs\n",
  2371. convert_gain_to_dB_from_minus96(dz->param[ISO_THRON]),convert_gain_to_dB_from_minus96(dz->param[ISO_THROFF]),time);
  2372. return(DATA_ERROR);
  2373. }
  2374. }
  2375. while(wincnt<winend) {
  2376. if(wincnt >= dz->ssampsread) {
  2377. wincnt -= dz->ssampsread;
  2378. winend -= dz->ssampsread;
  2379. lastsampsread = dz->total_samps_read;
  2380. if((exit_status = read_samps(ibuf,dz)) < 0)
  2381. return(exit_status);
  2382. if(dz->ssampsread == 0)
  2383. break;
  2384. }
  2385. if(fabs(ibuf[wincnt]) > winmax) {
  2386. winmax = fabs(ibuf[wincnt]);
  2387. maxloc = ((lastsampsread + wincnt)/chans) * chans; // Round location to a chan-group boundary
  2388. }
  2389. wincnt++;
  2390. }
  2391. if(gotmax) {
  2392. if(winmax <= dz->param[ISO_THROFF]) {
  2393. if(maxloc - segstart >= dz->iparam[ISO_MIN]) {
  2394. segcnt++;
  2395. gotmax = 0;
  2396. }
  2397. }
  2398. } else {
  2399. if(winmax >= dz->param[ISO_THRON]) {
  2400. gotmax = 1;
  2401. segstart = maxloc;
  2402. }
  2403. }
  2404. maxenvsamp = max(winmax,maxenvsamp);
  2405. minenvsamp = min(winmax,minenvsamp);
  2406. wincnt = winend;
  2407. winend += winlen;
  2408. }
  2409. if(gotmax) {
  2410. if(dz->insams[0] - segstart >= dz->iparam[ISO_MIN])
  2411. segcnt++;
  2412. }
  2413. if(segcnt == 0) {
  2414. sprintf(errstr,"No segments found above threshold and of sufficient length\n(maxlevel %.2lf dB, minlevel %.2lf dB)\n",
  2415. convert_gain_to_dB_from_minus96(maxenvsamp),convert_gain_to_dB_from_minus96(minenvsamp));
  2416. return(DATA_ERROR);
  2417. }
  2418. segcnt *= 2;
  2419. dz->specenvcnt = segcnt; // specevcnt used to store total number of cuts, for remnant-pass
  2420. dz->itemcnt = 1;
  2421. dz->iarray_cnt = 1;
  2422. dz->larray_cnt = 1;
  2423. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  2424. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer arrays.\n");
  2425. return(MEMORY_ERROR);
  2426. }
  2427. if((dz->iparray[0] = (int *)malloc(dz->itemcnt * sizeof(int)))==NULL) { // Store length of cut store
  2428. sprintf(errstr,"INSUFFICIENT MEMORY to store lengths of cut-groups.\n");
  2429. return(MEMORY_ERROR);
  2430. }
  2431. dz->iparray[0][0] = segcnt;
  2432. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  2433. sprintf(errstr,"INSUFFICIENT MEMORY for internal integer arrays.\n");
  2434. return(MEMORY_ERROR);
  2435. }
  2436. if((dz->lparray[0] = (int *)malloc(segcnt * sizeof(int)))==NULL) {
  2437. sprintf(errstr,"INSUFFICIENT MEMORY to store segment cuts.\n");
  2438. return(MEMORY_ERROR);
  2439. }
  2440. sndseekEx(dz->ifd[0],0,0);
  2441. reset_filedata_counters(dz);
  2442. if((exit_status = read_samps(ibuf,dz)) < 0)
  2443. return(exit_status);
  2444. cutscnt = 0;
  2445. cuts = dz->lparray[0];
  2446. gotmax = 0;
  2447. maxloc = 0;
  2448. lastsampsread = 0;
  2449. wincnt = 0;
  2450. winend = winlen;
  2451. fprintf(stdout,"INFO: Storing segment positions.\n");
  2452. fflush(stdout);
  2453. while(dz->ssampsread > 0) {
  2454. winmax = -1;
  2455. while(wincnt<winend) {
  2456. if(wincnt >= dz->ssampsread) {
  2457. wincnt -= dz->ssampsread;
  2458. winend -= dz->ssampsread;
  2459. lastsampsread = dz->total_samps_read;
  2460. if((exit_status = read_samps(ibuf,dz)) < 0)
  2461. return(exit_status);
  2462. if(dz->ssampsread == 0)
  2463. break;
  2464. }
  2465. if(fabs(ibuf[wincnt]) > winmax) {
  2466. winmax = fabs(ibuf[wincnt]);
  2467. maxloc = ((lastsampsread + wincnt)/chans) * chans; // Round location to a chan-group boundary
  2468. }
  2469. wincnt++;
  2470. }
  2471. if(gotmax) {
  2472. if(winmax <= dz->param[ISO_THROFF]) {
  2473. if(maxloc - segstart >= dz->iparam[ISO_MIN]) {
  2474. cuts[cutscnt++] = segstart;
  2475. cuts[cutscnt++] = maxloc;
  2476. gotmax = 0;
  2477. }
  2478. }
  2479. } else {
  2480. if(winmax >= dz->param[ISO_THRON]) {
  2481. gotmax = 1;
  2482. segstart = maxloc;
  2483. }
  2484. }
  2485. wincnt = winend;
  2486. winend += winlen;
  2487. }
  2488. if(gotmax) {
  2489. if(dz->insams[0] - segstart >= dz->iparam[ISO_MIN]) {
  2490. cuts[cutscnt++] = segstart;
  2491. cuts[cutscnt++] = dz->insams[0];
  2492. }
  2493. }
  2494. if(dz->iparam[ISO_LEN] > 0) {
  2495. for(n=0;n < cutscnt;n+=2)
  2496. cuts[n+1] = cuts[n] + dz->iparam[ISO_LEN];
  2497. }
  2498. sndseekEx(dz->ifd[0],0,0);
  2499. reset_filedata_counters(dz);
  2500. return FINISHED;
  2501. }
  2502. /******************************** CONVERT_GAIN_TO__FROM_MINUS96 *************************/
  2503. double convert_gain_to_dB_from_minus96(double val)
  2504. {
  2505. double mindb = 1.0/pow(10,(96.0/20.0));
  2506. if(val <= mindb)
  2507. val = -96.0;
  2508. else if(flteq(val,1.0))
  2509. val = 0.0;
  2510. else {
  2511. val = 1.0/val;
  2512. val = log10(val);
  2513. val *= 20.0;
  2514. val = -val;
  2515. if(val < -96.0)
  2516. val = -96.0;
  2517. }
  2518. return val;
  2519. }
  2520. /******************************** REVERSE_SNDREAD *************************
  2521. *
  2522. * Read buffer and reverse it
  2523. */
  2524. int reverse_sndread(float *ibuf,int bufcnt, dataptr dz)
  2525. {
  2526. int exit_status;
  2527. int n, m, j, up, dn;
  2528. float temp;
  2529. int total_samps_read = dz->total_samps_read;
  2530. if(bufcnt < 0) {
  2531. sprintf(errstr,"Error in reverse sample read accounting\n");
  2532. return(PROGRAM_ERROR);
  2533. }
  2534. sndseekEx(dz->ifd[0],bufcnt * dz->buflen,0);
  2535. if((exit_status = read_samps(ibuf,dz)) < 0)
  2536. return(exit_status);
  2537. total_samps_read += dz->ssampsread;
  2538. dz->total_samps_read = total_samps_read;
  2539. n = dz->ssampsread/2;
  2540. if(n * 2 != dz->ssampsread) { // ODD count of samples
  2541. up = n+1;
  2542. dn = n-1;
  2543. } else {
  2544. up = n;
  2545. dn = n-1;
  2546. }
  2547. for(m=up,j = dn;j >= 0;m++,j--) {
  2548. temp = ibuf[j];
  2549. ibuf[j] = ibuf[m];
  2550. ibuf[m] = temp;
  2551. }
  2552. return FINISHED;
  2553. }
  2554. /******************************** REVERSE_CUTS *************************
  2555. *
  2556. * reverse long-array of paired values (start+end of cuts)
  2557. */
  2558. int reverse_cuts(int *array,int itemcnt,dataptr dz)
  2559. {
  2560. int m, j, up, dn;
  2561. int temp;
  2562. int n = itemcnt/2;
  2563. if(n * 2 != itemcnt) { // ODD count in cuts array
  2564. sprintf(errstr,"Array to reverse is not correctly paired\n");
  2565. return(DATA_ERROR);
  2566. }
  2567. up = n;
  2568. dn = n-1;
  2569. for(m=up,j = dn;j >= 0;m++,j--) {
  2570. temp = array[j];
  2571. array[j] = dz->insams[0] - array[m];
  2572. array[m] = dz->insams[0] - temp;
  2573. }
  2574. return FINISHED;
  2575. }