shrink.c 123 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994
  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 SHRLEVLIM (0.95)
  41. #define MINUS60DB (0.001)
  42. //#ifdef unix
  43. #define round(x) lround((x))
  44. //#endif
  45. #define maxival scalefact
  46. char errstr[2400];
  47. int anal_infiles = 1;
  48. int sloom = 0;
  49. int sloombatch = 0;
  50. const char* cdp_version = "7.1.0";
  51. //CDP LIB REPLACEMENTS
  52. static int check_shrink_validity_and_consistency(dataptr dz);
  53. static int setup_shrink_application(dataptr dz);
  54. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  55. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  56. static int setup_shrink_param_ranges_and_defaults(dataptr dz);
  57. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  58. static int open_the_outfile(dataptr dz);
  59. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  60. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  61. static int establish_application(dataptr dz);
  62. static int initialise_vflags(dataptr dz);
  63. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  64. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  65. static int mark_parameter_types(dataptr dz,aplptr ap);
  66. static int assign_file_data_storage(int infilecnt,dataptr dz);
  67. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  68. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  69. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  70. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  71. static int shrink(dataptr dz);
  72. static int shrink2(dataptr dz);
  73. static int create_shrink_sndbufs(dataptr dz);
  74. static void shrink_normalise(float *buf,int len,double gain,int maxat);
  75. static double getmaxval(float *buf,int len,int *maxat);
  76. static void reverse_data(float *obuf,int seglen,dataptr dz);
  77. static int shrink_param_preprocess(dataptr dz);
  78. static int extract_env_from_sndfile(int *envcnt,dataptr dz);
  79. static void getenv_of_buffer(int samps_to_process,int envwindow_sampsize,double convertor,double time_convertor,float **envptr,float *buffer,dataptr dz);
  80. static double getmaxsamp(int startsamp, int sampcnt,float *buffer);
  81. static int eliminate_too_low_peaks(int *envcnt,int *trofcnt,dataptr dz);
  82. static int eliminate_redundant_trofs(int *envcnt,int *trofcnt,int orig_env_size,dataptr dz);
  83. static int shuffle_trofs(int troflocalcnt,int *trofcnt,int start_of_trofs,int *trofno,float peaktime,float lastpeaktime,int *lastrofstored,dataptr dz);
  84. static int find_exact_peaktimes(int envcnt,int *peaks,dataptr dz);
  85. static int copy_peaktimes_to_env_array(dataptr dz);
  86. static int find_exact_troftimes(int trofcnt,int *trofs,dataptr dz);
  87. static int test_buffers(int envcnt,int trofcnt,dataptr dz);
  88. static void extract_peaks_from_envelope(int *envcnt,dataptr dz);
  89. static void extract_trofs_from_envelope(int *trofcnt,int orig_env_size,dataptr dz);
  90. static int buffers_in_sndfile(int buffer_size,dataptr dz);
  91. static int windows_in_sndfile(dataptr dz);
  92. static int find_outsamps(dataptr dz);
  93. static int handle_the_special_data(char *str,dataptr dz);
  94. static int insert_trof(int *trofcnt,int trofno,float *troftime,float peaktime,float lastpeaktime,int orig_env_size,dataptr dz);
  95. static int copy_peaktimes(dataptr dz);
  96. static int find_local_minpeak(int *minpeakat,float *minpeak,int searchstt,int searchend,int searchlen, double lastpeaktime, double peaktime, dataptr dz);
  97. /**************************************** MAIN *********************************************/
  98. int main(int argc,char *argv[])
  99. {
  100. int exit_status;
  101. dataptr dz = NULL;
  102. char **cmdline;
  103. int cmdlinecnt;
  104. //aplptr ap;
  105. int is_launched = FALSE;
  106. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  107. fprintf(stdout,"%s\n",cdp_version);
  108. fflush(stdout);
  109. return 0;
  110. }
  111. /* CHECK FOR SOUNDLOOM */
  112. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  113. sloom = 0;
  114. sloombatch = 1;
  115. }
  116. if(sflinit("cdp")){
  117. sfperror("cdp: initialisation\n");
  118. return(FAILED);
  119. }
  120. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  121. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  122. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  123. return(FAILED);
  124. }
  125. if(!sloom) {
  126. if(argc == 1) {
  127. usage1();
  128. return(FAILED);
  129. } else if(argc == 2) {
  130. usage2(argv[1]);
  131. return(FAILED);
  132. }
  133. }
  134. if(!sloom) {
  135. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  136. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  137. return(FAILED);
  138. }
  139. cmdline = argv;
  140. cmdlinecnt = argc;
  141. if((get_the_process_no(argv[0],dz))<0)
  142. return(FAILED);
  143. cmdline++;
  144. cmdlinecnt--;
  145. dz->maxmode = 6;
  146. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  147. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  148. return(exit_status);
  149. }
  150. cmdline++;
  151. cmdlinecnt--;
  152. // setup_particular_application =
  153. if((exit_status = setup_shrink_application(dz))<0) {
  154. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  155. return(FAILED);
  156. }
  157. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  158. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  159. return(FAILED);
  160. }
  161. } else {
  162. //parse_TK_data() =
  163. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  164. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  165. return(exit_status);
  166. }
  167. }
  168. //ap = dz->application;
  169. // parse_infile_and_hone_type() =
  170. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  171. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  172. return(FAILED);
  173. }
  174. // setup_param_ranges_and_defaults() =
  175. if((exit_status = setup_shrink_param_ranges_and_defaults(dz))<0) {
  176. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  177. return(FAILED);
  178. }
  179. // open_first_infile CDP LIB
  180. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  181. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  182. return(FAILED);
  183. }
  184. cmdlinecnt--;
  185. cmdline++;
  186. // handle_extra_infiles() : redundant
  187. // handle_outfile() =
  188. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  189. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  190. return(FAILED);
  191. }
  192. // handle_formants() redundant
  193. // handle_formant_quiksearch() redundant
  194. dz->array_cnt = 3;
  195. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  196. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  197. return(MEMORY_ERROR);
  198. }
  199. dz->larray_cnt = 3;
  200. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  201. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  202. return(MEMORY_ERROR);
  203. }
  204. if(dz->mode == SHRM_LISTMX) {
  205. if((exit_status = handle_the_special_data(cmdline[0],dz))<0) {
  206. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  207. return(FAILED);
  208. }
  209. cmdlinecnt--;
  210. cmdline++;
  211. }
  212. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  213. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  214. return(FAILED);
  215. }
  216. // check_param_validity_and_consistency....
  217. if((exit_status = check_shrink_validity_and_consistency(dz))<0) {
  218. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  219. return(FAILED);
  220. }
  221. is_launched = TRUE;
  222. if((exit_status = create_shrink_sndbufs(dz))<0) {
  223. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  224. return(FAILED);
  225. }
  226. if((exit_status = shrink_param_preprocess(dz))<0) {
  227. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  228. return(FAILED);
  229. }
  230. //spec_process_file =
  231. if((exit_status = open_the_outfile(dz))<0) {
  232. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  233. return(FAILED);
  234. }
  235. switch(dz->mode) {
  236. case(SHRM_FINDMX):
  237. case(SHRM_LISTMX):
  238. exit_status = shrink2(dz);
  239. break;
  240. default:
  241. exit_status = shrink(dz);
  242. break;
  243. }
  244. if(exit_status <0) {
  245. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  246. return(FAILED);
  247. }
  248. if((exit_status = complete_output(dz))<0) { // CDP LIB
  249. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  250. return(FAILED);
  251. }
  252. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  253. free(dz);
  254. return(SUCCEEDED);
  255. }
  256. /**********************************************
  257. REPLACED CDP LIB FUNCTIONS
  258. **********************************************/
  259. /****************************** SET_PARAM_DATA *********************************/
  260. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  261. {
  262. ap->special_data = (char)special_data;
  263. ap->param_cnt = (char)paramcnt;
  264. ap->max_param_cnt = (char)maxparamcnt;
  265. if(ap->max_param_cnt>0) {
  266. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  267. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  268. return(MEMORY_ERROR);
  269. }
  270. strcpy(ap->param_list,paramlist);
  271. }
  272. return(FINISHED);
  273. }
  274. /****************************** SET_VFLGS *********************************/
  275. int set_vflgs
  276. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  277. {
  278. ap->option_cnt = (char) optcnt; /*RWD added cast */
  279. if(optcnt) {
  280. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  281. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  282. return(MEMORY_ERROR);
  283. }
  284. strcpy(ap->option_list,optlist);
  285. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  286. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  287. return(MEMORY_ERROR);
  288. }
  289. strcpy(ap->option_flags,optflags);
  290. }
  291. ap->vflag_cnt = (char) vflagcnt;
  292. ap->variant_param_cnt = (char) vparamcnt;
  293. if(vflagcnt) {
  294. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  295. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  296. return(MEMORY_ERROR);
  297. }
  298. strcpy(ap->variant_list,varlist);
  299. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  300. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  301. return(MEMORY_ERROR);
  302. }
  303. strcpy(ap->variant_flags,varflags);
  304. }
  305. return(FINISHED);
  306. }
  307. /***************************** APPLICATION_INIT **************************/
  308. int application_init(dataptr dz)
  309. {
  310. int exit_status;
  311. int storage_cnt;
  312. int tipc, brkcnt;
  313. aplptr ap = dz->application;
  314. if(ap->vflag_cnt>0)
  315. initialise_vflags(dz);
  316. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  317. ap->total_input_param_cnt = (char)tipc;
  318. if(tipc>0) {
  319. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  320. return(exit_status);
  321. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  322. return(exit_status);
  323. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  324. return(exit_status);
  325. }
  326. brkcnt = tipc;
  327. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  328. if(brkcnt>0) {
  329. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  330. return(exit_status);
  331. }
  332. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  333. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  334. return(exit_status);
  335. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  336. return(exit_status);
  337. }
  338. if((exit_status = mark_parameter_types(dz,ap))<0)
  339. return(exit_status);
  340. // establish_infile_constants() replaced by
  341. dz->infilecnt = 1;
  342. //establish_bufptrs_and_extra_buffers():
  343. return(FINISHED);
  344. }
  345. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  346. /* RWD mallo changed to calloc; helps debug verison run as release! */
  347. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  348. {
  349. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  350. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  351. return(MEMORY_ERROR);
  352. }
  353. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  354. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  355. return(MEMORY_ERROR);
  356. }
  357. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  358. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  359. return(MEMORY_ERROR);
  360. }
  361. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  362. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  363. return(MEMORY_ERROR);
  364. }
  365. return(FINISHED);
  366. }
  367. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  368. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  369. {
  370. int n;
  371. for(n=0;n<storage_cnt;n++) {
  372. dz->is_int[n] = (char)0;
  373. dz->no_brk[n] = (char)0;
  374. }
  375. return(FINISHED);
  376. }
  377. /***************************** MARK_PARAMETER_TYPES **************************/
  378. int mark_parameter_types(dataptr dz,aplptr ap)
  379. {
  380. int n, m; /* PARAMS */
  381. for(n=0;n<ap->max_param_cnt;n++) {
  382. switch(ap->param_list[n]) {
  383. case('0'): break; /* dz->is_active[n] = 0 is default */
  384. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  385. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  386. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  387. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  388. default:
  389. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  390. return(PROGRAM_ERROR);
  391. }
  392. } /* OPTIONS */
  393. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  394. switch(ap->option_list[n]) {
  395. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  396. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  397. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  398. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  399. default:
  400. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  401. return(PROGRAM_ERROR);
  402. }
  403. } /* VARIANTS */
  404. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  405. switch(ap->variant_list[n]) {
  406. case('0'): break;
  407. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  408. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  409. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  410. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  411. default:
  412. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  413. return(PROGRAM_ERROR);
  414. }
  415. } /* INTERNAL */
  416. for(n=0,
  417. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  418. switch(ap->internal_param_list[n]) {
  419. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  420. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  421. case('d'): dz->no_brk[m] = (char)1; break;
  422. default:
  423. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  424. return(PROGRAM_ERROR);
  425. }
  426. }
  427. return(FINISHED);
  428. }
  429. /************************ HANDLE_THE_OUTFILE *********************/
  430. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  431. {
  432. char *p, *filename = (*cmdline)[0];
  433. int n;
  434. if(filename[0]=='-' && filename[1]=='f') {
  435. dz->floatsam_output = 1;
  436. dz->true_outfile_stype = SAMP_FLOAT;
  437. filename+= 2;
  438. }
  439. if(!sloom) {
  440. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  441. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  442. return(DATA_ERROR);
  443. }
  444. }
  445. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX) {
  446. p = filename; // Drop file extension
  447. while(*p != ENDOFSTR) {
  448. if(*p == '.') {
  449. *p = ENDOFSTR;
  450. break;
  451. }
  452. p++;
  453. }
  454. strcpy(dz->outfilename,filename);
  455. if(sloom) { // IF sloom, drop trailing zero
  456. n = strlen(dz->outfilename);
  457. n--;
  458. dz->outfilename[n] = ENDOFSTR;
  459. }
  460. } else
  461. strcpy(dz->outfilename,filename);
  462. (*cmdline)++;
  463. (*cmdlinecnt)--;
  464. return(FINISHED);
  465. }
  466. /************************ OPEN_THE_OUTFILE *********************/
  467. int open_the_outfile(dataptr dz)
  468. {
  469. int exit_status;
  470. char filename[400];
  471. strcpy(filename,dz->outfilename);
  472. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX)
  473. strcat(filename,"0.wav");
  474. if((exit_status = create_sized_outfile(filename,dz))<0)
  475. return(exit_status);
  476. return(FINISHED);
  477. }
  478. /***************************** ESTABLISH_APPLICATION **************************/
  479. int establish_application(dataptr dz)
  480. {
  481. aplptr ap;
  482. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  483. sprintf(errstr,"establish_application()\n");
  484. return(MEMORY_ERROR);
  485. }
  486. ap = dz->application;
  487. memset((char *)ap,0,sizeof(struct applic));
  488. return(FINISHED);
  489. }
  490. /************************* INITIALISE_VFLAGS *************************/
  491. int initialise_vflags(dataptr dz)
  492. {
  493. int n;
  494. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  495. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  496. return(MEMORY_ERROR);
  497. }
  498. for(n=0;n<dz->application->vflag_cnt;n++)
  499. dz->vflag[n] = FALSE;
  500. return FINISHED;
  501. }
  502. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  503. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  504. {
  505. int n;
  506. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  507. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  508. return(MEMORY_ERROR);
  509. }
  510. for(n=0;n<tipc;n++)
  511. ap->default_val[n] = 0.0;
  512. return(FINISHED);
  513. }
  514. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  515. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  516. {
  517. int n;
  518. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  519. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  520. return(MEMORY_ERROR);
  521. }
  522. for(n=0;n<tipc;n++)
  523. dz->is_active[n] = (char)0;
  524. return(FINISHED);
  525. }
  526. /************************* SETUP_SHRINK_APPLICATION *******************/
  527. int setup_shrink_application(dataptr dz)
  528. {
  529. int exit_status;
  530. aplptr ap;
  531. if((exit_status = establish_application(dz))<0) // GLOBAL
  532. return(FAILED);
  533. ap = dz->application;
  534. // SEE parstruct FOR EXPLANATION of next 2 functions
  535. switch(dz->mode) {
  536. case(SHRM_TIMED):
  537. if((exit_status = set_param_data(ap,0 ,6,6,"dddddd"))<0)
  538. return(FAILED);
  539. if((exit_status = set_vflgs(ap,"smr",3,"ddd","ni",2,0,"00"))<0)
  540. return(FAILED);
  541. break;
  542. case(SHRM_FINDMX):
  543. if((exit_status = set_param_data(ap,0 ,6,5,"0ddddd"))<0)
  544. return(FAILED);
  545. if((exit_status = set_vflgs(ap,"smrglq",6,"dddddd","nieo",4,0,"0000"))<0)
  546. return(FAILED);
  547. break;
  548. case(SHRM_LISTMX):
  549. if((exit_status = set_param_data(ap,SHRFOC,6,5,"0ddddd"))<0)
  550. return(FAILED);
  551. if((exit_status = set_vflgs(ap,"smrgl",5,"ddddd","nieo",4,0,"0000"))<0)
  552. return(FAILED);
  553. break;
  554. default:
  555. if((exit_status = set_param_data(ap,0 ,6,5,"0ddddd"))<0)
  556. return(FAILED);
  557. if((exit_status = set_vflgs(ap,"smr",3,"ddd","ni",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_SHRINK_PARAM_RANGES_AND_DEFAULTS *******************/
  593. int setup_shrink_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. if(dz->mode == SHRM_TIMED) {
  604. ap->lo[SHR_TIME] = 0.0;
  605. ap->hi[SHR_TIME] = dz->duration;
  606. ap->default_val[SHR_TIME] = dz->duration/2.0;
  607. }
  608. ap->lo[SHR_INK] = 0;
  609. ap->hi[SHR_INK] = 1;
  610. ap->default_val[SHR_INK] = 0.9;
  611. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX) {
  612. ap->lo[SHR_WSIZE] = 1;
  613. ap->hi[SHR_WSIZE] = 128;
  614. ap->default_val[SHR_WSIZE] = 50;
  615. ap->lo[SHR_AFTER] = 0.0;
  616. ap->hi[SHR_AFTER] = dz->duration;
  617. ap->default_val[SHR_AFTER] = 0.0;
  618. } else {
  619. ap->lo[SHR_GAP] = dz->duration;
  620. ap->hi[SHR_GAP] = 60;
  621. ap->default_val[SHR_GAP] = dz->duration * 2.0;
  622. ap->lo[SHR_DUR] = dz->duration * 2.0;
  623. ap->hi[SHR_DUR] = 32767;
  624. ap->default_val[SHR_DUR] = dz->duration * 8;
  625. }
  626. ap->lo[SHR_CNTRCT] = 0;
  627. ap->hi[SHR_CNTRCT] = 1;
  628. ap->default_val[SHR_CNTRCT] = 1;
  629. ap->lo[SHR_SPLEN] = 2;
  630. ap->hi[SHR_SPLEN] = 50.0;
  631. ap->default_val[SHR_SPLEN] = 5;
  632. ap->lo[SHR_SMALL] = 0;
  633. ap->hi[SHR_SMALL] = dz->insams[0];
  634. ap->default_val[SHR_SMALL] = 0;
  635. ap->lo[SHR_MIN] = 0;
  636. ap->hi[SHR_MIN] = 32767;
  637. ap->default_val[SHR_MIN] = 0;
  638. ap->lo[SHR_RAND] = 0;
  639. ap->hi[SHR_RAND] = 1;
  640. ap->default_val[SHR_RAND] = 0;
  641. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX) {
  642. ap->lo[SHR_GATE] = 0;
  643. ap->hi[SHR_GATE] = 1;
  644. ap->default_val[SHR_GATE] = 0;
  645. ap->lo[SHR_LEN] = 0;
  646. ap->hi[SHR_LEN] = dz->duration;
  647. ap->default_val[SHR_LEN] = 0;
  648. }
  649. if(dz->mode == SHRM_FINDMX) {
  650. ap->lo[SHR_SKEW] = 0;
  651. ap->hi[SHR_SKEW] = 1;
  652. ap->default_val[SHR_SKEW] = 0.25;
  653. }
  654. if(!sloom)
  655. put_default_vals_in_all_params(dz);
  656. return(FINISHED);
  657. }
  658. /********************************* PARSE_SLOOM_DATA *********************************/
  659. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  660. {
  661. int exit_status;
  662. int cnt = 1, infilecnt;
  663. int filesize, insams, inbrksize;
  664. double dummy;
  665. int true_cnt = 0;
  666. //aplptr ap;
  667. while(cnt<=PRE_CMDLINE_DATACNT) {
  668. if(cnt > argc) {
  669. sprintf(errstr,"Insufficient data sent from TK\n");
  670. return(DATA_ERROR);
  671. }
  672. switch(cnt) {
  673. case(1):
  674. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  675. sprintf(errstr,"Cannot read process no. sent from TK\n");
  676. return(DATA_ERROR);
  677. }
  678. break;
  679. case(2):
  680. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  681. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  682. return(DATA_ERROR);
  683. }
  684. if(dz->mode > 0)
  685. dz->mode--;
  686. //setup_particular_application() =
  687. if((exit_status = setup_shrink_application(dz))<0)
  688. return(exit_status);
  689. //ap = dz->application;
  690. break;
  691. case(3):
  692. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  693. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  694. return(DATA_ERROR);
  695. }
  696. if(infilecnt < 1) {
  697. true_cnt = cnt + 1;
  698. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  699. }
  700. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  701. return(exit_status);
  702. break;
  703. case(INPUT_FILETYPE+4):
  704. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  705. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  706. return(DATA_ERROR);
  707. }
  708. break;
  709. case(INPUT_FILESIZE+4):
  710. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  711. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  712. return(DATA_ERROR);
  713. }
  714. dz->insams[0] = filesize;
  715. break;
  716. case(INPUT_INSAMS+4):
  717. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  718. sprintf(errstr,"Cannot read insams sent from TK\n");
  719. return(DATA_ERROR);
  720. }
  721. dz->insams[0] = insams;
  722. break;
  723. case(INPUT_SRATE+4):
  724. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  725. sprintf(errstr,"Cannot read srate sent from TK\n");
  726. return(DATA_ERROR);
  727. }
  728. break;
  729. case(INPUT_CHANNELS+4):
  730. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  731. sprintf(errstr,"Cannot read channels sent from TK\n");
  732. return(DATA_ERROR);
  733. }
  734. break;
  735. case(INPUT_STYPE+4):
  736. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  737. sprintf(errstr,"Cannot read stype sent from TK\n");
  738. return(DATA_ERROR);
  739. }
  740. break;
  741. case(INPUT_ORIGSTYPE+4):
  742. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  743. sprintf(errstr,"Cannot read origstype sent from TK\n");
  744. return(DATA_ERROR);
  745. }
  746. break;
  747. case(INPUT_ORIGRATE+4):
  748. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  749. sprintf(errstr,"Cannot read origrate sent from TK\n");
  750. return(DATA_ERROR);
  751. }
  752. break;
  753. case(INPUT_MLEN+4):
  754. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  755. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  756. return(DATA_ERROR);
  757. }
  758. break;
  759. case(INPUT_DFAC+4):
  760. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  761. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  762. return(DATA_ERROR);
  763. }
  764. break;
  765. case(INPUT_ORIGCHANS+4):
  766. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  767. sprintf(errstr,"Cannot read origchans sent from TK\n");
  768. return(DATA_ERROR);
  769. }
  770. break;
  771. case(INPUT_SPECENVCNT+4):
  772. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  773. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  774. return(DATA_ERROR);
  775. }
  776. dz->specenvcnt = dz->infile->specenvcnt;
  777. break;
  778. case(INPUT_WANTED+4):
  779. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  780. sprintf(errstr,"Cannot read wanted sent from TK\n");
  781. return(DATA_ERROR);
  782. }
  783. break;
  784. case(INPUT_WLENGTH+4):
  785. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  786. sprintf(errstr,"Cannot read wlength sent from TK\n");
  787. return(DATA_ERROR);
  788. }
  789. break;
  790. case(INPUT_OUT_CHANS+4):
  791. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  792. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  793. return(DATA_ERROR);
  794. }
  795. break;
  796. /* RWD these chanegs to samps - tk will have to deal with that! */
  797. case(INPUT_DESCRIPTOR_BYTES+4):
  798. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  799. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  800. return(DATA_ERROR);
  801. }
  802. break;
  803. case(INPUT_IS_TRANSPOS+4):
  804. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  805. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  806. return(DATA_ERROR);
  807. }
  808. break;
  809. case(INPUT_COULD_BE_TRANSPOS+4):
  810. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  811. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  812. return(DATA_ERROR);
  813. }
  814. break;
  815. case(INPUT_COULD_BE_PITCH+4):
  816. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  817. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  818. return(DATA_ERROR);
  819. }
  820. break;
  821. case(INPUT_DIFFERENT_SRATES+4):
  822. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  823. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  824. return(DATA_ERROR);
  825. }
  826. break;
  827. case(INPUT_DUPLICATE_SNDS+4):
  828. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  829. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  830. return(DATA_ERROR);
  831. }
  832. break;
  833. case(INPUT_BRKSIZE+4):
  834. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  835. sprintf(errstr,"Cannot read brksize sent from TK\n");
  836. return(DATA_ERROR);
  837. }
  838. if(inbrksize > 0) {
  839. switch(dz->input_data_type) {
  840. case(WORDLIST_ONLY):
  841. break;
  842. case(PITCH_AND_PITCH):
  843. case(PITCH_AND_TRANSPOS):
  844. case(TRANSPOS_AND_TRANSPOS):
  845. dz->tempsize = inbrksize;
  846. break;
  847. case(BRKFILES_ONLY):
  848. case(UNRANGED_BRKFILE_ONLY):
  849. case(DB_BRKFILES_ONLY):
  850. case(ALL_FILES):
  851. case(ANY_NUMBER_OF_ANY_FILES):
  852. if(dz->extrabrkno < 0) {
  853. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  854. return(DATA_ERROR);
  855. }
  856. if(dz->brksize == NULL) {
  857. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  858. return(PROGRAM_ERROR);
  859. }
  860. dz->brksize[dz->extrabrkno] = inbrksize;
  861. break;
  862. default:
  863. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  864. dz->input_data_type);
  865. return(PROGRAM_ERROR);
  866. }
  867. break;
  868. }
  869. break;
  870. case(INPUT_NUMSIZE+4):
  871. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  872. sprintf(errstr,"Cannot read numsize sent from TK\n");
  873. return(DATA_ERROR);
  874. }
  875. break;
  876. case(INPUT_LINECNT+4):
  877. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  878. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  879. return(DATA_ERROR);
  880. }
  881. break;
  882. case(INPUT_ALL_WORDS+4):
  883. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  884. sprintf(errstr,"Cannot read all_words sent from TK\n");
  885. return(DATA_ERROR);
  886. }
  887. break;
  888. case(INPUT_ARATE+4):
  889. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  890. sprintf(errstr,"Cannot read arate sent from TK\n");
  891. return(DATA_ERROR);
  892. }
  893. break;
  894. case(INPUT_FRAMETIME+4):
  895. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  896. sprintf(errstr,"Cannot read frametime sent from TK\n");
  897. return(DATA_ERROR);
  898. }
  899. dz->frametime = (float)dummy;
  900. break;
  901. case(INPUT_WINDOW_SIZE+4):
  902. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  903. sprintf(errstr,"Cannot read window_size sent from TK\n");
  904. return(DATA_ERROR);
  905. }
  906. break;
  907. case(INPUT_NYQUIST+4):
  908. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  909. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  910. return(DATA_ERROR);
  911. }
  912. break;
  913. case(INPUT_DURATION+4):
  914. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  915. sprintf(errstr,"Cannot read duration sent from TK\n");
  916. return(DATA_ERROR);
  917. }
  918. break;
  919. case(INPUT_MINBRK+4):
  920. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  921. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  922. return(DATA_ERROR);
  923. }
  924. break;
  925. case(INPUT_MAXBRK+4):
  926. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  927. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  928. return(DATA_ERROR);
  929. }
  930. break;
  931. case(INPUT_MINNUM+4):
  932. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  933. sprintf(errstr,"Cannot read minnum sent from TK\n");
  934. return(DATA_ERROR);
  935. }
  936. break;
  937. case(INPUT_MAXNUM+4):
  938. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  939. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  940. return(DATA_ERROR);
  941. }
  942. break;
  943. default:
  944. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  945. return(PROGRAM_ERROR);
  946. }
  947. cnt++;
  948. }
  949. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  950. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  951. return(DATA_ERROR);
  952. }
  953. if(true_cnt)
  954. cnt = true_cnt;
  955. *cmdlinecnt = 0;
  956. while(cnt < argc) {
  957. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  958. return(exit_status);
  959. cnt++;
  960. }
  961. return(FINISHED);
  962. }
  963. /********************************* GET_TK_CMDLINE_WORD *********************************/
  964. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  965. {
  966. if(*cmdlinecnt==0) {
  967. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  968. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  969. return(MEMORY_ERROR);
  970. }
  971. } else {
  972. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  973. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  974. return(MEMORY_ERROR);
  975. }
  976. }
  977. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  978. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  979. return(MEMORY_ERROR);
  980. }
  981. strcpy((*cmdline)[*cmdlinecnt],q);
  982. (*cmdlinecnt)++;
  983. return(FINISHED);
  984. }
  985. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  986. int assign_file_data_storage(int infilecnt,dataptr dz)
  987. {
  988. int exit_status;
  989. int no_sndfile_system_files = FALSE;
  990. dz->infilecnt = infilecnt;
  991. if((exit_status = allocate_filespace(dz))<0)
  992. return(exit_status);
  993. if(no_sndfile_system_files)
  994. dz->infilecnt = 0;
  995. return(FINISHED);
  996. }
  997. /************************* redundant functions: to ensure libs compile OK *******************/
  998. int assign_process_logic(dataptr dz)
  999. {
  1000. return(FINISHED);
  1001. }
  1002. void set_legal_infile_structure(dataptr dz)
  1003. {}
  1004. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1005. {
  1006. return(FINISHED);
  1007. }
  1008. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1009. {
  1010. return(FINISHED);
  1011. }
  1012. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1013. {
  1014. return(FINISHED);
  1015. }
  1016. int read_special_data(char *str,dataptr dz)
  1017. {
  1018. return(FINISHED);
  1019. }
  1020. int inner_loop
  1021. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1022. {
  1023. return(FINISHED);
  1024. }
  1025. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1026. {
  1027. return(FINISHED);
  1028. }
  1029. /******************************** USAGE1 ********************************/
  1030. int usage1(void)
  1031. {
  1032. usage2("shrink");
  1033. return(USAGE_ONLY);
  1034. }
  1035. /**************************** CHECK_SHRINK_VALIDITY_AND_CONSISTENCY *****************************/
  1036. int check_shrink_validity_and_consistency(dataptr dz)
  1037. {
  1038. int chans = dz->infile->channels;
  1039. double srate = (double)dz->infile->srate;
  1040. dz->iparam[SHR_SPLEN] = (int)round(dz->param[SHR_SPLEN] * srate * MS_TO_SECS);
  1041. dz->iparam[SHR_MIN] = (int)round(dz->param[SHR_MIN] * srate) * chans;
  1042. dz->iparam[SHR_SMALL] = (int)round(dz->param[SHR_SMALL] * srate) * chans;
  1043. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX) {
  1044. if(dz->param[SHR_AFTER] >= dz->duration) {
  1045. sprintf(errstr,"Contraction start point is too late.\n");
  1046. return(DATA_ERROR);
  1047. } else if(dz->param[SHR_AFTER] >= (3.0 * dz->duration)/4.0) {
  1048. fprintf(stdout,"WARNING: Contraction start point is late in source.\n");
  1049. fflush(stdout);
  1050. }
  1051. dz->iparam[SHR_LEN] = (int)round(dz->param[SHR_LEN] * srate) * chans;
  1052. }
  1053. else {
  1054. dz->iparam[SHR_GAP] = (int)round(dz->param[SHR_GAP] * srate) * chans;
  1055. if(dz->param[SHR_GAP] <= dz->param[SHR_MIN]) {
  1056. sprintf(errstr,"Minimum event separation must be less than initial event separation.\n");
  1057. return(DATA_ERROR);
  1058. }
  1059. }
  1060. if(dz->param[SHR_CNTRCT] < dz->param[SHR_INK]) {
  1061. sprintf(errstr,"Contraction of inter-events distance can't be less than shrinkage of sounds.\n");
  1062. return(DATA_ERROR);
  1063. }
  1064. if(((dz->iparam[SHR_SPLEN] * 2) + 1) * chans > dz->iparam[SHR_SMALL]) {
  1065. if(dz->iparam[SHR_SMALL] > 0) {
  1066. sprintf(errstr,"Minimum sound length must be greater than 2 splice lengths.\n");
  1067. return(DATA_ERROR);
  1068. } else {
  1069. dz->iparam[SHR_SMALL] = ((dz->iparam[SHR_SPLEN] * 2) + 1) * chans;
  1070. if(dz->iparam[SHR_MIN] == 0)
  1071. dz->iparam[SHR_MIN] = ((dz->iparam[SHR_SPLEN] * 2) + 1) * chans;
  1072. }
  1073. }
  1074. if(dz->iparam[SHR_SMALL] > dz->iparam[SHR_MIN]) {
  1075. if(dz->iparam[SHR_MIN] == 0)
  1076. dz->iparam[SHR_MIN] = dz->iparam[SHR_SMALL];
  1077. else {
  1078. sprintf(errstr,"Minimum sound length must be less than minimum event separation.\n");
  1079. return(DATA_ERROR);
  1080. }
  1081. }
  1082. if(dz->insams[0] <= dz->param[SHR_SMALL]) {
  1083. sprintf(errstr,"Minimum sound length must be less than input sound length.\n");
  1084. return(DATA_ERROR);
  1085. }
  1086. if(((dz->iparam[SHR_SPLEN] * 2) + 1) * chans > dz->iparam[SHR_SMALL]) {
  1087. sprintf(errstr,"Minimum sound length must be greater than length of two splices.\n");
  1088. return(DATA_ERROR);
  1089. }
  1090. if(dz->mode == SHRM_TIMED) {
  1091. dz->iparam[SHR_TIME] = (int)round(dz->param[SHR_TIME] * srate) * chans;
  1092. if(dz->iparam[SHR_TIME] <= dz->iparam[SHR_SPLEN] * chans)
  1093. dz->mode = SHRM_START;
  1094. else if(dz->iparam[SHR_TIME] >= dz->insams[0] - (dz->iparam[SHR_SPLEN] * chans))
  1095. dz->mode = SHRM_CENTRE;
  1096. }
  1097. return FINISHED;
  1098. }
  1099. /********************************************************************************************/
  1100. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1101. {
  1102. if(!strcmp(prog_identifier_from_cmdline,"shrink")) dz->process = SHRINK;
  1103. else {
  1104. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  1105. return(USAGE_ONLY);
  1106. }
  1107. return(FINISHED);
  1108. }
  1109. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  1110. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  1111. {
  1112. int n;
  1113. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1114. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  1115. return(MEMORY_ERROR);
  1116. }
  1117. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  1118. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  1119. return(MEMORY_ERROR);
  1120. }
  1121. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1122. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1123. return(MEMORY_ERROR);
  1124. }
  1125. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1126. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1127. return(MEMORY_ERROR);
  1128. }
  1129. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1130. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1131. return(MEMORY_ERROR);
  1132. }
  1133. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1134. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1135. return(MEMORY_ERROR);
  1136. }
  1137. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1138. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1139. return(MEMORY_ERROR);
  1140. }
  1141. for(n=0;n<brkcnt;n++) {
  1142. dz->brk[n] = NULL;
  1143. dz->brkptr[n] = NULL;
  1144. dz->brkinit[n] = 0;
  1145. dz->brksize[n] = 0;
  1146. }
  1147. return(FINISHED);
  1148. }
  1149. /******************************** USAGE2 ********************************/
  1150. int usage2(char *str)
  1151. {
  1152. if(!strcmp(str,"shrink")) {
  1153. fprintf(stdout,
  1154. "USAGE: shrink shrink 1-3 infile outfile shrinkage\n"
  1155. "gap contract dur spl [-ssmall] [-mmin] [-rrnd] [-n] [-i]\n"
  1156. "USAGE: shrink shrink 4 infile outfile time shrinkage\n"
  1157. "gap contract dur spl [-ssmall] [-mmin] [-rrnd] [-n] [-i]\n"
  1158. "USAGE: shrink shrink 5 infil generic-outfile-name shrinkage\n"
  1159. "wsiz contract aft spl [-ssmall] [-mmin] [-rrnd] [-llen] [-ggate] [-qskew]\n"
  1160. " [-n] [-i] [-e] [-o]\n"
  1161. "USAGE: shrink shrink 6 infil generic-outfile-name peaktimes shrinkage\n"
  1162. "wsiz contract aft spl [-ssmall] [-mmin] [-rrnd] [-llen] [-ggate]\n"
  1163. " [-n] [-i] [-e] [-o]\n"
  1164. "REPEAT SOUND, shortening it on each repetition.\n"
  1165. "Mode 1: Shrink from end. Mode 2: Shrink around midpoint.\n"
  1166. "Mode 3: Shrink from start. Mode 4: Shrink around specified time.\n"
  1167. "OR, ISOLATE EVENTS IN SOUND, and shorten as we proceed from one to next.\n"
  1168. "Mode 5: Shrink around found peaks and output each segment + mixfile.\n"
  1169. "Mode 6: Shrink around specified peaks and output each segment + mixfile.\n"
  1170. "TIME Time around which shrinkage takes place.\n"
  1171. "SHRINKAGE Shortening factor of sound from one repeat to next.\n"
  1172. " Shrinkage stops once events too short for splices.\n"
  1173. "GAP Initial timestep between output events (>= sound duration).\n"
  1174. "CONTRACT Shortening of gaps between output events.\n"
  1175. " 1.0 = events equally spaced, < 1.0 events become closer\n"
  1176. " Events can't overlap, so minimum \"contraction\" = \"shrinkage\".\n"
  1177. "DUR (Minimum) duration of output.\n"
  1178. "AFT Time after which shrinkage begins.\n"
  1179. "SPL Splice length in mS.\n"
  1180. "SMALL Minimum sound length (after which sounds are of equal length).\n"
  1181. "MIN Minimum event separation (after which events are regular in time).\n"
  1182. "RND Randomisation of timings AFTER min event separation reached.\n"
  1183. "PEAKTIMES Textfile list of times of peaks in sound.\n"
  1184. "WSIZ Windowsize (in mS) for extracting envelope (1-100 dflt 100)\n"
  1185. "LEN Minimum segment length before sound squeezing can begin (for -e flag)\n"
  1186. "GATE Level (relative to max) below which found peaks ignored (0-1 dflt 0)\n"
  1187. "SKEW How envelope centred on segment (0 to 1: dflt 0.25). 0.5 = central.\n"
  1188. " Zero value switches the flag off.\n"
  1189. "-n Equalise maximum level of output events (if possible).\n"
  1190. "-i Inverse: Reverse each segment in output.\n"
  1191. " Reversing outfile creates stream of unreversed segments\n"
  1192. " where segments expand/accelerate (rather than shrink/contract).\n"
  1193. "-e Even Squeeze: Sounds shorten in regular manner, from 1st squeezed segment.\n"
  1194. " (squeezed snd lengths not dependent on length of input segments).\n"
  1195. "-o Omit any too-quiet events once a fixed end tempo has been reached.\n"
  1196. "\n");
  1197. } else
  1198. fprintf(stdout,"Unknown option '%s'\n",str);
  1199. return(USAGE_ONLY);
  1200. }
  1201. int usage3(char *str1,char *str2)
  1202. {
  1203. fprintf(stderr,"Insufficient parameters on command line.\n");
  1204. return(USAGE_ONLY);
  1205. }
  1206. /******************************** SHRINK ********************************/
  1207. int shrink(dataptr dz)
  1208. {
  1209. int exit_status, chans = dz->infile->channels, sndchanged, continuation;
  1210. double spliceval = 0.0, splincr = 1.0/(double)dz->iparam[SHR_SPLEN], srate = (double)dz->infile->srate;
  1211. int sndlen, lastsndlen, seglen, lastseglen = 0, halflen, centre, startseg, endseg, remnant, maxat = 0, n = 0, m, k;
  1212. int splen = dz->iparam[SHR_SPLEN], splenlen, dblsplenlen, startsplice, gpinsams, gpinsegm, randrange = 0, offset;
  1213. double outdur, thismaxval, gain = 1.0, contraction, shrinkage, val;
  1214. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  1215. splenlen = splen * chans;
  1216. dblsplenlen = ((splen * 2) + 1) * chans;
  1217. gpinsegm = dz->iparam[SHR_GAP]/chans; // Initial length of segment, in sample-groups
  1218. gpinsams = dz->insams[0]/chans; // Initial length of sound, in sample-groups
  1219. if((exit_status = read_samps(ibuf,dz))<0)
  1220. return(exit_status);
  1221. if(dz->maxival > SHRLEVLIM) {
  1222. fprintf(stdout,"INFO: Input sound very high level: reducing slightly.\n");
  1223. fflush(stdout);
  1224. gain = SHRLEVLIM/dz->maxival;
  1225. shrink_normalise(ibuf,dz->insams[0],gain,maxat);
  1226. }
  1227. if(dz->param[SHR_RAND] > 0.0) { // Range for random-seg-dur variation
  1228. seglen = dz->iparam[SHR_GAP]; // Calculated fron difference of seglen and sndlen
  1229. sndlen = dz->insams[0]; // When they reach their minima
  1230. if(dz->param[SHR_CNTRCT] < 1.0) {
  1231. shrinkage = 1.0;
  1232. contraction = 1.0;
  1233. while(seglen > dz->iparam[SHR_MIN]) {
  1234. sndlen = (int)round((double)gpinsams * shrinkage) * chans;
  1235. sndlen = max(sndlen,dblsplenlen); // Seg can't be shorter than 2 splices
  1236. if(sndlen < dz->iparam[SHR_SMALL])
  1237. sndlen = dz->iparam[SHR_SMALL];
  1238. seglen = (int)round((double)gpinsegm * contraction) * chans;
  1239. seglen = max(seglen,sndlen); // Can't overlap output segs
  1240. contraction *= dz->param[SHR_CNTRCT];
  1241. shrinkage *= dz->param[SHR_INK];
  1242. }
  1243. }
  1244. randrange = seglen - sndlen;
  1245. if(randrange <= chans)
  1246. dz->param[SHR_RAND] = 0.0;
  1247. }
  1248. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1249. memcpy((char *)obuf,(char *)ibuf,dz->insams[0] * sizeof(float));
  1250. seglen = dz->iparam[SHR_GAP];
  1251. sndlen = dz->insams[0];
  1252. lastsndlen = sndlen;
  1253. if(dz->mode == SHRM_TIMED)
  1254. centre = dz->iparam[SHR_TIME];
  1255. else
  1256. centre = (gpinsams/2) * chans;
  1257. if(dz->vflag[SHRNK_INVERT])
  1258. sndchanged = 1; // Forces initial sound to be reversed
  1259. else
  1260. sndchanged = 0;
  1261. outdur = 0.0;
  1262. continuation = 0;
  1263. contraction = dz->param[SHR_CNTRCT]; // Initial values of contraction and shrinkage
  1264. shrinkage = dz->param[SHR_INK];
  1265. for(;;) {
  1266. if(sndchanged && dz->vflag[SHRNK_NORM]) { // Only do normalise, if seg is different from last
  1267. thismaxval = getmaxval(obuf,seglen,&maxat);
  1268. if(thismaxval > FLTERR) {
  1269. if (thismaxval < dz->maxival) {
  1270. gain = dz->maxival/thismaxval;
  1271. shrink_normalise(obuf,seglen,gain,maxat);
  1272. }
  1273. } else {
  1274. fprintf(stdout,"WARNING: Remaining sound too quiet to be normalised: Exiting early.\n");
  1275. fflush(stdout);
  1276. return FINISHED;
  1277. }
  1278. }
  1279. if(dz->vflag[SHRNK_INVERT] && sndchanged)
  1280. reverse_data(obuf,seglen,dz);
  1281. if((exit_status = write_samps(obuf,seglen,dz))<0) // Write a segment
  1282. return(exit_status);
  1283. outdur += (double)(seglen/chans)/srate; // Assess total output length, and exit if limit exceeded
  1284. if(outdur >= dz->param[SHR_DUR])
  1285. break;
  1286. sndchanged = 0; // Shrink sound and contract segment
  1287. sndlen = (int)round((double)gpinsams * shrinkage) * chans;
  1288. sndlen = max(sndlen,dblsplenlen); // Sound can't be shorter than 2 splices
  1289. if(sndlen < dz->iparam[SHR_SMALL])
  1290. sndlen = dz->iparam[SHR_SMALL]; // If there's a limiting sound size, shrink no further
  1291. // contract segment
  1292. seglen = (int)round((double)gpinsegm * contraction) * chans;
  1293. seglen = max(seglen,sndlen); // Can't overlap output segs
  1294. if(seglen < dz->iparam[SHR_MIN]) { // If contracting, & segs reach a min size, stop contraction
  1295. seglen = dz->iparam[SHR_MIN]; // and set "continuation" flag.
  1296. continuation = 1;
  1297. } // If no continuation set,segs reach min size when snap to snd minsize
  1298. if(seglen == lastseglen) { // and can contract no further, so are same seglen.
  1299. if(dz->param[SHR_CNTRCT] < 1.0 && !continuation) // In this case, Halt process.
  1300. return FINISHED; // Segs can be same len if NOT contracting (SHR_CNTRCT = 1.0)
  1301. }
  1302. if(seglen != sndlen && dz->param[SHR_RAND] > 0.0) { // If space between snds, and randomisation set
  1303. val = (drand48() * 2.0) - 1.0; // Randomise output segment position
  1304. val *= dz->param[SHR_RAND];
  1305. offset = (int)round((randrange/chans) * val) * chans;
  1306. seglen += offset;
  1307. }
  1308. if(sndlen != lastsndlen) { // Only recalculate sound output, if soundlength has changed
  1309. sndchanged = 1;
  1310. memset((char *)obuf,0,dz->buflen * sizeof(float));
  1311. memcpy((char *)obuf,(char *)ibuf,dz->insams[0] * sizeof(float));
  1312. switch(dz->mode) {
  1313. case(SHRM_START):
  1314. spliceval = 1.0;
  1315. startsplice = sndlen - splenlen;
  1316. for(n=startsplice;n < sndlen;n+=chans) { // DNSPLICE
  1317. spliceval = max(0.0,spliceval - splincr);
  1318. for(m=0;m<chans;m++)
  1319. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  1320. }
  1321. break;
  1322. case(SHRM_END):
  1323. spliceval = 0.0;
  1324. halflen = ((sndlen/chans)/2) * chans;
  1325. startseg = max(0,centre - halflen);
  1326. endseg = min(dz->insams[0],centre + halflen);
  1327. for(k=0,n = startseg;k < splen;k++,n+=chans) { // UPSPLICE
  1328. spliceval = min(1.0,spliceval + splincr);
  1329. for(m=0;m<chans;m++)
  1330. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  1331. }
  1332. spliceval = 0.0;
  1333. for(k=0,n = endseg-chans;k < splen;k++,n-=chans) {
  1334. spliceval = min(1.0,spliceval + splincr); // DOWNSPLICE (bkwds)
  1335. for(m=0;m<chans;m++)
  1336. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  1337. }
  1338. for(m=startseg,n=0;m < endseg;m++,n++) // COPY SEG TO BUF START
  1339. obuf[n] = obuf[m];
  1340. break;
  1341. case(SHRM_CENTRE):
  1342. spliceval = 0.0;
  1343. startseg = dz->insams[0] - sndlen;
  1344. endseg = dz->insams[0];
  1345. spliceval = 0.0;
  1346. for(k=0,n = startseg;k < splen;k++,n+=chans) { // UPSPLICE
  1347. spliceval = min(1.0,spliceval + splincr);
  1348. for(m=0;m<chans;m++)
  1349. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  1350. }
  1351. for(m=startseg,n=0;m < endseg;m++,n++) // COPY SEG TO BUF START
  1352. obuf[n] = obuf[m];
  1353. break;
  1354. case(SHRM_TIMED):
  1355. spliceval = 0.0;
  1356. halflen = ((sndlen/chans)/2) * chans;
  1357. startseg = max(0,centre - halflen);
  1358. endseg = min(dz->insams[0],startseg + sndlen);
  1359. for(k=0,n = startseg;k < splen;k++,n+=chans) { // UPSPLICE
  1360. spliceval = min(1.0,spliceval + splincr);
  1361. for(m=0;m<chans;m++)
  1362. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  1363. }
  1364. spliceval = 0.0;
  1365. for(k=0,n = endseg-chans;k < splen;k++,n-=chans) {
  1366. spliceval = min(1.0,spliceval + splincr); // DOWNSPLICE (bkwds)
  1367. for(m=0;m<chans;m++)
  1368. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  1369. }
  1370. for(m=startseg,n=0;m < endseg;m++,n++) // COPY SEG TO BUF START
  1371. obuf[n] = obuf[m];
  1372. break;
  1373. }
  1374. remnant = dz->buflen - n; // Zero remainder of buffer
  1375. memset((char *)(obuf + n),0,remnant * sizeof(float));
  1376. lastsndlen = sndlen; // Remember last sound length
  1377. }
  1378. lastseglen = seglen; // Remember last sound-separation
  1379. contraction *= dz->param[SHR_CNTRCT];
  1380. shrinkage *= dz->param[SHR_INK];
  1381. }
  1382. return FINISHED;
  1383. }
  1384. /****************************** GET_MODE *********************************/
  1385. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1386. {
  1387. char temp[200], *p;
  1388. if(sscanf(str,"%s",temp)!=1) {
  1389. sprintf(errstr,"Cannot read mode of program.\n");
  1390. return(USAGE_ONLY);
  1391. }
  1392. p = temp + strlen(temp) - 1;
  1393. while(p >= temp) {
  1394. if(!isdigit(*p)) {
  1395. fprintf(stderr,"Invalid mode of program entered.\n");
  1396. return(USAGE_ONLY);
  1397. }
  1398. p--;
  1399. }
  1400. if(sscanf(str,"%d",&dz->mode)!=1) {
  1401. fprintf(stderr,"Cannot read mode of program.\n");
  1402. return(USAGE_ONLY);
  1403. }
  1404. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1405. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1406. return(USAGE_ONLY);
  1407. }
  1408. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1409. return(FINISHED);
  1410. }
  1411. /****************************** CREATE_SHRINK_SNDBUFS *********************************/
  1412. int create_shrink_sndbufs(dataptr dz)
  1413. {
  1414. int n;
  1415. int bigbufsize, twopow, framesize;
  1416. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX) { // Create 4 sec buffer (larger than any syllable which is a power of 2 in size)
  1417. dz->bufcnt = 2;
  1418. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  1419. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  1420. return(MEMORY_ERROR);
  1421. }
  1422. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  1423. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  1424. return(MEMORY_ERROR);
  1425. }
  1426. for(n = 0;n <dz->bufcnt; n++)
  1427. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  1428. dz->sampbuf[n] = (float *)0;
  1429. bigbufsize = (int)ceil(4 * dz->infile->srate) * dz->infile->channels;
  1430. twopow = 2;
  1431. while(twopow < bigbufsize)
  1432. twopow *= 2;
  1433. bigbufsize = twopow;
  1434. dz->buflen = bigbufsize;
  1435. if((dz->bigbuf = (float *)calloc(dz->buflen * dz->bufcnt,sizeof(float))) == NULL) {
  1436. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1437. return(PROGRAM_ERROR);
  1438. }
  1439. for(n=0;n<dz->bufcnt;n++)
  1440. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  1441. dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  1442. } else {
  1443. framesize = F_SECSIZE * dz->infile->channels;
  1444. dz->bufcnt = 2;
  1445. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  1446. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  1447. return(MEMORY_ERROR);
  1448. }
  1449. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  1450. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  1451. return(MEMORY_ERROR);
  1452. }
  1453. dz->buflen = (int)round(dz->param[SHR_GAP] * dz->infile->srate) * dz->infile->channels;
  1454. dz->buflen = (dz->buflen / framesize) * framesize;
  1455. dz->buflen += framesize;
  1456. bigbufsize = dz->buflen * sizeof(float);
  1457. if(bigbufsize <=0 || bigbufsize * 2 <=0) {
  1458. sprintf(errstr,"Input sound too large for this process\n");
  1459. return(DATA_ERROR);
  1460. }
  1461. if((dz->bigbuf = (float *)malloc(bigbufsize * dz->bufcnt)) == NULL) {
  1462. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  1463. return(PROGRAM_ERROR);
  1464. }
  1465. for(n=0;n<dz->bufcnt;n++)
  1466. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  1467. dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  1468. }
  1469. return(FINISHED);
  1470. }
  1471. /****************************** SHRINK_NORMALISE *********************************/
  1472. void shrink_normalise(float *buf,int len,double gain,int maxat)
  1473. {
  1474. int n = 0;
  1475. double val = fabs(buf[maxat]) * gain;
  1476. if(val > SHRLEVLIM)
  1477. gain = SHRLEVLIM/fabs(buf[maxat]);
  1478. while( n < len) {
  1479. buf[n] = (float)(buf[n] * gain);
  1480. n++;
  1481. }
  1482. }
  1483. /****************************** REVERSE_DATA *********************************/
  1484. void reverse_data(float *obuf,int seglen,dataptr dz)
  1485. {
  1486. int chans = dz->infile->channels;
  1487. float temp;
  1488. int gplen = seglen/chans, n, m, j;
  1489. int centre = (gplen/2) * chans;
  1490. for(n=0,m = seglen - chans; n<centre;n+=chans,m-=chans) {
  1491. for(j=0;j<chans;j++) {
  1492. temp = obuf[n+j];
  1493. obuf[n+j] = obuf[m+j];
  1494. obuf[m+j] = temp;
  1495. }
  1496. }
  1497. }
  1498. /*********************** SHRINK_PARAM_PREPROCESS *********************/
  1499. int shrink_param_preprocess(dataptr dz)
  1500. {
  1501. int exit_status, chans = dz->infile->channels;
  1502. int maxlen, cnt, len;
  1503. int envcnt, trofcnt, orig_env_size, n, j, k, unadjusted_envwindow_sampsize;
  1504. int *peaks, *trofs;
  1505. float *buf = dz->sampbuf[0];
  1506. double maxsamp, thisval, srate = (double)dz->infile->srate;
  1507. // Trim envelopesize to fit exactly into buffers (which are a pow of two in length)
  1508. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX) {
  1509. unadjusted_envwindow_sampsize = round(dz->param[SHR_WSIZE] * MS_TO_SECS * srate) * chans;
  1510. if(unadjusted_envwindow_sampsize < dz->buflen) {
  1511. k = dz->buflen;
  1512. while(unadjusted_envwindow_sampsize<k)
  1513. k /= 2;
  1514. j = k * 2;
  1515. if(j - unadjusted_envwindow_sampsize > unadjusted_envwindow_sampsize - k)
  1516. dz->iparam[SHR_WSIZE] = (int)k;
  1517. else
  1518. dz->iparam[SHR_WSIZE] = (int)j;
  1519. } else {
  1520. k = round((double)unadjusted_envwindow_sampsize/(double)dz->buflen);
  1521. dz->iparam[SHR_WSIZE] = (int)(dz->buflen * k);
  1522. }
  1523. } // Get and store maximum source sample, if required
  1524. fprintf(stdout,"INFO: Finding maximum sample.\n");
  1525. fflush(stdout);
  1526. buf = dz->sampbuf[0];
  1527. if((exit_status = read_samps(buf,dz))<0)
  1528. return(exit_status);
  1529. maxsamp = 0.0;
  1530. while(dz->ssampsread > 0) {
  1531. n = 0;
  1532. while(n < dz->ssampsread) {
  1533. thisval = fabs(buf[n]);
  1534. if(thisval > maxsamp)
  1535. maxsamp = thisval;
  1536. n++;
  1537. }
  1538. if((exit_status = read_samps(buf,dz))<0)
  1539. return(exit_status);
  1540. }
  1541. if(maxsamp <= FLTERR) {
  1542. sprintf(errstr,"NO SIGNIFICANT SIGNAL FOUND IN SOURCE\n");
  1543. return(DATA_ERROR);
  1544. }
  1545. if(dz->mode == SHRM_FINDMX || dz->mode == SHRM_LISTMX) {
  1546. if(dz->param[SHR_GATE] > 0.0)
  1547. dz->param[SHR_GATE] *= maxsamp;
  1548. }
  1549. dz->maxival = maxsamp;
  1550. if((sndseekEx(dz->ifd[0],0,0)) < 0) {
  1551. sprintf(errstr,"sndseek() 1 failed.\n");
  1552. return(SYSTEM_ERROR);
  1553. }
  1554. reset_filedata_counters(dz);
  1555. if(sloom)
  1556. display_virtual_time(dz->total_samps_read,dz);
  1557. if(dz->mode < SHRM_FINDMX)
  1558. return FINISHED;
  1559. for(n=0;n<dz->larray_cnt;n++)
  1560. dz->lparray[n] = NULL;
  1561. if((exit_status = extract_env_from_sndfile(&envcnt,dz))<0) // Data to env, also Copies data to origenv
  1562. return(exit_status);
  1563. orig_env_size = envcnt;
  1564. if(dz->mode == SHRM_FINDMX) {
  1565. extract_peaks_from_envelope(&envcnt,dz); // env reduced to PEAKS as time-val pairs
  1566. if(envcnt == 0) {
  1567. sprintf(errstr,"No peaks found. Silent file.\n");
  1568. return(DATA_ERROR);
  1569. }
  1570. } else { // Inpput peaktimes copied to env, with dummy vals 0.0 (no longer needed)
  1571. if(dz->itemcnt > orig_env_size) {
  1572. sprintf(errstr,"No of peaks specified exceeds number of peaks found in file: reduce window-size or no of peak.\n");
  1573. return DATA_ERROR;
  1574. }
  1575. if((exit_status = copy_peaktimes_to_env_array(dz))<0)
  1576. return(exit_status);
  1577. envcnt = dz->itemcnt;
  1578. }
  1579. extract_trofs_from_envelope(&trofcnt,orig_env_size,dz); // TROFS to 'origenv' as time-val pairs
  1580. if(dz->mode == SHRM_LISTMX) {
  1581. if(trofcnt < dz->itemcnt) {
  1582. sprintf(errstr,"Found too few troughs (%d) for no of peaks specified (%d): decrease windowsize.\n",trofcnt,dz->itemcnt);
  1583. return(DATA_ERROR);
  1584. }
  1585. }
  1586. if(trofcnt == 0) {
  1587. sprintf(errstr,"No troughs found.\n");
  1588. return(PROGRAM_ERROR);
  1589. }
  1590. if(dz->mode == SHRM_FINDMX && dz->param[SHR_GATE] > 0.0) {
  1591. if((exit_status = eliminate_too_low_peaks(&envcnt,&trofcnt,dz))<0)
  1592. return(exit_status);
  1593. }
  1594. if((dz->lparray[LOCAL_PK_AT] = (int *)malloc(dz->buflen * sizeof(int)))==NULL) {
  1595. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  1596. return(MEMORY_ERROR);
  1597. }
  1598. if((dz->parray[LOCAL_PK_VAL] = (double *)malloc(dz->buflen * sizeof(double)))==NULL) {
  1599. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  1600. return(MEMORY_ERROR);
  1601. }
  1602. if((exit_status = eliminate_redundant_trofs(&envcnt,&trofcnt,orig_env_size,dz))<0)
  1603. return(exit_status);
  1604. if((sndseekEx(dz->ifd[0],0,0)) < 0) {
  1605. sprintf(errstr,"sndseek() 2 failed\n");
  1606. return(SYSTEM_ERROR);
  1607. }
  1608. if((dz->lparray[SHR_PEAKS] = (int *)malloc(envcnt * sizeof(int)))==NULL) {
  1609. sprintf(errstr,"INSUFFICIENT MEMORY for array to store peaktimes.\n");
  1610. return(MEMORY_ERROR);
  1611. }
  1612. if((dz->parray[SHR_INVTGAPS] = (double *)malloc(envcnt * sizeof(double)))==NULL) {
  1613. sprintf(errstr,"INSUFFICIENT MEMORY for array to store inverse-time info.\n");
  1614. return(MEMORY_ERROR);
  1615. }
  1616. if((dz->lparray[SHR_TROFS] = (int *)malloc(trofcnt * sizeof(int)))==NULL) {
  1617. sprintf(errstr,"INSUFFICIENT MEMORY for array to store troughtimes.\n");
  1618. return(MEMORY_ERROR);
  1619. }
  1620. peaks = dz->lparray[SHR_PEAKS];
  1621. trofs = dz->lparray[SHR_TROFS];
  1622. dz->itemcnt = envcnt;
  1623. dz->ringsize = trofcnt;
  1624. if(dz->mode == SHRM_FINDMX) {
  1625. if((sndseekEx(dz->ifd[0],0,0)) < 0) {
  1626. sprintf(errstr,"sndseek() 3 failed.\n");
  1627. return(SYSTEM_ERROR);
  1628. }
  1629. reset_filedata_counters(dz);
  1630. if(sloom)
  1631. display_virtual_time(dz->total_samps_read,dz);
  1632. if((exit_status = find_exact_peaktimes(envcnt,peaks,dz))<0)
  1633. return(exit_status);
  1634. } else {
  1635. if((exit_status = copy_peaktimes(dz))<0)
  1636. return(exit_status);
  1637. }
  1638. if((sndseekEx(dz->ifd[0],0,0)) < 0) {
  1639. sprintf(errstr,"sndseek() 4 failed.\n");
  1640. return(SYSTEM_ERROR);
  1641. }
  1642. reset_filedata_counters(dz);
  1643. if(sloom)
  1644. display_virtual_time(dz->total_samps_read,dz);
  1645. if((exit_status = find_exact_troftimes(trofcnt,trofs,dz))<0)
  1646. return(exit_status);
  1647. if((exit_status = test_buffers(envcnt,trofcnt,dz))<0)
  1648. return(exit_status);
  1649. if((sndseekEx(dz->ifd[0],0,0)) < 0) {
  1650. sprintf(errstr,"sndseek() 5 failed.\n");
  1651. return(SYSTEM_ERROR);
  1652. }
  1653. if(dz->iparam[SHR_LEN] > 0) {
  1654. maxlen = 0;
  1655. cnt = 0;
  1656. for(n=1;n<envcnt;n++) {
  1657. len = peaks[n] - peaks[n-1];
  1658. maxlen = max(len,maxlen);
  1659. if(len < dz->iparam[SHR_LEN])
  1660. cnt++;
  1661. }
  1662. if(maxlen < dz->iparam[SHR_LEN]) {
  1663. sprintf(errstr,"Minimum length setting is longer than all segments in file.\n");
  1664. return(DATA_ERROR);
  1665. }
  1666. if(cnt) {
  1667. fprintf(stdout,"INFO: Min length setting is longer than %d out of %d segments in file.\n",cnt,envcnt);
  1668. fflush(stdout);
  1669. }
  1670. }
  1671. reset_filedata_counters(dz);
  1672. if(sloom)
  1673. display_virtual_time(dz->total_samps_read,dz);
  1674. return FINISHED;
  1675. }
  1676. /************************* EXTRACT_PEAKS_FROM_ENVELOPE *******************************/
  1677. void extract_peaks_from_envelope(int *envcnt,dataptr dz)
  1678. {
  1679. int orig_env_size = *envcnt, n, t=0, v=0;
  1680. int islocalmax = 0;
  1681. float lastenv = 0.0;
  1682. int envloc = 0;
  1683. float *env = dz->env;
  1684. fprintf(stdout,"INFO: Finding peaks.\n");
  1685. fflush(stdout);
  1686. for(n=1;n < orig_env_size; n++) {
  1687. t = n * 2; // indexes time
  1688. v = t + 1; // indexes value
  1689. if(env[v] <= lastenv) {
  1690. if(islocalmax) {
  1691. env[envloc] = env[t-2]; // overwrites original envelope, with env peaks
  1692. envloc++;
  1693. env[envloc] = env[v-2]; // overwrites original envelope, with env peaks
  1694. envloc++;
  1695. }
  1696. islocalmax = 0;
  1697. } else
  1698. islocalmax = 1;
  1699. lastenv = env[v];
  1700. }
  1701. if(islocalmax) { // Capture last peak, if a max
  1702. env[envloc] = env[t-2];
  1703. envloc++;
  1704. env[envloc] = env[v-2];
  1705. envloc++;
  1706. }
  1707. *envcnt = envloc/2;
  1708. }
  1709. /************************* EXTRACT_TROFS_FROM_ENVELOPE *******************************/
  1710. void extract_trofs_from_envelope(int *trofcnt,int orig_env_size,dataptr dz)
  1711. {
  1712. int n, t=0, v=0;
  1713. int islocalmin = 0;
  1714. float lastenv = 0.0;
  1715. int envloc = 0;
  1716. float *env = dz->origenv;
  1717. fprintf(stdout,"INFO: Finding troughs.\n");
  1718. fflush(stdout);
  1719. for(n=1;n < orig_env_size; n++) {
  1720. t = n * 2; // indexes time
  1721. v = t + 1; // indexes value
  1722. if(env[v] > lastenv) {
  1723. if(islocalmin) {
  1724. env[envloc] = env[t-2]; // overwrites original envelope, with env trofs
  1725. envloc++;
  1726. env[envloc] = env[v-2]; // overwrites original envelope, with env trofs
  1727. envloc++;
  1728. }
  1729. islocalmin = 0;
  1730. } else
  1731. islocalmin = 1;
  1732. lastenv = env[v];
  1733. }
  1734. if(islocalmin) { // Capture last trof, if a min
  1735. env[envloc] = env[t-2];
  1736. envloc++;
  1737. env[envloc] = env[v-2];
  1738. envloc++;
  1739. }
  1740. *trofcnt = envloc/2;
  1741. }
  1742. /****************************** EXTRACT_ENV_FROM_SNDFILE ******************************/
  1743. int extract_env_from_sndfile(int *envcnt,dataptr dz)
  1744. {
  1745. int exit_status, safety = 100;
  1746. int n, bufcnt, totmem;
  1747. double convertor = 1.0/F_ABSMAXSAMP;
  1748. double time_convertor = 1.0/(dz->infile->channels * dz->infile->srate);
  1749. float *envptr;
  1750. float *buffer = dz->sampbuf[0];
  1751. fprintf(stdout,"INFO: Finding envelope of source.\n");
  1752. fflush(stdout);
  1753. bufcnt = buffers_in_sndfile(dz->buflen,dz);
  1754. *envcnt = windows_in_sndfile(dz);
  1755. totmem = (*envcnt * 2) + safety;
  1756. if((dz->env=(float *)calloc(totmem,sizeof(float)))==NULL) { // *2 -> accomodates time,val PAIRS
  1757. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
  1758. return(MEMORY_ERROR);
  1759. }
  1760. if((dz->origenv =(float *)calloc(totmem,sizeof(float)))==NULL) { // *2 -> accomodates time,val PAIRS
  1761. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array copy.\n");
  1762. return(MEMORY_ERROR);
  1763. }
  1764. envptr = dz->env;
  1765. for(n = 0; n < bufcnt; n++) {
  1766. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1767. return(exit_status);
  1768. if(sloom)
  1769. display_virtual_time(dz->total_samps_read,dz);
  1770. getenv_of_buffer(dz->ssampsread,dz->iparam[SHR_WSIZE],convertor,time_convertor,&envptr,buffer,dz);
  1771. }
  1772. for(n=0;n<totmem;n++)
  1773. dz->origenv[n] = dz->env[n];
  1774. return(FINISHED);
  1775. }
  1776. /************************* GETENV_OF_BUFFER *******************************/
  1777. void getenv_of_buffer(int samps_to_process,int envwindow_sampsize,double convertor,double time_convertor,float **envptr,float *buffer,dataptr dz)
  1778. {
  1779. int start_samp = 0;
  1780. int bufstart = dz->total_samps_read - dz->ssampsread;
  1781. float *env = *envptr;
  1782. while(samps_to_process >= envwindow_sampsize) {
  1783. *env++ = (float)((start_samp + bufstart) * time_convertor);
  1784. *env++ = (float)(getmaxsamp(start_samp,envwindow_sampsize,buffer) * convertor);
  1785. start_samp += envwindow_sampsize;
  1786. samps_to_process -= envwindow_sampsize;
  1787. }
  1788. if(samps_to_process) { /* Handle any final short buffer */
  1789. *env++ = (float)((start_samp + bufstart) * time_convertor);
  1790. *env++ = (float)(getmaxsamp(start_samp,samps_to_process,buffer) * convertor);
  1791. }
  1792. *envptr = env;
  1793. }
  1794. /*************************** GETMAXSAMP *******************************/
  1795. double getmaxsamp(int startsamp, int sampcnt,float *buffer)
  1796. {
  1797. int i, endsamp = startsamp + sampcnt;
  1798. double thisval, thismaxsamp = 0.0;
  1799. for(i = startsamp; i<endsamp; i++) {
  1800. if((thisval = fabs(buffer[i]))>thismaxsamp)
  1801. thismaxsamp = thisval;
  1802. }
  1803. return thismaxsamp;
  1804. }
  1805. /************************* ELIMINATE_TOO_LOW_PEAKS *******************************
  1806. *
  1807. * This also eliminates any trofs between the previous peak and the eliminated peak
  1808. */
  1809. int eliminate_too_low_peaks(int *envcnt,int *trofcnt,dataptr dz)
  1810. {
  1811. int new_envcnt = *envcnt;
  1812. int tabend = new_envcnt * 2;
  1813. int envpos = 0, trofpos = 0, trofstart = 0, j, k, jj, gated, t, v, tt, vv, t1, v1, t2, v2, eliminate;
  1814. double troftime = -1.0;
  1815. float peaktime, mintroft, mintrofv;
  1816. fprintf(stdout,"INFO: Gating low-level peaks.\n");
  1817. fflush(stdout);
  1818. while(envpos < new_envcnt) {
  1819. t = envpos * 2;
  1820. v = t + 1;
  1821. peaktime = dz->env[v];
  1822. trofstart = trofpos;
  1823. tt = trofpos * 2;
  1824. troftime = dz->origenv[tt];
  1825. if(dz->env[v] < dz->param[SHR_GATE]) {
  1826. while(troftime < peaktime) {
  1827. trofpos++;
  1828. tt = trofpos * 2;
  1829. troftime = dz->origenv[tt];
  1830. } // PURE SAFETY: SHOULD NOT BE MORE THAN 1 TROF BETWEEN 2 PEAKS!!!
  1831. eliminate = (trofpos - trofstart) - 1; // Is there more than 1 trof between peaks,
  1832. if(eliminate > 0) { // If so
  1833. tt = trofstart * 2;
  1834. vv = tt + 1;
  1835. mintroft = dz->origenv[tt]; // Find and store the minimum trof value
  1836. mintrofv = dz->origenv[vv];
  1837. for(k = trofstart+1; k < trofpos;k++) {
  1838. tt = k * 2;
  1839. vv = tt + 1;
  1840. if(dz->origenv[vv] < mintrofv) {
  1841. mintroft = dz->origenv[tt];
  1842. mintrofv = dz->origenv[vv];
  1843. }
  1844. } // Eliminate all intervening trofs except 1
  1845. for(k = trofstart+1, j = trofpos; j < *trofcnt;k++,j++) {
  1846. t1 = k * 2;
  1847. v1 = t1 + 1;
  1848. t2 = j * 2;
  1849. v2 = t2 + 1;
  1850. dz->origenv[t1] = dz->origenv[t2];
  1851. dz->origenv[v1] = dz->origenv[v2];
  1852. } // And overwrite the other one with the mintrof data
  1853. k = trofstart;
  1854. t1 = k * 2;
  1855. v1 = t1 + 1;
  1856. dz->origenv[t1] = mintroft;
  1857. dz->origenv[v1] = mintrofv;
  1858. *trofcnt -= eliminate; // Reduce troftable size
  1859. }
  1860. new_envcnt--;
  1861. tabend = new_envcnt * 2; // Eliminate peak
  1862. jj = t;
  1863. while(jj < tabend) { // Reduce peaktable size
  1864. dz->env[jj] = dz->env[jj + 2];
  1865. jj++;
  1866. }
  1867. } else {
  1868. while(troftime < peaktime) { // If peak is OK, skip over trofs till we're beyond peak
  1869. trofpos++;
  1870. tt = trofpos * 2;
  1871. troftime = dz->origenv[tt];
  1872. }
  1873. envpos++;
  1874. }
  1875. }
  1876. if(new_envcnt == 0) {
  1877. sprintf(errstr,"No peaks retained at this gate level.\n");
  1878. return(DATA_ERROR);
  1879. }
  1880. if((gated = *envcnt - new_envcnt) > 0) {
  1881. fprintf(stdout,"INFO: %d peaks removed by gate: %d peaks remain\n",gated,new_envcnt);
  1882. fflush(stdout);
  1883. *envcnt = new_envcnt;
  1884. }
  1885. return FINISHED;
  1886. }
  1887. /************************* ELIMINATE_REDUNDANT_TROFS *******************************/
  1888. int eliminate_redundant_trofs(int *envcnt,int *trofcnt,int orig_env_size,dataptr dz)
  1889. {
  1890. int exit_status, troflocalcnt, start;
  1891. int trofno, peakno, start_of_trofs, lastrofstored = 0, total_trofs_stored;
  1892. int n, t, v, cnt, k, j, t1, t2, v1, v2;
  1893. float peaktime, lastpeaktime, troftime;
  1894. fprintf(stdout,"INFO: Rationalising troughs.\n");
  1895. fflush(stdout);
  1896. if((dz->env[0] < dz->origenv[0]) && !flteq(dz->env[0],0.0)) { // If 1st peak before 1st trof but NOT at zero
  1897. for(n = *trofcnt; n > 0;n--) { // Insert trof at zero
  1898. t = n * 2;
  1899. v = t + 1;
  1900. dz->origenv[t] = dz->origenv[t-2];
  1901. dz->origenv[v] = dz->origenv[v-2];
  1902. }
  1903. dz->origenv[0] = 0.0f;
  1904. dz->origenv[1] = 0.0f;
  1905. (*trofcnt)++;
  1906. }
  1907. peaktime = 0.0;
  1908. if(flteq(dz->env[0],0.0))
  1909. start = 1;
  1910. else
  1911. start = 0;
  1912. trofno = 0;
  1913. for(peakno = start; peakno < *envcnt;peakno++) {
  1914. lastpeaktime = peaktime;
  1915. t = peakno * 2;
  1916. peaktime = dz->env[t];
  1917. start_of_trofs = trofno;
  1918. t = trofno * 2;
  1919. troftime = dz->origenv[t];
  1920. troflocalcnt = 0;
  1921. if(troftime >= peaktime) {
  1922. if((exit_status =insert_trof(trofcnt,trofno,&troftime,peaktime,lastpeaktime,orig_env_size,dz))<0)
  1923. return exit_status;
  1924. }
  1925. while(troftime < peaktime) {
  1926. troflocalcnt++;
  1927. if(++trofno >= *trofcnt)
  1928. break;
  1929. t = trofno * 2;
  1930. troftime = dz->origenv[t];
  1931. }
  1932. if((exit_status =shuffle_trofs(troflocalcnt,trofcnt,start_of_trofs,&trofno,peaktime,lastpeaktime,&lastrofstored,dz))<0)
  1933. return exit_status;
  1934. }
  1935. if(*trofcnt == 0) {
  1936. sprintf(errstr,"No troughs retained : programming problem.\n");
  1937. return(PROGRAM_ERROR);
  1938. }
  1939. total_trofs_stored = lastrofstored + 1;
  1940. if(total_trofs_stored < *trofcnt) { // Count any trofs remaining from orig-array with times before last peak
  1941. n = total_trofs_stored;
  1942. cnt = 0;
  1943. while(dz->origenv[n*2] < peaktime) {
  1944. cnt++;
  1945. if(++n >= *trofcnt)
  1946. break;
  1947. }
  1948. for(k = n,j = total_trofs_stored; k < *trofcnt;k++,j++) {
  1949. t1 = j * 2; // Eliminate these extra trofs still in array before last peak
  1950. v1 = t1 + 1;
  1951. t2 = k * 2;
  1952. v2 = t2 + 1;
  1953. dz->origenv[t1] = dz->origenv[t2];
  1954. dz->origenv[v1] = dz->origenv[v2];
  1955. }
  1956. *trofcnt -= cnt;
  1957. }
  1958. if(*trofcnt > total_trofs_stored) // If there are trofs AFTER the peak
  1959. *trofcnt = total_trofs_stored + 1; // Keep first (only) (SAFETY, should be only 1)
  1960. else if(!flteq(peaktime,dz->duration)) { // Else, if last peak is not at end of file
  1961. t = (*trofcnt) * 2; // Insert a trof at end of file
  1962. v = t + 1;
  1963. dz->origenv[t] = (float)dz->duration;
  1964. dz->origenv[v] = 0.0f;
  1965. (*trofcnt)++;
  1966. }
  1967. return FINISHED;
  1968. }
  1969. /************************* SHUFFLE_TROFS *******************************/
  1970. int shuffle_trofs(int troflocalcnt,int *trofcnt,int start_of_trofs,int *trofno,float peaktime,float lastpeaktime,int *lastrofstored,dataptr dz)
  1971. {
  1972. int k, j, t, v, t1, v1, t2, v2, maxtrofat;
  1973. int allsame, eliminate;
  1974. float maxtrof;
  1975. switch(troflocalcnt) {
  1976. case(0): // Should only happen if first peak at zero.
  1977. if(!flteq(peaktime,0.0)) { // But if it happens elsewhere insert a trof if it does
  1978. for(k = *trofcnt; k > *trofno;k--) { // insert trof-place at current location.
  1979. t = k * 2;
  1980. v = t + 1;
  1981. dz->origenv[t] = dz->origenv[t-2];
  1982. dz->origenv[v] = dz->origenv[v-2];
  1983. }
  1984. t = k * 2;
  1985. v = t + 1;
  1986. dz->origenv[t] = (float)((peaktime - lastpeaktime)/2.0); // Time halfweay between peaks on either side
  1987. dz->origenv[v] = 0.0f; // Trof value 0.0
  1988. (*trofcnt)++;
  1989. }
  1990. *lastrofstored = start_of_trofs;
  1991. break;
  1992. case(1): // If trof falls between 2 peaks, that's OK
  1993. *lastrofstored = start_of_trofs;
  1994. break;
  1995. case(2): // If 2 trofs falls between 2 peaks, 1 associated with left, other with right,peak
  1996. if(*trofno > 0) {
  1997. t = (*trofno) * 2;
  1998. v = t + 1;
  1999. if(flteq(dz->origenv[t],dz->origenv[t-2])) { // BUT if trof same as last, eliminate
  2000. for(k = *trofno; k < *trofcnt;k++) {
  2001. t = k * 2;
  2002. v = t + 1;
  2003. dz->origenv[t-2] = dz->origenv[t];
  2004. dz->origenv[v-2] = dz->origenv[v];
  2005. }
  2006. (*trofcnt)--;
  2007. }
  2008. *lastrofstored = start_of_trofs;
  2009. } else
  2010. *lastrofstored = start_of_trofs + 1;
  2011. break;
  2012. default: // If > 2 trofs eliminate higher trofs
  2013. maxtrof = -1.0f;
  2014. maxtrofat = -1;
  2015. while(troflocalcnt > 2) {
  2016. for(k = start_of_trofs; k < *trofno; k++) { // Find maximum trof
  2017. t = k * 2;
  2018. v = t + 1;
  2019. if(dz->origenv[v] > maxtrof)
  2020. maxtrof = dz->origenv[v];
  2021. maxtrofat = k;
  2022. }
  2023. if(maxtrofat < 0) {
  2024. sprintf(errstr,"Programming Error in search in multitrof\n");
  2025. return(PROGRAM_ERROR);
  2026. }
  2027. allsame = 1; // Are all trofs same ??
  2028. for(k = start_of_trofs; k < *trofno; k++) {
  2029. t = k * 2;
  2030. v = t + 1;
  2031. if(!flteq(dz->origenv[v],maxtrof)) {
  2032. allsame = 0;
  2033. break;
  2034. }
  2035. }
  2036. if(allsame) { // If all same, eliminate all but 2 edge ones
  2037. for(k = start_of_trofs+1,j = *trofno-1;j<*trofcnt; k++,j++) {
  2038. t1 = k * 2;
  2039. v1 = t1 + 1;
  2040. t2 = j * 2;
  2041. v2 = t2 + 1;
  2042. dz->origenv[t1] = dz->origenv[t2];
  2043. dz->origenv[v1] = dz->origenv[v2];
  2044. }
  2045. eliminate = troflocalcnt - 2;
  2046. *trofcnt -= eliminate;
  2047. *trofno -= eliminate;
  2048. troflocalcnt = 2;
  2049. } else { // Else, eliminate loudest trof, and continue round loop
  2050. for(k = maxtrofat+1;k < *trofcnt; k++) {
  2051. t = k * 2;
  2052. v = t + 1;
  2053. dz->origenv[t-2] = dz->origenv[t];
  2054. dz->origenv[v-2] = dz->origenv[v];
  2055. }
  2056. (*trofcnt)--;
  2057. (*trofno)--;
  2058. troflocalcnt--;
  2059. }
  2060. }
  2061. *lastrofstored = start_of_trofs + 1;
  2062. break;
  2063. }
  2064. return FINISHED;
  2065. }
  2066. /************************* FIND_EXACT_PEAKTIMES *******************************/
  2067. int find_exact_peaktimes(int envcnt,int *peaks,dataptr dz)
  2068. {
  2069. int exit_status;
  2070. double maxsamp, val;
  2071. int n, t, maxtime, samptime, searchend, ibufstart_in_file, start, end;
  2072. float *env = dz->env;
  2073. float *buf = dz->sampbuf[0];
  2074. if((exit_status = read_samps(buf,dz))<0)
  2075. return(exit_status);
  2076. ibufstart_in_file = 0;
  2077. if(env[0] == 0.0) {
  2078. peaks[0] = 0;
  2079. start = 1;
  2080. } else
  2081. start = 0;
  2082. if(flteq(env[envcnt - 1],dz->duration)) {
  2083. peaks[envcnt - 1] = dz->insams[0];
  2084. end = envcnt - 1;
  2085. } else
  2086. end = envcnt;
  2087. for(n=start;n < end; n++) {
  2088. t = n * 2; // indexes time
  2089. //v = t + 1; // indexes value
  2090. samptime = (int)round(env[t] * (double)dz->infile->srate) * dz->infile->channels;
  2091. if((searchend = samptime + dz->iparam[SHR_WSIZE]) >= dz->total_samps_read) {
  2092. if(dz->ssampsread < dz->buflen) {
  2093. samptime -= ibufstart_in_file;
  2094. searchend = dz->ssampsread;
  2095. } else {
  2096. ibufstart_in_file = (samptime/F_SECSIZE) * F_SECSIZE;
  2097. if((sndseekEx(dz->ifd[0],ibufstart_in_file,0)) < 0) {
  2098. sprintf(errstr,"sndseek() 6 failed\n");
  2099. return(SYSTEM_ERROR);
  2100. }
  2101. dz->total_samps_read = ibufstart_in_file;
  2102. if((exit_status = read_samps(buf,dz))<0)
  2103. return(exit_status);
  2104. if(dz->ssampsread == 0)
  2105. break;
  2106. if(sloom)
  2107. display_virtual_time(dz->total_samps_read,dz);
  2108. samptime -= ibufstart_in_file;
  2109. searchend = min(samptime + dz->iparam[SHR_WSIZE],dz->ssampsread);
  2110. }
  2111. } else {
  2112. samptime -= ibufstart_in_file;
  2113. searchend -= ibufstart_in_file;
  2114. }
  2115. maxtime = 0;
  2116. maxsamp = fabs(buf[samptime++]);
  2117. while(samptime < searchend) {
  2118. val = fabs(buf[samptime]);
  2119. if(val > maxsamp) {
  2120. maxtime = samptime;
  2121. maxsamp = val;
  2122. }
  2123. samptime++;
  2124. }
  2125. maxtime += ibufstart_in_file;
  2126. maxtime /= dz->infile->channels; // peaks must be at channel-group boundaries
  2127. maxtime *= dz->infile->channels;
  2128. peaks[n] = maxtime;
  2129. }
  2130. return FINISHED;
  2131. }
  2132. /************************* FIND_EXACT_TROFTIMES ********************************/
  2133. int find_exact_troftimes(int trofcnt,int *trofs,dataptr dz)
  2134. {
  2135. int exit_status, chans = dz->infile->channels;
  2136. double peaktime, lastpeaktime, srate = (double)dz->infile->srate;
  2137. int n, t, p, searchstt, searchend, start, end, minpeakat, troftime;
  2138. int searchlen;
  2139. float *env = dz->origenv, minpeak;
  2140. int *peaks = dz->lparray[SHR_PEAKS];
  2141. float *buf = dz->sampbuf[0];
  2142. if((exit_status = read_samps(buf,dz))<0)
  2143. return(exit_status);
  2144. //ibufstart_in_file = 0;
  2145. if(env[0] == 0.0) {
  2146. trofs[0] = 0;
  2147. start = 1;
  2148. } else
  2149. start = 0;
  2150. if(flteq(env[trofcnt - 1],dz->duration)) {
  2151. trofs[trofcnt - 1] = dz->insams[0];
  2152. end = trofcnt - 1;
  2153. } else
  2154. end = trofcnt;
  2155. for(n=start;n < end; n++) {
  2156. t = n * 2; // indexes time
  2157. //v = t + 1; // indexes value
  2158. troftime = (int)round(env[t] * (double)dz->infile->srate) * dz->infile->channels;
  2159. searchstt = troftime/dz->iparam[SHR_WSIZE]; // Locate window in which trough occurred
  2160. searchstt *= dz->iparam[SHR_WSIZE]; // Set search start to start of window
  2161. searchend = min(dz->insams[0],searchstt + dz->iparam[SHR_WSIZE]); // and end to window end
  2162. for(p = 0;p < dz->itemcnt;p++) {
  2163. if(peaks[p] > troftime) // Find times of enclosing peaks
  2164. break;
  2165. }
  2166. if(p <dz->itemcnt)
  2167. peaktime = (peaks[p]/chans)/srate;
  2168. else
  2169. peaktime = dz->duration;
  2170. if(p > 0)
  2171. lastpeaktime = (peaks[p-1]/chans)/srate;
  2172. else
  2173. lastpeaktime = 0.0;
  2174. if(dz->mode == SHRM_LISTMX) { // If these are specified (not found) peaks
  2175. if(searchend > peaks[p]) // and searchend is beyond next peak,
  2176. searchend = peaks[p]; // move search end to peak-position
  2177. if(p > 0) { // Check if peak which precedes trough is after search start
  2178. if(peaks[p-1] > searchstt) // and if so, move search start to peak-position
  2179. searchstt = peaks[p-1];
  2180. }
  2181. }
  2182. searchlen = searchend - searchstt;
  2183. if((exit_status = find_local_minpeak(&minpeakat,&minpeak,searchstt,searchend,searchlen,lastpeaktime,peaktime,dz))< 0)
  2184. return exit_status;
  2185. trofs[n] = minpeakat;
  2186. }
  2187. return FINISHED;
  2188. }
  2189. /******************************** SHRINK2 ********************************/
  2190. int shrink2(dataptr dz)
  2191. {
  2192. int exit_status, chans = dz->infile->channels, tooquiet = 0, at_contraction_end = 0, quiet, suppressed = 0;
  2193. int shrink_started = 0;
  2194. double spliceval = 0.0, splincr = 1.0/(double)dz->iparam[SHR_SPLEN], srate = (double)dz->infile->srate;
  2195. int sndlen, lastsndlen = 0, evenly_sndlen = 0, inseglen, outseglen, centre, maxat = 0, n = 0, m, k, halflen;
  2196. int splen = dz->iparam[SHR_SPLEN], dblsplenlen, randrange = 0, offset;
  2197. int trofno, peakno, extraspace, start = 0, end = 0, nextrof, nextpeak, sndwidth, halfsndwidth, centring, peakadj;
  2198. int startsnd = 0, endsnd = 0, lastoutseglen = 0;
  2199. double outdur, lastoutdur = 0.0, thismaxval, gain = 1.0, contraction, shrinkage, val;
  2200. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  2201. int *peaks = dz->lparray[SHR_PEAKS], *trofs = dz->lparray[SHR_TROFS], trofcnt = dz->ringsize, peakcnt = dz->itemcnt;
  2202. double *invtgaps = dz->parray[SHR_INVTGAPS];
  2203. char num[200], filename[400], temp[400], temp2[64];
  2204. //splenlen = splen * chans;
  2205. dblsplenlen = ((splen * 2) + 1) * chans;
  2206. outdur = 0.0;
  2207. contraction = 1; // Initial values of contraction and shrinkage
  2208. shrinkage = 1;
  2209. outdur = 0.0;
  2210. trofno = 0;
  2211. dz->insams[0] = find_outsamps(dz); // This sets up correct printout of progress-bar
  2212. strcpy(filename,dz->outfilename); // Open the mixfile (sndfile already open)
  2213. sprintf(temp,"%d",peakcnt);
  2214. strcat(filename,temp);
  2215. if((dz->fp = fopen(filename,"w"))==NULL) {
  2216. sprintf(errstr,"Cannot open output mixfile %s\n",filename);
  2217. return(USER_ERROR);
  2218. }
  2219. for (peakno = 0; peakno < peakcnt;peakno++) {
  2220. strcpy(filename,dz->outfilename);
  2221. sprintf(num,"%d",peakno);
  2222. strcat(filename,num);
  2223. strcat(filename,".wav");
  2224. extraspace = 0;
  2225. if(peakno == 0 && peaks[0] == 0) {
  2226. start = 0;
  2227. end = trofs[0];
  2228. } else {
  2229. while(trofs[trofno] < peaks[peakno]) {
  2230. if(++trofno >= trofcnt) { // If reach end without finding trof AFTER peak
  2231. start = trofs[trofno-1]; // peak must be at end
  2232. end = peaks[peakno]; // so peak is end of segment
  2233. break;
  2234. }
  2235. }
  2236. if(trofno < trofcnt) { // Otherwise use trofs on either side of peak
  2237. end = trofs[trofno]; // To define INPUT segment size from which to cut sound
  2238. start = trofs[trofno-1];
  2239. }
  2240. }
  2241. if(trofno < trofcnt-1 && peakno < peakcnt - 1) {
  2242. nextrof = trofs[trofno + 1]; // Where there are 2 trofs between peaks
  2243. nextpeak = peaks[peakno + 1]; // Note the gap between the trofs
  2244. if(nextrof < nextpeak) // To add to the OUTPUT segment length
  2245. extraspace = trofs[trofno + 1] - trofs[trofno];
  2246. }
  2247. inseglen = end - start;
  2248. memset((char *)obuf,0,dz->buflen * sizeof(float));
  2249. if(inseglen < dblsplenlen) { // If input segment too short
  2250. fprintf(stdout,"WARNING: Input found-segment %d too short\n",peakno+1);
  2251. fflush(stdout);
  2252. continue; // skip to next segment
  2253. }
  2254. sndseekEx(dz->ifd[0],start,0);
  2255. if((exit_status = read_samps(ibuf,dz))<0)
  2256. return(exit_status);
  2257. memcpy((char *)obuf,(char *)ibuf,dz->ssampsread * sizeof(float));
  2258. if(outdur > dz->param[SHR_AFTER]) { // If shrinkage is about to start or has started
  2259. if(dz->vflag[SHRNK_EVENLY]) { // If shrinking evenly
  2260. if(!shrink_started) { // If even-shrinking about to start
  2261. evenly_sndlen = (int)round((double)inseglen/chans * shrinkage) * chans; // Get first shrunksnd len from seglen
  2262. if(dz->iparam[SHR_LEN] > 0) { // If there's a min length for first shrunk
  2263. if(dz->iparam[SHR_LEN] > evenly_sndlen) // and this is greater than calcd length,
  2264. evenly_sndlen = dz->iparam[SHR_LEN]; // increase sndlen to min length
  2265. }
  2266. if(evenly_sndlen > inseglen) { // IF this sndlength is TOO BIG for the segment
  2267. shrink_started = 0;
  2268. sndlen = inseglen;
  2269. } else { // Else set sndlen to newly calcd length
  2270. shrink_started = 1;
  2271. sndlen = evenly_sndlen;
  2272. }
  2273. } else { // IF even-shrinkage already started
  2274. evenly_sndlen = (int)round((double)evenly_sndlen/chans * shrinkage) * chans;
  2275. sndlen = evenly_sndlen; // calc shrink from previous (theoretical) sndlen
  2276. if(sndlen > inseglen) // But it can't be greater than inseglen
  2277. sndlen = inseglen;
  2278. } // If not shrinking evenly but shrinkage has started
  2279. } else // Calculate sndlen from seglen
  2280. sndlen = (int)round((double)inseglen/chans * shrinkage) * chans;
  2281. if(sndlen < dz->iparam[SHR_SMALL]) {
  2282. if(dz->iparam[SHR_SMALL] <= inseglen)
  2283. sndlen = dz->iparam[SHR_SMALL]; // If there's a limiting sound size, stick at limiting size
  2284. else
  2285. sndlen = inseglen; // unless that's not possible (inseg too small)
  2286. }
  2287. } else // If shrinkage not started, sndlen = inseglen
  2288. sndlen = inseglen;
  2289. sndlen = max(sndlen,dblsplenlen); // Sound can't be shorter than 2 splices
  2290. switch(dz->mode) {
  2291. case(SHRM_FINDMX):
  2292. centre = ((inseglen/chans)/2)*chans; // Actual centre of input data
  2293. sndwidth = sndlen/chans; // Width of snd to be cut
  2294. halfsndwidth = sndwidth/2;
  2295. centring = (int)round(dz->param[SHR_SKEW] * sndwidth);
  2296. peakadj = (centring - halfsndwidth) * chans;
  2297. if(peakadj < 0) { // Snd is cut with centre at start, middle or end (etc) of src
  2298. startsnd = max(0,centre + peakadj); // IF there is space ....
  2299. endsnd = startsnd + sndlen;
  2300. if(endsnd >= inseglen) {
  2301. endsnd = inseglen;
  2302. startsnd = endsnd - sndlen;
  2303. }
  2304. } else if(peakadj > 0) { // IF not, adjust appropriately
  2305. endsnd = min(inseglen,centre + peakadj);
  2306. startsnd = endsnd - sndlen;
  2307. if(startsnd < 0) {
  2308. startsnd = 0;
  2309. endsnd = startsnd + sndlen;
  2310. }
  2311. }
  2312. if(endsnd - startsnd < dblsplenlen) {
  2313. sprintf(errstr,"Error in sound length calculation.\n");
  2314. return(PROGRAM_ERROR);
  2315. }
  2316. break;
  2317. case(SHRM_LISTMX):
  2318. centre = peaks[peakno] - start;
  2319. halflen = ((sndlen/chans)/2) * chans;
  2320. startsnd = centre - halflen;
  2321. if(startsnd < 0)
  2322. startsnd = 0;
  2323. endsnd = startsnd + sndlen;
  2324. endsnd = min(endsnd,inseglen);
  2325. break;
  2326. } // If shrinking evenly
  2327. if(dz->vflag[SHRNK_EVENLY] && outdur > dz->param[SHR_AFTER]) // Calc outseglen from previous
  2328. outseglen = (int)round((double)(lastoutseglen/chans) * shrinkage) * chans;
  2329. else { // Else,
  2330. outseglen = inseglen + extraspace; // outseglen includes any extra space between snds
  2331. if(outdur > dz->param[SHR_AFTER]) // Contract all this
  2332. outseglen = ((int)round((double)(outseglen/chans) * contraction) * chans);
  2333. }
  2334. outseglen = max(outseglen,sndlen); // Can't overlap output segs
  2335. if(outseglen <= dz->iparam[SHR_MIN]) { // If contracting, & segs reach a min size, stop contraction
  2336. outseglen = dz->iparam[SHR_MIN];
  2337. at_contraction_end = 1;
  2338. }
  2339. if(dz->param[SHR_RAND] > 0.0) { // If randomisation set, randomise output segment position
  2340. randrange = ((outseglen - sndlen)/2)/chans; // If there is any space
  2341. if(randrange > 1) {
  2342. val = (drand48() * 2.0) - 1.0;
  2343. val *= dz->param[SHR_RAND];
  2344. offset = (int)round(randrange * val) * chans;
  2345. outseglen += offset;
  2346. }
  2347. }
  2348. spliceval = 0.0;
  2349. for(k=0,n = startsnd;k < splen;k++,n+=chans) { // Upsplice
  2350. spliceval = min(1.0,spliceval + splincr);
  2351. for(m=0;m<chans;m++)
  2352. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  2353. }
  2354. spliceval = 0.0;
  2355. for(k=0,n = endsnd-chans;k < splen;k++,n-=chans) {
  2356. spliceval = min(1.0,spliceval + splincr); // Downsplice (bkwds)
  2357. for(m=0;m<chans;m++)
  2358. obuf[n+m] = (float)(obuf[n+m] * spliceval);
  2359. }
  2360. if(startsnd > 0) {
  2361. for(m=startsnd,n=0;m < endsnd;m++,n++) // Copy seg to buf start
  2362. obuf[n] = obuf[m];
  2363. endsnd = n;
  2364. }
  2365. for(n = endsnd;n < outseglen;n++) // Zero remainder of output
  2366. obuf[n] = 0.0f;
  2367. quiet = 0;
  2368. if(dz->vflag[SHRNK_NORM]) {
  2369. thismaxval = getmaxval(obuf,sndlen,&maxat);
  2370. if(thismaxval > MINUS60DB) {
  2371. if (thismaxval < dz->maxival) {
  2372. gain = dz->maxival/thismaxval;
  2373. shrink_normalise(obuf,sndlen,gain,maxat);
  2374. }
  2375. } else {
  2376. tooquiet++;
  2377. quiet = 1;
  2378. }
  2379. }
  2380. if(dz->vflag[SHR_SUPPRESS] && at_contraction_end && quiet) {
  2381. tooquiet--;
  2382. suppressed++;
  2383. continue;
  2384. }
  2385. if(dz->vflag[SHRNK_INVERT])
  2386. reverse_data(obuf,outseglen,dz);
  2387. if(peakno > 0) {
  2388. if(sndcloseEx(dz->ofd) < 0) {
  2389. sprintf(errstr,"Failed to close output file %d\n",peakno+1);
  2390. return(SYSTEM_ERROR);
  2391. }
  2392. dz->ofd = -1;
  2393. if((exit_status = create_sized_outfile(filename,dz))<0)
  2394. return(exit_status);
  2395. sndseekEx(dz->ifd[0],0,0);
  2396. reset_filedata_counters(dz);
  2397. }
  2398. if((exit_status = write_samps(obuf,outseglen,dz))<0) // Write a segment
  2399. return(exit_status);
  2400. lastoutseglen = outseglen;
  2401. strcpy(temp,filename); // filename
  2402. sprintf(temp2," %lf",outdur); // time
  2403. strcat(temp,temp2);
  2404. sprintf(temp2," %d",chans); // channel count
  2405. strcat(temp,temp2);
  2406. strcat(temp," 1.0\n"); // gain 1.0
  2407. if(fputs(temp,dz->fp) < 0) {
  2408. sprintf(errstr,"Error writing to output mixfile\n");
  2409. return(PROGRAM_ERROR);
  2410. }
  2411. if(dz->vflag[SHRNK_INVERT])
  2412. lastoutdur = outdur;
  2413. outdur += (double)(outseglen/chans)/srate; // Get output length
  2414. if(dz->vflag[SHRNK_INVERT] && peakno > 0)
  2415. invtgaps[peakno-1] = (((double)(sndlen - lastsndlen)/chans)/srate) + lastoutdur;
  2416. if(outdur > dz->param[SHR_AFTER]) {
  2417. contraction *= dz->param[SHR_CNTRCT];
  2418. shrinkage *= dz->param[SHR_INK];
  2419. }
  2420. if(dz->vflag[SHRNK_INVERT])
  2421. lastsndlen = sndlen;
  2422. }
  2423. fclose(dz->fp);
  2424. if(dz->vflag[SHRNK_INVERT]) {
  2425. strcpy(filename,dz->outfilename); // Open the inverse time-gaps listing file
  2426. sprintf(temp,"%d",peakcnt+1);
  2427. strcat(filename,temp);
  2428. if((dz->fp = fopen(filename,"w"))==NULL) {
  2429. sprintf(errstr,"Cannot open output file %s\n",filename);
  2430. return(USER_ERROR);
  2431. }
  2432. for (peakno = 0; peakno < peakcnt-1;peakno++) {
  2433. sprintf(temp,"%lf\n",invtgaps[peakno]);
  2434. if(fputs(temp,dz->fp) < 0) {
  2435. sprintf(errstr,"Error writing to output mixfile\n");
  2436. return(PROGRAM_ERROR);
  2437. }
  2438. }
  2439. fclose(dz->fp);
  2440. }
  2441. if(tooquiet) {
  2442. fprintf(stdout,"INFO: %d segments too quiet to be normalised.\n",tooquiet);
  2443. fflush(stdout);
  2444. }
  2445. if(suppressed) {
  2446. fprintf(stdout,"INFO: %d segments suppressed\n",suppressed);
  2447. fflush(stdout);
  2448. }
  2449. return FINISHED;
  2450. }
  2451. /****************************** GETMAXVAL *********************************/
  2452. double getmaxval(float *buf,int len,int *maxat)
  2453. {
  2454. int n = 0;
  2455. double maxval = 0.0;
  2456. *maxat = 0;
  2457. while( n < len) {
  2458. if(fabs(buf[n]) > maxval) {
  2459. maxval = fabs(buf[n]);
  2460. *maxat = n;
  2461. }
  2462. n++;
  2463. }
  2464. return maxval;
  2465. }
  2466. /****************************** TEST_BUFFERS *********************************
  2467. *
  2468. * Test length of found segments against assigned buffersize
  2469. */
  2470. int test_buffers(int envcnt,int trofcnt,dataptr dz)
  2471. {
  2472. int *peaks = dz->lparray[SHR_PEAKS], *trofs = dz->lparray[SHR_TROFS], n, m, segstart, segend, peakpos, seglen;
  2473. int maxseglen = dz->buflen, twopow, bigbufsize, bigat = 0, totalcnt;
  2474. double srate = (double)dz->infile->srate;
  2475. int chans = dz->infile->channels;
  2476. m = 0;
  2477. if (peaks[0] < trofs[0])
  2478. segstart = peaks[0]; // If data starts with peak, this is start of first segment
  2479. else // otherwise
  2480. segstart = trofs[0]; // Data starts at first trof
  2481. totalcnt = segstart;
  2482. for(n = 1; n < envcnt; n++) {
  2483. peakpos = peaks[n];
  2484. while(trofs[m] < peakpos) { // Move through trofs until cross peak
  2485. if(++m >= trofcnt)
  2486. break;
  2487. }
  2488. segend = trofs[m-1]; // Segend is trof before peak
  2489. seglen = segend - segstart;
  2490. if(seglen > maxseglen) {
  2491. maxseglen = seglen;
  2492. bigat = totalcnt;
  2493. }
  2494. totalcnt += seglen;
  2495. segstart = segend;
  2496. }
  2497. if(maxseglen > dz->buflen) {
  2498. free(dz->bigbuf);
  2499. twopow = 2;
  2500. while(twopow < maxseglen)
  2501. twopow *= 2;
  2502. bigbufsize = twopow;
  2503. dz->buflen = bigbufsize;
  2504. if((dz->bigbuf = (float *)calloc(dz->buflen * dz->bufcnt,sizeof(float))) == NULL) {
  2505. sprintf(errstr,"INSUFFICIENT MEMORY to store largest segment (at %lf).\n",(double)(bigat/chans)/srate);
  2506. return(PROGRAM_ERROR);
  2507. }
  2508. for(n=0;n<dz->bufcnt;n++)
  2509. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  2510. dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  2511. }
  2512. return FINISHED;
  2513. }
  2514. /****************************** BUFFERS_IN_SNDFILE ******************************/
  2515. int buffers_in_sndfile(int buffer_size,dataptr dz)
  2516. {
  2517. int bufcnt;
  2518. if(((bufcnt = dz->insams[0]/buffer_size)*buffer_size)!=dz->insams[0])
  2519. bufcnt++;
  2520. return(bufcnt);
  2521. }
  2522. /****************************** WINDOWS_IN_SNDFILE [GET_ENVSIZE] ******************************/
  2523. int windows_in_sndfile(dataptr dz)
  2524. {
  2525. int envsize, winsize = dz->iparam[SHR_WSIZE];
  2526. if(((envsize = dz->insams[0]/winsize) * winsize)!=dz->insams[0])
  2527. envsize++;
  2528. return(envsize);
  2529. }
  2530. /**************************************** FIND_OUTDUR *****************************************
  2531. *
  2532. * Calcualte expected output duration for use in calculating proprtional vals to send
  2533. * to sloom progress-bar.
  2534. *
  2535. * This calculation ignores suppressed (too quiet) segments in output
  2536. * so generates a length val >= (rather than =) to the actual output duration-in-samples.
  2537. * This is OK for progress-bar display.
  2538. */
  2539. int find_outsamps(dataptr dz)
  2540. {
  2541. int chans = dz->infile->channels;
  2542. double srate = (double)dz->infile->srate;
  2543. int inseglen, outseglen, lastoutseglen = 0, sndlen, evenly_sndlen = 0;
  2544. int splen = dz->iparam[SHR_SPLEN], dblsplenlen;
  2545. int trofno, peakno, extraspace, start = 0, end = 0, nextrof, nextpeak;
  2546. double outdur, contraction, shrinkage;
  2547. int *peaks = dz->lparray[SHR_PEAKS], *trofs = dz->lparray[SHR_TROFS], trofcnt = dz->ringsize, peakcnt = dz->itemcnt;
  2548. //splenlen = splen * chans;
  2549. dblsplenlen = ((splen * 2) + 1) * chans;
  2550. //gpinsegm = dz->iparam[SHR_GAP]/chans; // Initial length of segment, in sample-groups
  2551. outdur = 0.0;
  2552. contraction = 1; // Initial values of contraction and shrinkage
  2553. shrinkage = 1;
  2554. outdur = 0.0;
  2555. trofno = 0;
  2556. for (peakno = 0; peakno < peakcnt;peakno++) {
  2557. extraspace = 0;
  2558. if(peakno == 0 && peaks[0] == 0) {
  2559. start = 0;
  2560. end = trofs[0];
  2561. } else {
  2562. while(trofs[trofno] < peaks[peakno]) {
  2563. if(++trofno >= trofcnt) { // If reach end without finding trof AFTER peak
  2564. start = trofs[trofno-1]; // peak must be at end
  2565. end = peaks[peakno]; // so peak is end of segment
  2566. break;
  2567. }
  2568. }
  2569. if(trofno < trofcnt) { // Otherwise use trofs on either side of peak
  2570. end = trofs[trofno]; // To define INPUT segment size from which to cut sound
  2571. start = trofs[trofno-1];
  2572. }
  2573. }
  2574. if(trofno < trofcnt-1 && peakno < peakcnt - 1) {
  2575. nextrof = trofs[trofno + 1]; // Where there are 2 trofs between peaks
  2576. nextpeak = peaks[peakno + 1]; // Note the gap between the trofs
  2577. if(nextrof < nextpeak) // To add to the OUTPUT segment length
  2578. extraspace = trofs[trofno + 1] - trofs[trofno];
  2579. }
  2580. inseglen = end - start;
  2581. if(inseglen < dblsplenlen) { // If input segment too short
  2582. outseglen = inseglen + extraspace;
  2583. outdur += (double)(outseglen /chans)/srate; // Get output length
  2584. if(outdur > dz->param[SHR_AFTER]) {
  2585. contraction *= dz->param[SHR_CNTRCT];
  2586. shrinkage *= dz->param[SHR_INK];
  2587. }
  2588. continue;
  2589. }
  2590. if(outdur > dz->param[SHR_AFTER]) { // If shrinkage is about to start or has started
  2591. if(dz->vflag[SHRNK_EVENLY]) { // If shrinking evenly
  2592. if(evenly_sndlen == 0) { // If even-shrinking about to start
  2593. evenly_sndlen = (int)round((double)inseglen/chans * shrinkage) * chans; // Get first shrunksnd len from seglen
  2594. if(dz->iparam[SHR_LEN] > 0) { // If there's a min length for first shrunk
  2595. if(dz->iparam[SHR_LEN] > evenly_sndlen) // and this is greater than calcd length,
  2596. evenly_sndlen = dz->iparam[SHR_LEN]; // increase sndlen to min length
  2597. }
  2598. if(evenly_sndlen > inseglen) { // IF this sndlength is TOO BIG for the segment
  2599. evenly_sndlen = 0; // Don't do shrinking yet
  2600. sndlen = inseglen;
  2601. } else // Else set sndlen to newly calcd length
  2602. sndlen = evenly_sndlen;
  2603. } else { // IF even-shrinkage already started
  2604. evenly_sndlen = (int)round((double)evenly_sndlen/chans * shrinkage) * chans;
  2605. sndlen = evenly_sndlen; // calc shrink from previous (theoretical) sndlen
  2606. if(sndlen > inseglen) { // But it can't be greater than inseglen
  2607. sndlen = inseglen;
  2608. }
  2609. } // If not shrinking evenly but shrinkage has started
  2610. } else // Calculate sndlen from seglen
  2611. sndlen = (int)round((double)inseglen/chans * shrinkage) * chans;
  2612. if(sndlen < dz->iparam[SHR_SMALL] && dz->iparam[SHR_SMALL] >= inseglen)
  2613. sndlen = dz->iparam[SHR_SMALL]; // If there's a limiting sound size, shrink no further
  2614. } else // If shrinkage not started, sndlen = inseglen
  2615. sndlen = inseglen;
  2616. sndlen = max(sndlen,dblsplenlen); // Sound can't be shorter than 2 splices
  2617. if(outdur > dz->param[SHR_AFTER] && dz->vflag[SHRNK_EVENLY]) // Calc outseglen from previous
  2618. outseglen = (int)round((double)(lastoutseglen/chans) * shrinkage) * chans;
  2619. else { // Else, outseglen includes any extra space between snds
  2620. outseglen = inseglen + extraspace; // Contract all this
  2621. outseglen = ((int)round((double)(outseglen/chans) * contraction) * chans);
  2622. }
  2623. if(outseglen < dz->iparam[SHR_MIN])
  2624. outseglen = dz->iparam[SHR_MIN];
  2625. outseglen = max(outseglen,sndlen); // Can't overlap output segs
  2626. outdur += (double)(outseglen/chans)/srate; // Get output length
  2627. if(outdur > dz->param[SHR_AFTER]) {
  2628. contraction *= dz->param[SHR_CNTRCT];
  2629. shrinkage *= dz->param[SHR_INK];
  2630. }
  2631. lastoutseglen = outseglen;
  2632. }
  2633. return (int)ceil(outdur * srate) * chans;
  2634. }
  2635. /**************************** HANDLE_THE_SPECIAL_DATA ****************************/
  2636. int handle_the_special_data(char *str,dataptr dz)
  2637. {
  2638. double dummy = 0.0, lasttime = -1.0;
  2639. double *q;
  2640. FILE *fp;
  2641. int cnt;
  2642. char temp[200], *p;
  2643. if((fp = fopen(str,"r"))==NULL) {
  2644. sprintf(errstr,"Cannot open file %s to read peak times.\n",str);
  2645. return(DATA_ERROR);
  2646. }
  2647. cnt = 0;
  2648. while(fgets(temp,200,fp)!=NULL) {
  2649. p = temp;
  2650. if(*p == ';') // Allow comments in file
  2651. continue;
  2652. while(get_float_from_within_string(&p,&dummy)) {
  2653. if(dummy < 0.0) {
  2654. sprintf(errstr,"Time (%lf) less than zero in peak times file %s.\n",dummy,str);
  2655. return(DATA_ERROR);
  2656. } else if(dummy > dz->duration) {
  2657. sprintf(errstr,"Time (%lf) beyond end of sound (%lf) in peak times file %s.\n",dummy,dz->duration,str);
  2658. return(DATA_ERROR);
  2659. } else if(dummy <= lasttime) {
  2660. sprintf(errstr,"Times (%lf then %lf) do not increase in peak times file %s.\n",dummy,lasttime,str);
  2661. return(DATA_ERROR);
  2662. }
  2663. lasttime = dummy;
  2664. cnt++;
  2665. }
  2666. }
  2667. if(cnt == 0) {
  2668. sprintf(errstr,"No valid times in peak-times file %s.\n",str);
  2669. return(DATA_ERROR);
  2670. }
  2671. dz->itemcnt = cnt;
  2672. dz->larray_cnt = 1;
  2673. if((dz->parray[SHR_INPUT_PKS] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  2674. sprintf(errstr,"INSUFFICIENT MEMORY to store packet times.\n");
  2675. return(MEMORY_ERROR);
  2676. }
  2677. fseek(fp,0,0);
  2678. q = dz->parray[SHR_INPUT_PKS];
  2679. while(fgets(temp,200,fp)!=NULL) {
  2680. p = temp;
  2681. if(*p == ';') // Allow comments in file
  2682. continue;
  2683. while(get_float_from_within_string(&p,&dummy)) {
  2684. *q = dummy;
  2685. q++;
  2686. }
  2687. }
  2688. if(fclose(fp)<0) {
  2689. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",str);
  2690. fflush(stdout);
  2691. }
  2692. return(FINISHED);
  2693. }
  2694. /************************* COPY_PEAKTIMES_TO_ENV_ARRAY *******************************/
  2695. int copy_peaktimes_to_env_array(dataptr dz)
  2696. {
  2697. int n, m;
  2698. float *env = dz->env;
  2699. double *pks = dz->parray[SHR_INPUT_PKS];
  2700. for(n=0,m=0;n < dz->itemcnt; n++,m+=2) {
  2701. env[m] = (float)pks[n];
  2702. env[m+1] = 0.0f; // Dummy zero vals for peaks: vals not needed at this stage
  2703. }
  2704. return FINISHED;
  2705. }
  2706. /************************* COPY_PEAKTIMES *******************************/
  2707. int copy_peaktimes(dataptr dz)
  2708. {
  2709. int n;
  2710. double *pks = dz->parray[SHR_INPUT_PKS];
  2711. int *peaks = dz->lparray[SHR_PEAKS];
  2712. for(n=0;n < dz->itemcnt; n++)
  2713. peaks[n] = (int)round(pks[n] * (double)dz->infile->srate) * dz->infile->channels;
  2714. return FINISHED;
  2715. }
  2716. /************************* INSERT_TROF *******************************/
  2717. int insert_trof(int *trofcnt,int trofno,float *troftime,float peaktime,float lastpeaktime,int orig_env_size,dataptr dz)
  2718. {
  2719. int exit_status, chans = dz->infile->channels;
  2720. double srate = (double)dz->infile->srate;
  2721. int searchstt, searchend, searchlen, n, t, v;
  2722. int minpeakat;
  2723. float minpeak;
  2724. (*trofcnt)++;
  2725. if((*trofcnt) * 2 > orig_env_size) {
  2726. sprintf(errstr,"Too few troughs found in sound: use smaller envelope.\n");
  2727. return(DATA_ERROR);
  2728. }
  2729. for(n = *trofcnt; n>trofno;n--) { // Make space
  2730. t = n * 2;
  2731. v = t + 1;
  2732. dz->origenv[t] = dz->origenv[t-2];
  2733. dz->origenv[v] = dz->origenv[v-2];
  2734. }
  2735. t = trofno * 2; // point to space
  2736. v = t + 1;
  2737. searchstt = (int)round(lastpeaktime * srate) * chans;
  2738. searchend = (int)round(peaktime * srate) * chans;
  2739. searchlen = searchend - searchstt;
  2740. if((exit_status = find_local_minpeak(&minpeakat,&minpeak,searchstt,searchend,searchlen,lastpeaktime,peaktime,dz))< 0)
  2741. return exit_status;
  2742. dz->origenv[t] = (float)((minpeakat/chans)/srate);
  2743. dz->origenv[v] = minpeak;
  2744. *troftime = dz->origenv[t];
  2745. return FINISHED;
  2746. }
  2747. /************************* FIND_LOCAL_MINPEAK *******************************/
  2748. int find_local_minpeak(int *minpeakat,float *minpeak,int searchstt,int searchend,int searchlen, double lastpeaktime, double peaktime, dataptr dz)
  2749. {
  2750. int exit_status, mergelast, chans = dz->infile->channels;
  2751. double *local_peak = dz->parray[LOCAL_PK_VAL];
  2752. double srate = dz->infile->srate, timegap, midtime;
  2753. int *local_peak_at = dz->lparray[LOCAL_PK_AT];
  2754. int wincnt, local_peak_cnt, maxat, n, bufsampcnt, sampcnt, covered, remnant, wsiz, midsamp;
  2755. float maxsamp, *ibuf = dz->sampbuf[0];
  2756. wsiz = TINY_WSIZE * chans;
  2757. if(searchlen/wsiz < 3) { // If can't find a small enough window to search for min-peak
  2758. timegap = peaktime - lastpeaktime; // Insert trof at midtime between peaks
  2759. midtime = peaktime + timegap/2.0;
  2760. midsamp = (int)round(midtime * srate) * chans;
  2761. if(midsamp == searchstt || midsamp == searchend) {
  2762. sprintf(errstr,"No space to insert trough between peaks at %lf and %lf.\n",lastpeaktime,peaktime);
  2763. return(DATA_ERROR);
  2764. }
  2765. *minpeakat = midsamp;
  2766. *minpeak = 0.0f;
  2767. return FINISHED;
  2768. }
  2769. mergelast = 0;
  2770. wincnt = searchlen/wsiz; // Find number of small windows
  2771. covered = wincnt * wsiz;
  2772. remnant = searchlen - covered; // Find any short-window (remnant) at end
  2773. if(remnant < wsiz/2) // If remnant is less than half-windowsize
  2774. mergelast = 1; // treat it as part of previous window
  2775. if((sndseekEx(dz->ifd[0],searchstt,0)) < 0) {
  2776. sprintf(errstr,"sndseek() 8 failed.\n");
  2777. return(SYSTEM_ERROR);
  2778. }
  2779. sampcnt = 0;
  2780. local_peak_cnt = 0;
  2781. wincnt = 0;
  2782. maxsamp = 0.0f;
  2783. maxat = searchstt;
  2784. dz->total_samps_read = 0;
  2785. dz->ssampsread = 0;
  2786. while(dz->total_samps_read < searchlen) { // Search for local peaks
  2787. if((exit_status = read_samps(ibuf,dz))<0)
  2788. return(exit_status);
  2789. if(dz->ssampsread == 0)
  2790. break;
  2791. bufsampcnt = 0;
  2792. while(sampcnt < searchlen) {
  2793. if(fabs(ibuf[bufsampcnt]) > maxsamp) {
  2794. maxsamp = (float)fabs(ibuf[bufsampcnt]);
  2795. maxat = sampcnt + searchstt;
  2796. }
  2797. if(++wincnt >= wsiz) {
  2798. local_peak[local_peak_cnt] = maxsamp;
  2799. local_peak_at[local_peak_cnt] = maxat;
  2800. local_peak_cnt++;
  2801. wincnt = 0;
  2802. maxsamp = (float)fabs(ibuf[bufsampcnt]);
  2803. }
  2804. sampcnt++;
  2805. if(++bufsampcnt >= dz->ssampsread)
  2806. break;
  2807. }
  2808. }
  2809. if(local_peak_cnt == 0) {
  2810. sprintf(errstr,"Failed to find trof between peaks at %lf and %lf\n",lastpeaktime,peaktime);
  2811. return PROGRAM_ERROR;
  2812. }
  2813. if(mergelast && local_peak_cnt >= 2) { // If short last window, merge it with previous window
  2814. if(local_peak[local_peak_cnt-1] > local_peak[local_peak_cnt-2]) {
  2815. local_peak[local_peak_cnt-2] = local_peak[local_peak_cnt-1];
  2816. local_peak_at[local_peak_cnt-2] = local_peak_at[local_peak_cnt-1];
  2817. }
  2818. local_peak_cnt--;
  2819. }
  2820. *minpeak = (float)local_peak[0]; // Find minimum local peak (= trof)
  2821. *minpeakat = local_peak_at[0];
  2822. for(n=1;n < local_peak_cnt; n++) {
  2823. if(local_peak[n] < *minpeak) {
  2824. *minpeak = (float)local_peak[n];
  2825. *minpeakat = local_peak_at[n];
  2826. }
  2827. }
  2828. return FINISHED;
  2829. }