tweet.c 120 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132
  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 <science.h>
  37. #include <ctype.h>
  38. #include <sfsys.h>
  39. #include <string.h>
  40. #include <srates.h>
  41. #define TWEET_PDATA 0
  42. #define TWEET_MIN 1
  43. #define WINDIV (6.0)
  44. #define FOFCOSWINDOW (.002)
  45. #define MINSPEECHGLITCH (0.15) // Assume minimum time for speaking voice to leap > 8va and back is > 150 mS
  46. #define PITCHERROR (1.5)
  47. #define ALMOST_OCT (1.9)
  48. #ifdef unix
  49. #define round(x) lround((x))
  50. #endif
  51. #ifndef HUGE
  52. #define HUGE 3.40282347e+38F
  53. #endif
  54. char errstr[2400];
  55. int anal_infiles = 1;
  56. int sloom = 0;
  57. int sloombatch = 0;
  58. const char* cdp_version = "6.1.0";
  59. //CDP LIB REPLACEMENTS
  60. static int setup_tweet_application(dataptr dz);
  61. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  62. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  63. static int setup_tweet_param_ranges_and_defaults(dataptr dz);
  64. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  65. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  66. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  67. static int establish_application(dataptr dz);
  68. static int initialise_vflags(dataptr dz);
  69. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  70. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  71. static int mark_parameter_types(dataptr dz,aplptr ap);
  72. static int assign_file_data_storage(int infilecnt,dataptr dz);
  73. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  74. static int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz);
  75. static int get_the_mode_from_cmdline(char *str,dataptr dz);
  76. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  77. static int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz);
  78. static int get_exclude_data(char *filename,dataptr dz);
  79. static int extract_formant_shape(double *env,int segdur,int maxoutdur,dataptr dz);
  80. static int recreate_tweet_sndbufs(dataptr dz);
  81. static int create_tweet_sndbufs(dataptr dz);
  82. static int silence_lolevel_fofs(int *outsegs,int *silence,int outcnt,dataptr dz);
  83. static int smooth_cuts(int *cut,int *cutcnt,int cutstart,dataptr dz);
  84. static int find_min_energy_downward_zero_crossing_point
  85. (int *n,int *trofpnt,int trofpntcnt,double *scanarray,int *cutcnt,int *cut,int cutstart,dataptr dz);
  86. static int find_the_local_peaks(int *here,int *there,float *buf,int *n,int trofpntcnt,int *trofpnt,
  87. int *startsamp,int *endsamp,int losamp, int *cut, int cutcnt, double *localpeak, double *scanarray,
  88. int *localpeakcnt,int *first_downcross,dataptr dz);
  89. static int mark_cut(int *cutcnt,int *cut,int localpeakcnt,double *startarray,int here,int there,
  90. int startsamp,int first_downcross,double starttime,int msg,dataptr dz);
  91. static int get_envelope_troughs(int *trofpnt,int *trofpntcnt,int envcnt,dataptr dz);
  92. static int get_min_wsize(int *minwsize, dataptr dz);
  93. static int extract_pitch_dependent_env_from_sndfile(int minwsize,int *maxwsize,dataptr dz);
  94. static int check_tweet_param_validity_and_consistency(dataptr dz);
  95. static int tweet_param_preprocess(dataptr dz);
  96. static float getmaxsampr(int startsamp, int sampcnt,float *buffer);
  97. static void smooth_oct_glitches(dataptr dz);
  98. static int read_validpitch_wsize_in_samps_from_brktable(double thistime,int kk,dataptr dz);
  99. static int count_zerocrossings(int here,int there,float *buf);
  100. static int triangulate_env(int *here,int *there,int ideal_place,float *buf);
  101. static int next_zero_cross(int here,dataptr dz);
  102. static int previous_zero_cross(int here,int firstzero,dataptr dz);
  103. static double autocorrelate(int n,int m,float *buf);
  104. static int auto_correlate(int start,int *at,int end,int realend,int minlen,double pitchseg,int kk,dataptr dz);
  105. static int next_down_zcross(int here,int hibound,float *buf);
  106. static int last_down_zcross(int here,int lobound,float *buf);
  107. static int silence_zero_signal_areas(int *outsegs,int *silence,int outcnt,dataptr dz);
  108. static int impulse(int seglen,double time,dataptr dz);
  109. static int tweet(dataptr dz);
  110. /**************************************** MAIN *********************************************/
  111. int main(int argc,char *argv[])
  112. {
  113. int exit_status;
  114. dataptr dz = NULL;
  115. char **cmdline;
  116. int cmdlinecnt;
  117. int n;
  118. // aplptr ap;
  119. int is_launched = FALSE;
  120. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  121. fprintf(stdout,"%s\n",cdp_version);
  122. fflush(stdout);
  123. return 0;
  124. }
  125. /* CHECK FOR SOUNDLOOM */
  126. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  127. sloom = 0;
  128. sloombatch = 1;
  129. }
  130. if(sflinit("cdp")){
  131. sfperror("cdp: initialisation\n");
  132. return(FAILED);
  133. }
  134. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  135. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  136. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  137. return(FAILED);
  138. }
  139. if(!sloom) {
  140. if(argc == 1) {
  141. usage1();
  142. return(FAILED);
  143. } else if(argc == 2) {
  144. usage2(argv[1]);
  145. return(FAILED);
  146. }
  147. }
  148. if(!sloom) {
  149. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) { // CDP LIB
  150. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  151. return(FAILED);
  152. }
  153. cmdline = argv;
  154. cmdlinecnt = argc;
  155. if((get_the_process_no(argv[0],dz))<0)
  156. return(FAILED);
  157. cmdline++;
  158. cmdlinecnt--;
  159. dz->maxmode = 3;
  160. if((exit_status = get_the_mode_from_cmdline(cmdline[0],dz))<0) {
  161. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  162. return(exit_status);
  163. }
  164. cmdline++;
  165. cmdlinecnt--;
  166. // setup_particular_application =
  167. if((exit_status = setup_tweet_application(dz))<0) {
  168. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  169. return(FAILED);
  170. }
  171. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) { // CDP LIB
  172. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  173. return(FAILED);
  174. }
  175. } else {
  176. //parse_TK_data() =
  177. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {
  178. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  179. return(exit_status);
  180. }
  181. }
  182. // ap = dz->application;
  183. // parse_infile_and_hone_type() =
  184. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  185. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  186. return(FAILED);
  187. }
  188. // setup_param_ranges_and_defaults() =
  189. if((exit_status = setup_tweet_param_ranges_and_defaults(dz))<0) {
  190. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  191. return(FAILED);
  192. }
  193. // open_first_infile CDP LIB
  194. if((exit_status = open_first_infile(cmdline[0],dz))<0) {
  195. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  196. return(FAILED);
  197. }
  198. cmdlinecnt--;
  199. cmdline++;
  200. // handle_extra_infiles() : redundant
  201. // handle_outfile() =
  202. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  203. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  204. return(FAILED);
  205. }
  206. // handle_formants() redundant
  207. // handle_formant_quiksearch() redundant
  208. // handle_special_data ..........
  209. if((exit_status = handle_the_special_data(&cmdlinecnt,&cmdline,dz))<0) {
  210. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  211. return(FAILED);
  212. }
  213. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  214. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  215. return(FAILED);
  216. }
  217. // check_param_validity_and_consistency....
  218. if((exit_status = check_tweet_param_validity_and_consistency(dz))<0) {
  219. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  220. return(FAILED);
  221. }
  222. //param_preprocess ......
  223. if((exit_status = tweet_param_preprocess(dz))<0) {
  224. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  225. return(FAILED);
  226. }
  227. is_launched = TRUE;
  228. dz->bufcnt = 3;
  229. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  230. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  231. return(MEMORY_ERROR);
  232. }
  233. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  234. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  235. return(MEMORY_ERROR);
  236. }
  237. for(n = 0;n <dz->bufcnt; n++)
  238. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  239. dz->sampbuf[n] = (float *)0;
  240. if((exit_status = create_tweet_sndbufs(dz))<0) {
  241. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  242. return(FAILED);
  243. }
  244. //spec_process_file =
  245. if((exit_status = tweet(dz))<0) {
  246. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  247. return(FAILED);
  248. }
  249. if((exit_status = complete_output(dz))<0) { // CDP LIB
  250. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  251. return(FAILED);
  252. }
  253. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  254. free(dz);
  255. return(SUCCEEDED);
  256. }
  257. /**********************************************
  258. REPLACED CDP LIB FUNCTIONS
  259. **********************************************/
  260. /****************************** SET_PARAM_DATA *********************************/
  261. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  262. {
  263. ap->special_data = (char)special_data;
  264. ap->param_cnt = (char)paramcnt;
  265. ap->max_param_cnt = (char)maxparamcnt;
  266. if(ap->max_param_cnt>0) {
  267. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  268. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  269. return(MEMORY_ERROR);
  270. }
  271. strcpy(ap->param_list,paramlist);
  272. }
  273. return(FINISHED);
  274. }
  275. /****************************** SET_VFLGS *********************************/
  276. int set_vflgs
  277. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  278. {
  279. ap->option_cnt = (char) optcnt; /*RWD added cast */
  280. if(optcnt) {
  281. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  282. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  283. return(MEMORY_ERROR);
  284. }
  285. strcpy(ap->option_list,optlist);
  286. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  287. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  288. return(MEMORY_ERROR);
  289. }
  290. strcpy(ap->option_flags,optflags);
  291. }
  292. ap->vflag_cnt = (char) vflagcnt;
  293. ap->variant_param_cnt = (char) vparamcnt;
  294. if(vflagcnt) {
  295. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  296. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  297. return(MEMORY_ERROR);
  298. }
  299. strcpy(ap->variant_list,varlist);
  300. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  301. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  302. return(MEMORY_ERROR);
  303. }
  304. strcpy(ap->variant_flags,varflags);
  305. }
  306. return(FINISHED);
  307. }
  308. /***************************** APPLICATION_INIT **************************/
  309. int application_init(dataptr dz)
  310. {
  311. int exit_status;
  312. int storage_cnt;
  313. int tipc, brkcnt;
  314. aplptr ap = dz->application;
  315. if(ap->vflag_cnt>0)
  316. initialise_vflags(dz);
  317. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  318. ap->total_input_param_cnt = (char)tipc;
  319. if(tipc>0) {
  320. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  321. return(exit_status);
  322. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  323. return(exit_status);
  324. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  325. return(exit_status);
  326. }
  327. brkcnt = tipc;
  328. //THERE ARE NO INPUTFILE brktables USED IN THIS PROCESS
  329. if(brkcnt>0) {
  330. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  331. return(exit_status);
  332. }
  333. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  334. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  335. return(exit_status);
  336. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  337. return(exit_status);
  338. }
  339. if((exit_status = mark_parameter_types(dz,ap))<0)
  340. return(exit_status);
  341. // establish_infile_constants() replaced by
  342. dz->infilecnt = 1;
  343. //establish_bufptrs_and_extra_buffers():
  344. return(FINISHED);
  345. }
  346. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  347. /* RWD mallo changed to calloc; helps debug verison run as release! */
  348. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  349. {
  350. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  351. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  352. return(MEMORY_ERROR);
  353. }
  354. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  355. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  356. return(MEMORY_ERROR);
  357. }
  358. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  359. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  360. return(MEMORY_ERROR);
  361. }
  362. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  363. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  364. return(MEMORY_ERROR);
  365. }
  366. return(FINISHED);
  367. }
  368. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  369. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  370. {
  371. int n;
  372. for(n=0;n<storage_cnt;n++) {
  373. dz->is_int[n] = (char)0;
  374. dz->no_brk[n] = (char)0;
  375. }
  376. return(FINISHED);
  377. }
  378. /***************************** MARK_PARAMETER_TYPES **************************/
  379. int mark_parameter_types(dataptr dz,aplptr ap)
  380. {
  381. int n, m; /* PARAMS */
  382. for(n=0;n<ap->max_param_cnt;n++) {
  383. switch(ap->param_list[n]) {
  384. case('0'): break; /* dz->is_active[n] = 0 is default */
  385. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  386. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  387. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  388. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  389. default:
  390. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  391. return(PROGRAM_ERROR);
  392. }
  393. } /* OPTIONS */
  394. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  395. switch(ap->option_list[n]) {
  396. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  397. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  398. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  399. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  400. default:
  401. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  402. return(PROGRAM_ERROR);
  403. }
  404. } /* VARIANTS */
  405. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  406. switch(ap->variant_list[n]) {
  407. case('0'): break;
  408. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  409. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  410. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  411. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  412. default:
  413. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  414. return(PROGRAM_ERROR);
  415. }
  416. } /* INTERNAL */
  417. for(n=0,
  418. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  419. switch(ap->internal_param_list[n]) {
  420. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  421. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  422. case('d'): dz->no_brk[m] = (char)1; break;
  423. default:
  424. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  425. return(PROGRAM_ERROR);
  426. }
  427. }
  428. return(FINISHED);
  429. }
  430. /************************ HANDLE_THE_OUTFILE *********************/
  431. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  432. {
  433. int exit_status;
  434. char *filename = (*cmdline)[0];
  435. if(filename[0]=='-' && filename[1]=='f') {
  436. dz->floatsam_output = 1;
  437. dz->true_outfile_stype = SAMP_FLOAT;
  438. filename+= 2;
  439. }
  440. if(!sloom) {
  441. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  442. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  443. return(DATA_ERROR);
  444. }
  445. }
  446. strcpy(dz->outfilename,filename);
  447. if((exit_status = create_sized_outfile(filename,dz))<0)
  448. return(exit_status);
  449. (*cmdline)++;
  450. (*cmdlinecnt)--;
  451. return(FINISHED);
  452. }
  453. /***************************** ESTABLISH_APPLICATION **************************/
  454. int establish_application(dataptr dz)
  455. {
  456. aplptr ap;
  457. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  458. sprintf(errstr,"establish_application()\n");
  459. return(MEMORY_ERROR);
  460. }
  461. ap = dz->application;
  462. memset((char *)ap,0,sizeof(struct applic));
  463. return(FINISHED);
  464. }
  465. /************************* INITIALISE_VFLAGS *************************/
  466. int initialise_vflags(dataptr dz)
  467. {
  468. int n;
  469. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  470. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  471. return(MEMORY_ERROR);
  472. }
  473. for(n=0;n<dz->application->vflag_cnt;n++)
  474. dz->vflag[n] = FALSE;
  475. return FINISHED;
  476. }
  477. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  478. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  479. {
  480. int n;
  481. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  482. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  483. return(MEMORY_ERROR);
  484. }
  485. for(n=0;n<tipc;n++)
  486. ap->default_val[n] = 0.0;
  487. return(FINISHED);
  488. }
  489. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  490. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  491. {
  492. int n;
  493. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  494. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  495. return(MEMORY_ERROR);
  496. }
  497. for(n=0;n<tipc;n++)
  498. dz->is_active[n] = (char)0;
  499. return(FINISHED);
  500. }
  501. /************************* SETUP_TWEET_APPLICATION *******************/
  502. int setup_tweet_application(dataptr dz)
  503. {
  504. int exit_status;
  505. aplptr ap;
  506. if((exit_status = establish_application(dz))<0) // GLOBAL
  507. return(FAILED);
  508. ap = dz->application;
  509. // SEE parstruct FOR EXPLANATION of next 2 functions
  510. if(dz->mode == 2)
  511. exit_status = set_param_data(ap,0 ,4,2,"Dd00");
  512. else
  513. exit_status = set_param_data(ap,0 ,4,4,"DdID");
  514. if(exit_status<0)
  515. return(FAILED);
  516. if((exit_status = set_vflgs(ap,"",0,"","w",1,0,"0"))<0)
  517. return(FAILED);
  518. // set_legal_infile_structure -->
  519. dz->has_otherfile = FALSE;
  520. // assign_process_logic -->
  521. dz->input_data_type = SNDFILES_ONLY;
  522. dz->process_type = UNEQUAL_SNDFILE;
  523. dz->outfiletype = SNDFILE_OUT;
  524. return application_init(dz); //GLOBAL
  525. }
  526. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  527. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  528. {
  529. int exit_status;
  530. infileptr infile_info;
  531. if(!sloom) {
  532. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  533. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  534. return(MEMORY_ERROR);
  535. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  536. sprintf(errstr,"Failed to parse input file %s\n",cmdline[0]);
  537. return(PROGRAM_ERROR);
  538. } else if(infile_info->filetype != SNDFILE) {
  539. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  540. return(DATA_ERROR);
  541. } else if(infile_info->channels != 1) {
  542. sprintf(errstr,"File %s is not of correct type (must be mono)\n",cmdline[0]);
  543. return(DATA_ERROR);
  544. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  545. sprintf(errstr,"Failed to copy file parsing information\n");
  546. return(PROGRAM_ERROR);
  547. }
  548. free(infile_info);
  549. }
  550. return(FINISHED);
  551. }
  552. /************************* SETUP_TWEET_PARAM_RANGES_AND_DEFAULTS *******************/
  553. int setup_tweet_param_ranges_and_defaults(dataptr dz)
  554. {
  555. int exit_status;
  556. aplptr ap = dz->application;
  557. // set_param_ranges()
  558. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  559. // NB total_input_param_cnt is > 0 !!!
  560. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  561. return(FAILED);
  562. // get_param_ranges()
  563. ap->lo[TWT_PDAT] = -2.0; // Pitch data
  564. ap->hi[TWT_PDAT] = dz->nyquist;
  565. ap->default_val[TWT_PDAT] = 440.0;
  566. ap->lo[TWT_MIN] = -60.0;
  567. ap->hi[TWT_MIN] = 0.0;
  568. ap->default_val[TWT_MIN] = 0.0;
  569. if(dz->mode != 2) {
  570. ap->lo[TWT_PKCNT] = 1;
  571. if(dz->mode == 1)
  572. ap->hi[TWT_PKCNT] = 4000;
  573. else
  574. ap->hi[TWT_PKCNT] = 200;
  575. ap->default_val[TWT_PKCNT] = 4;
  576. ap->lo[TWT_CHIRP] = 0;
  577. ap->hi[TWT_CHIRP] = 30;
  578. ap->default_val[TWT_CHIRP] = 0;
  579. }
  580. dz->maxmode = 3;
  581. if(!sloom)
  582. put_default_vals_in_all_params(dz);
  583. return(FINISHED);
  584. }
  585. /********************************* PARSE_SLOOM_DATA *********************************/
  586. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  587. {
  588. int exit_status;
  589. int cnt = 1, infilecnt;
  590. int filesize, insams, inbrksize;
  591. double dummy;
  592. int true_cnt = 0;
  593. // aplptr ap;
  594. while(cnt<=PRE_CMDLINE_DATACNT) {
  595. if(cnt > argc) {
  596. sprintf(errstr,"Insufficient data sent from TK\n");
  597. return(DATA_ERROR);
  598. }
  599. switch(cnt) {
  600. case(1):
  601. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  602. sprintf(errstr,"Cannot read process no. sent from TK\n");
  603. return(DATA_ERROR);
  604. }
  605. break;
  606. case(2):
  607. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  608. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  609. return(DATA_ERROR);
  610. }
  611. if(dz->mode > 0)
  612. dz->mode--;
  613. //setup_particular_application()=
  614. if((exit_status = setup_tweet_application(dz))<0)
  615. return(exit_status);
  616. // ap = dz->application;
  617. break;
  618. case(3):
  619. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  620. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  621. return(DATA_ERROR);
  622. }
  623. if(infilecnt < 1) {
  624. true_cnt = cnt + 1;
  625. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  626. }
  627. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  628. return(exit_status);
  629. break;
  630. case(INPUT_FILETYPE+4):
  631. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  632. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  633. return(DATA_ERROR);
  634. }
  635. break;
  636. case(INPUT_FILESIZE+4):
  637. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  638. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  639. return(DATA_ERROR);
  640. }
  641. dz->insams[0] = filesize;
  642. break;
  643. case(INPUT_INSAMS+4):
  644. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  645. sprintf(errstr,"Cannot read insams sent from TK\n");
  646. return(DATA_ERROR);
  647. }
  648. dz->insams[0] = insams;
  649. break;
  650. case(INPUT_SRATE+4):
  651. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  652. sprintf(errstr,"Cannot read srate sent from TK\n");
  653. return(DATA_ERROR);
  654. }
  655. break;
  656. case(INPUT_CHANNELS+4):
  657. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  658. sprintf(errstr,"Cannot read channels sent from TK\n");
  659. return(DATA_ERROR);
  660. }
  661. break;
  662. case(INPUT_STYPE+4):
  663. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  664. sprintf(errstr,"Cannot read stype sent from TK\n");
  665. return(DATA_ERROR);
  666. }
  667. break;
  668. case(INPUT_ORIGSTYPE+4):
  669. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  670. sprintf(errstr,"Cannot read origstype sent from TK\n");
  671. return(DATA_ERROR);
  672. }
  673. break;
  674. case(INPUT_ORIGRATE+4):
  675. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  676. sprintf(errstr,"Cannot read origrate sent from TK\n");
  677. return(DATA_ERROR);
  678. }
  679. break;
  680. case(INPUT_MLEN+4):
  681. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  682. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  683. return(DATA_ERROR);
  684. }
  685. break;
  686. case(INPUT_DFAC+4):
  687. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  688. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  689. return(DATA_ERROR);
  690. }
  691. break;
  692. case(INPUT_ORIGCHANS+4):
  693. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  694. sprintf(errstr,"Cannot read origchans sent from TK\n");
  695. return(DATA_ERROR);
  696. }
  697. break;
  698. case(INPUT_SPECENVCNT+4):
  699. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  700. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  701. return(DATA_ERROR);
  702. }
  703. dz->specenvcnt = dz->infile->specenvcnt;
  704. break;
  705. case(INPUT_WANTED+4):
  706. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  707. sprintf(errstr,"Cannot read wanted sent from TK\n");
  708. return(DATA_ERROR);
  709. }
  710. break;
  711. case(INPUT_WLENGTH+4):
  712. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  713. sprintf(errstr,"Cannot read wlength sent from TK\n");
  714. return(DATA_ERROR);
  715. }
  716. break;
  717. case(INPUT_OUT_CHANS+4):
  718. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  719. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  720. return(DATA_ERROR);
  721. }
  722. break;
  723. /* RWD these chanegs to samps - tk will have to deal with that! */
  724. case(INPUT_DESCRIPTOR_BYTES+4):
  725. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  726. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  727. return(DATA_ERROR);
  728. }
  729. break;
  730. case(INPUT_IS_TRANSPOS+4):
  731. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  732. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  733. return(DATA_ERROR);
  734. }
  735. break;
  736. case(INPUT_COULD_BE_TRANSPOS+4):
  737. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  738. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  739. return(DATA_ERROR);
  740. }
  741. break;
  742. case(INPUT_COULD_BE_PITCH+4):
  743. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  744. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  745. return(DATA_ERROR);
  746. }
  747. break;
  748. case(INPUT_DIFFERENT_SRATES+4):
  749. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  750. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  751. return(DATA_ERROR);
  752. }
  753. break;
  754. case(INPUT_DUPLICATE_SNDS+4):
  755. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  756. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  757. return(DATA_ERROR);
  758. }
  759. break;
  760. case(INPUT_BRKSIZE+4):
  761. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  762. sprintf(errstr,"Cannot read brksize sent from TK\n");
  763. return(DATA_ERROR);
  764. }
  765. if(inbrksize > 0) {
  766. switch(dz->input_data_type) {
  767. case(WORDLIST_ONLY):
  768. break;
  769. case(PITCH_AND_PITCH):
  770. case(PITCH_AND_TRANSPOS):
  771. case(TRANSPOS_AND_TRANSPOS):
  772. dz->tempsize = inbrksize;
  773. break;
  774. case(BRKFILES_ONLY):
  775. case(UNRANGED_BRKFILE_ONLY):
  776. case(DB_BRKFILES_ONLY):
  777. case(ALL_FILES):
  778. case(ANY_NUMBER_OF_ANY_FILES):
  779. if(dz->extrabrkno < 0) {
  780. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  781. return(DATA_ERROR);
  782. }
  783. if(dz->brksize == NULL) {
  784. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  785. return(PROGRAM_ERROR);
  786. }
  787. dz->brksize[dz->extrabrkno] = inbrksize;
  788. break;
  789. default:
  790. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  791. dz->input_data_type);
  792. return(PROGRAM_ERROR);
  793. }
  794. break;
  795. }
  796. break;
  797. case(INPUT_NUMSIZE+4):
  798. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  799. sprintf(errstr,"Cannot read numsize sent from TK\n");
  800. return(DATA_ERROR);
  801. }
  802. break;
  803. case(INPUT_LINECNT+4):
  804. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  805. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  806. return(DATA_ERROR);
  807. }
  808. break;
  809. case(INPUT_ALL_WORDS+4):
  810. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  811. sprintf(errstr,"Cannot read all_words sent from TK\n");
  812. return(DATA_ERROR);
  813. }
  814. break;
  815. case(INPUT_ARATE+4):
  816. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  817. sprintf(errstr,"Cannot read arate sent from TK\n");
  818. return(DATA_ERROR);
  819. }
  820. break;
  821. case(INPUT_FRAMETIME+4):
  822. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  823. sprintf(errstr,"Cannot read frametime sent from TK\n");
  824. return(DATA_ERROR);
  825. }
  826. dz->frametime = (float)dummy;
  827. break;
  828. case(INPUT_WINDOW_SIZE+4):
  829. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  830. sprintf(errstr,"Cannot read window_size sent from TK\n");
  831. return(DATA_ERROR);
  832. }
  833. break;
  834. case(INPUT_NYQUIST+4):
  835. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  836. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  837. return(DATA_ERROR);
  838. }
  839. break;
  840. case(INPUT_DURATION+4):
  841. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  842. sprintf(errstr,"Cannot read duration sent from TK\n");
  843. return(DATA_ERROR);
  844. }
  845. break;
  846. case(INPUT_MINBRK+4):
  847. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  848. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  849. return(DATA_ERROR);
  850. }
  851. break;
  852. case(INPUT_MAXBRK+4):
  853. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  854. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  855. return(DATA_ERROR);
  856. }
  857. break;
  858. case(INPUT_MINNUM+4):
  859. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  860. sprintf(errstr,"Cannot read minnum sent from TK\n");
  861. return(DATA_ERROR);
  862. }
  863. break;
  864. case(INPUT_MAXNUM+4):
  865. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  866. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  867. return(DATA_ERROR);
  868. }
  869. break;
  870. default:
  871. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  872. return(PROGRAM_ERROR);
  873. }
  874. cnt++;
  875. }
  876. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  877. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  878. return(DATA_ERROR);
  879. }
  880. if(true_cnt)
  881. cnt = true_cnt;
  882. *cmdlinecnt = 0;
  883. while(cnt < argc) {
  884. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  885. return(exit_status);
  886. cnt++;
  887. }
  888. return(FINISHED);
  889. }
  890. /********************************* GET_TK_CMDLINE_WORD *********************************/
  891. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  892. {
  893. if(*cmdlinecnt==0) {
  894. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  895. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  896. return(MEMORY_ERROR);
  897. }
  898. } else {
  899. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  900. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  901. return(MEMORY_ERROR);
  902. }
  903. }
  904. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  905. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  906. return(MEMORY_ERROR);
  907. }
  908. strcpy((*cmdline)[*cmdlinecnt],q);
  909. (*cmdlinecnt)++;
  910. return(FINISHED);
  911. }
  912. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  913. int assign_file_data_storage(int infilecnt,dataptr dz)
  914. {
  915. int exit_status;
  916. int no_sndfile_system_files = FALSE;
  917. dz->infilecnt = infilecnt;
  918. if((exit_status = allocate_filespace(dz))<0)
  919. return(exit_status);
  920. if(no_sndfile_system_files)
  921. dz->infilecnt = 0;
  922. return(FINISHED);
  923. }
  924. /************************* redundant functions: to ensure libs compile OK *******************/
  925. int assign_process_logic(dataptr dz)
  926. {
  927. return(FINISHED);
  928. }
  929. void set_legal_infile_structure(dataptr dz)
  930. {}
  931. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  932. {
  933. return(FINISHED);
  934. }
  935. int setup_internal_arrays_and_array_pointers(dataptr dz)
  936. {
  937. return(FINISHED);
  938. }
  939. int establish_bufptrs_and_extra_buffers(dataptr dz)
  940. {
  941. return(FINISHED);
  942. }
  943. int read_special_data(char *str,dataptr dz)
  944. {
  945. return(FINISHED);
  946. }
  947. int inner_loop
  948. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  949. {
  950. return(FINISHED);
  951. }
  952. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  953. {
  954. return(FINISHED);
  955. }
  956. /******************************** USAGE1 ********************************/
  957. int usage1(void)
  958. {
  959. usage2("tweet");
  960. return(USAGE_ONLY);
  961. }
  962. /******************************** DBTOLEVEL ***********************/
  963. double dbtolevel(double val)
  964. {
  965. int isneg = 0;
  966. if(flteq(val,0.0))
  967. return(1.0);
  968. if(val < 0.0) {
  969. val = -val;
  970. isneg = 1;
  971. }
  972. val /= 20.0;
  973. val = pow(10.0,val);
  974. if(isneg)
  975. val = 1.0/val;
  976. return(val);
  977. }
  978. /********************************************************************************************/
  979. int get_the_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  980. {
  981. if(!strcmp(prog_identifier_from_cmdline,"tweet")) dz->process = TWEET;
  982. else {
  983. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  984. return(USAGE_ONLY);
  985. }
  986. return(FINISHED);
  987. }
  988. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  989. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  990. {
  991. int n;
  992. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  993. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  994. return(MEMORY_ERROR);
  995. }
  996. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  997. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  998. return(MEMORY_ERROR);
  999. }
  1000. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1001. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  1002. return(MEMORY_ERROR);
  1003. }
  1004. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1005. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  1006. return(MEMORY_ERROR);
  1007. }
  1008. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1009. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  1010. return(MEMORY_ERROR);
  1011. }
  1012. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  1013. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  1014. return(MEMORY_ERROR);
  1015. }
  1016. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  1017. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  1018. return(MEMORY_ERROR);
  1019. }
  1020. for(n=0;n<brkcnt;n++) {
  1021. dz->brk[n] = NULL;
  1022. dz->brkptr[n] = NULL;
  1023. dz->brkinit[n] = 0;
  1024. dz->brksize[n] = 0;
  1025. }
  1026. return(FINISHED);
  1027. }
  1028. /******************************** USAGE2 ********************************/
  1029. int usage2(char *str)
  1030. {
  1031. if(!strcmp(str,"tweet")) {
  1032. fprintf(stderr,
  1033. "USAGE:\n"
  1034. "tweet tweet 1 infile outfile exclude pitchdata minlevel pkcnt chirp [-w]\n"
  1035. "tweet tweet 2 infile outfile exclude pitchdata minlevel frq chirp [-w]\n"
  1036. "tweet tweet 3 infile outfile exclude pitchdata minlevel [-w]\n"
  1037. "\n"
  1038. "Replace FOFs in vocal sound by synthetic tweets or (mode 3) noise.\n"
  1039. "\n"
  1040. "PITCHDATA A breakpoint file with time and frq information.\n"
  1041. " (Use \"repitch getpitch 2\").\n"
  1042. " May contain zeros (indicating moments of no-signal)\n"
  1043. " but it must contain SOME significant frequency information.\n"
  1044. "EXCLUDE Areas in src from which FOFs will NOT be extracted.\n"
  1045. " If not wanted, enter \"0\". Otherwise pairs of times in textfile.\n"
  1046. "MINLEVEL A level in dBs below level of loudest FOF found,\n"
  1047. " FOFs below this level rejected. NB Zero = NO FOFS rejected.\n"
  1048. "PKCNT Number of peaks in impulse. (1-200) (frq changes with FOF size)\n"
  1049. "FRQ Freq of peaks in impulse. (1-200) (frq fixed).\n"
  1050. "CHIRP Glissing of impulse. (Range 0 to 30) (Care, output may clip).\n"
  1051. "\n"
  1052. "-w FOFs are windowed (cosine smooth of edges)\n");
  1053. } else
  1054. fprintf(stdout,"Unknown option '%s'\n",str);
  1055. return(USAGE_ONLY);
  1056. }
  1057. int usage3(char *str1,char *str2)
  1058. {
  1059. fprintf(stderr,"Insufficient parameters on command line.\n");
  1060. return(USAGE_ONLY);
  1061. }
  1062. /****************************** GET_MODE *********************************/
  1063. int get_the_mode_from_cmdline(char *str,dataptr dz)
  1064. {
  1065. char temp[200], *p;
  1066. if(sscanf(str,"%s",temp)!=1) {
  1067. sprintf(errstr,"Cannot read mode of program.\n");
  1068. return(USAGE_ONLY);
  1069. }
  1070. p = temp + strlen(temp) - 1;
  1071. while(p >= temp) {
  1072. if(!isdigit(*p)) {
  1073. fprintf(stderr,"Invalid mode of program entered.\n");
  1074. return(USAGE_ONLY);
  1075. }
  1076. p--;
  1077. }
  1078. if(sscanf(str,"%d",&dz->mode)!=1) {
  1079. fprintf(stderr,"Cannot read mode of program.\n");
  1080. return(USAGE_ONLY);
  1081. }
  1082. if(dz->mode <= 0 || dz->mode > dz->maxmode) {
  1083. fprintf(stderr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode);
  1084. return(USAGE_ONLY);
  1085. }
  1086. dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */
  1087. return(FINISHED);
  1088. }
  1089. /************************* TWEET *******************************/
  1090. int tweet(dataptr dz)
  1091. {
  1092. int exit_status;
  1093. /* double maxenv = 10000.0;*/
  1094. int n, m, k, j, cutcnt, ipos, trofpntcnt = 0;
  1095. int outcnt, fofcnt,exclustt, excluend, maxoutdur=0, inbufstart, inbufend, obufpos, splen;
  1096. int envcnt, minwsize, maxwsize = 0, bigarray, cutstart = 0, thiscut, lastcut=0;
  1097. int segdur, segstart, segend;
  1098. int *trofpnt, *cuttime, *outsegs, *excludes = NULL;
  1099. double *scanarray, *env, srate = (double)dz->infile->srate;
  1100. float *ibuf = dz->sampbuf[0], *obuf, *chpbuf;
  1101. int *silence = NULL, done, init;
  1102. int jj, kk;
  1103. int cosedgelen = (int)round(FOFCOSWINDOW * dz->infile->srate);
  1104. int min_fofsamps_for_windowing = (cosedgelen * 2) + 1;
  1105. double *cosedge, val, time, splic;
  1106. if((cosedge = (double *)malloc(cosedgelen * sizeof(double)))==NULL) {
  1107. sprintf(errstr,"Insufficient memory for FOF windowing.\n");
  1108. return(MEMORY_ERROR);
  1109. }
  1110. for(jj=0,kk=1;jj<cosedgelen;jj++,kk++) {
  1111. val = (double)kk/(double)cosedgelen;
  1112. val = (cos(val * PI) + 1.0)/2.0;
  1113. cosedge[jj] = 1.0 - val;
  1114. }
  1115. if(dz->itemcnt > 0) // Get exclude-data, if it is being used
  1116. excludes = dz->lparray[0];
  1117. if((exit_status = get_min_wsize(&minwsize,dz)) < 0)
  1118. return exit_status;
  1119. if(((envcnt = dz->insams[0]/minwsize) * minwsize)!=dz->insams[0])
  1120. envcnt++;
  1121. if((dz->env=(float *)malloc(((envcnt+20) * 2) * sizeof(float)))==NULL) {
  1122. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
  1123. return(MEMORY_ERROR);
  1124. }
  1125. bigarray = envcnt+20;
  1126. memset(dz->env,0,(envcnt+20) * 2 * sizeof(float)); /* PRESET env VALS TO ZERO */
  1127. /* PART ENVELOPE vals CAN THEN BE STORED, where env-extract overlaps a buffer boundary */
  1128. fprintf(stdout,"INFO: Extracting pitch-related envelope from file.\n");
  1129. fflush(stdout);
  1130. if((exit_status = extract_pitch_dependent_env_from_sndfile(minwsize,&maxwsize,dz))<0)
  1131. return(exit_status);
  1132. envcnt = dz->envend - dz->env;
  1133. fprintf(stdout,"INFO: Locating envelope peaks.\n");
  1134. fflush(stdout);
  1135. if((trofpnt = (int *)malloc(envcnt/2 * sizeof(int)))==NULL) {
  1136. sprintf(errstr,"INSUFFICIENT MEMORY TO ANALYSE ENVELOPE.\n");
  1137. return(MEMORY_ERROR);
  1138. }
  1139. if((cuttime = (int *)malloc(bigarray/2 * sizeof(int)))==NULL) {
  1140. sprintf(errstr,"INSUFFICIENT MEMORY TO ANALYSE ENVELOPE.\n");
  1141. return(MEMORY_ERROR);
  1142. }
  1143. if((outsegs = (int *)malloc(bigarray * sizeof(int)))==NULL) {
  1144. sprintf(errstr,"INSUFFICIENT MEMORY TO ANALYSE ENVELOPE.\n");
  1145. return(MEMORY_ERROR);
  1146. }
  1147. if((silence = (int *)malloc(bigarray/2 * sizeof(int)))==NULL) {
  1148. sprintf(errstr,"INSUFFICIENT MEMORY TO MARK SILENCES.\n");
  1149. return(MEMORY_ERROR);
  1150. }
  1151. if((exit_status = get_envelope_troughs(trofpnt,&trofpntcnt,envcnt,dz))<0)
  1152. return(exit_status);
  1153. if((scanarray = (double *)malloc((maxwsize + 20) * sizeof(double)))==NULL) {
  1154. sprintf(errstr,"Insufficient memory for array to scan for zero-crossings.\n");
  1155. return(MEMORY_ERROR);
  1156. }
  1157. if((sndseekEx(dz->ifd[0],0,0)<0)){
  1158. sprintf(errstr,"sndseek() failed\n");
  1159. return SYSTEM_ERROR;
  1160. }
  1161. dz->total_samps_read = 0;
  1162. if(sloom)
  1163. display_virtual_time(dz->total_samps_read,dz);
  1164. fprintf(stdout,"INFO: Calculating cut points.\n");
  1165. fflush(stdout);
  1166. if((exit_status = read_samps(ibuf,dz))<0)
  1167. return(exit_status);
  1168. k = 0;
  1169. cutcnt = 0;
  1170. if(dz->env[trofpnt[0]] <= 0.0) /* if first trof is at zero, skip that one */
  1171. k++;
  1172. for(n = k;n<trofpntcnt;n++) { /* find places to cut the source */
  1173. if((exit_status = find_min_energy_downward_zero_crossing_point(&n,trofpnt,trofpntcnt,scanarray,&cutcnt,cuttime,cutstart,dz)) < 0)
  1174. return(exit_status);
  1175. if(!dz->zeroset)
  1176. cutcnt++;
  1177. }
  1178. if((exit_status = smooth_cuts(cuttime,&cutcnt,cutstart,dz))<0)
  1179. return(exit_status);
  1180. n = 0;
  1181. m = 0;
  1182. thiscut = 0;
  1183. done = 0;
  1184. outcnt = 0;
  1185. init = 0;
  1186. if(dz->itemcnt > 0) { // REMOVE FOFS IN EXCLUDED AREAS
  1187. while(n < dz->itemcnt) {
  1188. exclustt = excludes[m];
  1189. excluend = excludes[m+1];
  1190. while(cuttime[thiscut] < exclustt) {
  1191. if(init) {
  1192. silence[outcnt/2] = 0;
  1193. outsegs[outcnt++] = cuttime[lastcut];
  1194. outsegs[outcnt++] = cuttime[thiscut];
  1195. }
  1196. lastcut = thiscut;
  1197. init = 1;
  1198. if(++thiscut >= cutcnt) {
  1199. done = 1;
  1200. break;
  1201. }
  1202. }
  1203. if(done)
  1204. break;
  1205. silence[outcnt/2] = 1;
  1206. outsegs[outcnt++] = cuttime[lastcut]; // Mark as silent
  1207. while(cuttime[thiscut] < excluend) {
  1208. thiscut++;
  1209. if(thiscut >= cutcnt) {
  1210. done = 1;
  1211. break;
  1212. }
  1213. }
  1214. if(done)
  1215. break;
  1216. outsegs[outcnt++] = cuttime[thiscut];
  1217. lastcut = thiscut;
  1218. if(++thiscut >= cutcnt)
  1219. break;
  1220. n++;
  1221. m += 2;
  1222. }
  1223. }
  1224. while(thiscut < cutcnt) {
  1225. if(init) {
  1226. silence[outcnt/2] = 0;
  1227. outsegs[outcnt++] = cuttime[lastcut];
  1228. outsegs[outcnt++] = cuttime[thiscut];
  1229. }
  1230. lastcut = thiscut;
  1231. init = 1;
  1232. thiscut++;
  1233. }
  1234. if((exit_status = silence_zero_signal_areas(outsegs,silence,outcnt,dz)) < 0)
  1235. return(exit_status);
  1236. if(dz->param[1] < 0.0) {
  1237. if((exit_status = silence_lolevel_fofs(outsegs,silence,outcnt,dz)) < 0)
  1238. return(exit_status);
  1239. }
  1240. fofcnt = outcnt/2;
  1241. n = 0;
  1242. maxoutdur = 0;
  1243. for(n=0,j=0,k=1;n<fofcnt;n++,j+=2,k+=2)
  1244. maxoutdur = max(outsegs[k] - outsegs[j],maxoutdur);
  1245. dz->buflen = max(maxoutdur + 64,dz->buflen); // Recalc buflen for for output phase
  1246. if((exit_status = recreate_tweet_sndbufs(dz))<0)
  1247. return exit_status;
  1248. ibuf = dz->sampbuf[0];
  1249. obuf = dz->sampbuf[1];
  1250. chpbuf = dz->sampbuf[2];
  1251. if((env = (double *)malloc(maxoutdur * sizeof(double))) == NULL) {
  1252. sprintf(errstr,"INSUFFICIENT MEMORY establishing level check array.\n");
  1253. return(MEMORY_ERROR);
  1254. }
  1255. if((sndseekEx(dz->ifd[0],0,0)<0)){
  1256. sprintf(errstr,"sndseek() failed\n");
  1257. return SYSTEM_ERROR;
  1258. }
  1259. dz->total_samps_read = 0;
  1260. if((exit_status = read_samps(ibuf,dz))<0)
  1261. return(exit_status);
  1262. inbufstart = 0;
  1263. inbufend = dz->ssampsread;
  1264. obufpos = 0;
  1265. n = 0;
  1266. j = 0;
  1267. k = 1;
  1268. time = 0.0;
  1269. memset((char*)obuf,0,dz->buflen * sizeof(float));
  1270. while(n<fofcnt) {
  1271. segstart = outsegs[j];
  1272. segend = outsegs[k];
  1273. segdur = segend - segstart;
  1274. if(silence[n]) { // Output silence
  1275. for(jj=0;jj < segdur;jj++) {
  1276. obuf[obufpos] = 0.0f;
  1277. if(++obufpos >= dz->buflen) {
  1278. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1279. return exit_status;
  1280. obufpos = 0;
  1281. }
  1282. }
  1283. } else { // Check we have all of segment in current inbuf
  1284. if(segstart < inbufstart || segend >= inbufend) { // and if not, get a new buffer
  1285. if((sndseekEx(dz->ifd[0],segstart,0)<0)){
  1286. sprintf(errstr,"sndseek() failed\n");
  1287. return SYSTEM_ERROR;
  1288. }
  1289. dz->total_samps_read = segstart;
  1290. if((exit_status = read_samps(ibuf,dz))<0)
  1291. return(exit_status);
  1292. inbufstart = segstart;
  1293. }
  1294. ipos = segstart - inbufstart;
  1295. segend = ipos + segdur;
  1296. if(segend > dz->buflen) {
  1297. sprintf(errstr,"FOF too long for buffer.\n");
  1298. return(PROGRAM_ERROR);
  1299. }
  1300. memcpy((char*)chpbuf,(char*)(ibuf + ipos),segdur * sizeof(float)); // Copy FOF to chpbuf
  1301. if(dz->vflag[FOF_UNWIN]) { // // If ness cosin-splice the FOF
  1302. if(segdur >= min_fofsamps_for_windowing)
  1303. splen = cosedgelen;
  1304. else
  1305. splen = segdur/2;
  1306. for(jj = 0,kk = segdur - 1;jj < segdur;jj++,kk--) {
  1307. val = chpbuf[jj];
  1308. if(jj < splen) {
  1309. splic = (double)(jj+1)/(double)splen;
  1310. splic = (cos(splic * PI) + 1.0)/2.0;
  1311. splic = 1.0 - splic;
  1312. val *= splic;
  1313. } else if(kk < splen) {
  1314. splic = (double)(kk+1)/(double)splen;
  1315. splic = (cos(splic * PI) + 1.0)/2.0;
  1316. splic = 1.0 - splic;
  1317. val *= splic;
  1318. }
  1319. chpbuf[jj] = (float)val;
  1320. }
  1321. }
  1322. if((exit_status = extract_formant_shape(env,segdur,maxoutdur,dz))<0) // Extract outer envelope of formant
  1323. return exit_status;
  1324. if((exit_status = impulse(segdur,time,dz))<0) // Generate chirp to fit
  1325. return exit_status;
  1326. for(kk=0;kk<segdur;kk++) // superimpose formant shape on chirp
  1327. chpbuf[kk] = (float)(chpbuf[kk] * env[kk]);
  1328. for(jj=0;jj < segdur;jj++) {
  1329. obuf[obufpos] = chpbuf[jj];
  1330. if(++obufpos >= dz->buflen) {
  1331. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  1332. return exit_status;
  1333. obufpos = 0;
  1334. }
  1335. }
  1336. }
  1337. n++;
  1338. j += 2;
  1339. k += 2;
  1340. time = (double)(dz->total_samps_written + obufpos)/srate;
  1341. }
  1342. if(obufpos > 0) {
  1343. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  1344. return(exit_status);
  1345. }
  1346. return FINISHED;
  1347. }
  1348. /************************* EXTRACT_PITCH_DEPENDENT_ENV_FROM_SNDFILE *******************************/
  1349. int extract_pitch_dependent_env_from_sndfile(int minwsize,int *maxwsize,dataptr dz)
  1350. {
  1351. int exit_status;
  1352. double tconvertor = 1.0/(double)dz->infile->srate;
  1353. double fconvertor = (double)dz->infile->srate/WINDIV;
  1354. int start_samp = 0, envwindow_sampsize, big_envwindow_sampsize, here = 0, start_buf = 0;
  1355. float *env = dz->env, *ibuf = dz->sampbuf[0], *ovflwbuf = dz->sampbuf[1];
  1356. double time = 0.0;
  1357. if((dz->ssampsread = fgetfbufEx(ibuf, dz->buflen * 2,dz->ifd[0],0)) < 0) {
  1358. sprintf(errstr,"Can't read samples from input soundfile\n"); // NB Uses a double length buf for reading envelope
  1359. return(SYSTEM_ERROR);
  1360. }
  1361. if((exit_status = read_value_from_brktable(time,TWT_PDAT,dz))<0)
  1362. return(exit_status);
  1363. if(dz->param[TWT_PDAT] < 0.0) /* no-pitch */
  1364. envwindow_sampsize = minwsize;
  1365. else
  1366. envwindow_sampsize = (int)round(fconvertor/dz->param[TWT_PDAT]);
  1367. while(here < dz->insams[0]) {
  1368. if(here - start_buf >= dz->buflen) {
  1369. memset((char *)ibuf,0,dz->buflen * sizeof(float));
  1370. memcpy((char *)ibuf,(char *)ovflwbuf,dz->buflen * sizeof(float));
  1371. start_buf += dz->buflen;
  1372. if(dz->total_samps_read < dz->insams[0]) {
  1373. if((dz->ssampsread = fgetfbufEx(ovflwbuf, dz->buflen,dz->ifd[0],0)) < 0) {
  1374. sprintf(errstr,"Can't read samples from input soundfile\n");
  1375. return(SYSTEM_ERROR);
  1376. }
  1377. }
  1378. }
  1379. big_envwindow_sampsize = envwindow_sampsize * 2;
  1380. *env++ = (float)time;
  1381. if(here + big_envwindow_sampsize >= dz->insams[0]) {
  1382. here -= envwindow_sampsize;
  1383. big_envwindow_sampsize = dz->insams[0] - here;
  1384. *env++ = getmaxsampr(start_samp,big_envwindow_sampsize,ibuf);
  1385. break;
  1386. }
  1387. start_samp = here - start_buf;
  1388. *env++ = getmaxsampr(start_samp,big_envwindow_sampsize,ibuf);
  1389. here += envwindow_sampsize;
  1390. time = (float)(here * tconvertor);
  1391. if((exit_status = read_value_from_brktable(time,TWT_PDAT,dz))<0)
  1392. return(exit_status);
  1393. if(dz->param[TWT_PDAT] < 0.0) /* no-pitch */
  1394. envwindow_sampsize = minwsize;
  1395. else
  1396. envwindow_sampsize = (int)round(fconvertor/dz->param[TWT_PDAT]);
  1397. if(envwindow_sampsize > *maxwsize)
  1398. *maxwsize = envwindow_sampsize;
  1399. }
  1400. *maxwsize *= 2; /* using overlapping windows */
  1401. dz->envend = env;
  1402. memset((char *)ibuf,0,dz->buflen * 2 * sizeof(float));
  1403. return FINISHED;
  1404. }
  1405. /************************** GET_MIN_WSIZE **************************/
  1406. int get_min_wsize(int *minwsize, dataptr dz) {
  1407. int n,m;
  1408. int wsize;
  1409. double fconvertor = (double)dz->infile->srate/WINDIV, frq;
  1410. *minwsize = dz->insams[0];
  1411. for(n=0,m=1;n<dz->brksize[TWEET_PDATA];n++,m+=2) {
  1412. frq = dz->brk[TWEET_PDATA][m];
  1413. if(frq > 0.0) {
  1414. wsize = (int)round(fconvertor/frq);
  1415. if(wsize < *minwsize)
  1416. *minwsize = wsize;
  1417. }
  1418. }
  1419. if(*minwsize >= dz->insams[0])
  1420. return(DATA_ERROR);
  1421. return FINISHED;
  1422. }
  1423. /******************************** GET_ENVELOPE_TROUGHS ********************************/
  1424. int get_envelope_troughs(int *trofpnt,int *trofpntcnt,int envcnt,dataptr dz)
  1425. {
  1426. int n;
  1427. int lasttrofpntcnt = 0, realtrofpntcnt = 0, reallasttrofpntcnt = 0;
  1428. float lastenval;
  1429. int zerotrof;
  1430. trofpnt[0] = 0;
  1431. n = 1; /* time-val pairs : vals are odd numbers */
  1432. lastenval = dz->env[n];
  1433. if(lastenval <= 0.0) {
  1434. trofpnt[0] = 0; /* mark start of zero trough */
  1435. while(dz->env[n] <= 0.0) {
  1436. n+= 2;
  1437. if(n >= envcnt) {
  1438. sprintf(errstr,"NO PEAKS FOUND IN ENVELOPE\n");
  1439. return(GOAL_FAILED);
  1440. }
  1441. }
  1442. n -= 2;
  1443. if(n > 1) { /* if zero trough persists, also mark its end */
  1444. trofpnt[1] = n-1; /* times are even numbers : n is odd */
  1445. lastenval = dz->env[n];
  1446. *trofpntcnt = 1;
  1447. lasttrofpntcnt = 1;
  1448. }
  1449. n += 2;
  1450. } else {
  1451. n += 2;
  1452. while(n < envcnt) { /* GET FIRST ENVELOPE TROUGH */
  1453. if(dz->env[n] > lastenval) {
  1454. trofpnt[0] = 0;
  1455. lastenval = dz->env[n];
  1456. n+=2;
  1457. break;
  1458. } else if (dz->env[n] < lastenval) {
  1459. trofpnt[0] = n-1; /* times are even numbers : n is odd */
  1460. lastenval = dz->env[n];
  1461. n+=2;
  1462. break;
  1463. }
  1464. lastenval = dz->env[n];
  1465. n+=2;
  1466. }
  1467. }
  1468. if(n >= envcnt) {
  1469. sprintf(errstr,"NO PEAKS FOUND IN ENVELOPE\n");
  1470. return(GOAL_FAILED);
  1471. }
  1472. zerotrof = 0;
  1473. while(n < envcnt) { /* GET ENVELOPE TROUGHS */
  1474. if(dz->env[n] > lastenval) {
  1475. if(zerotrof) { /* mark and count end of a zero section */
  1476. *trofpntcnt = lasttrofpntcnt + 1;
  1477. trofpnt[*trofpntcnt] = n-3; /* times are even numbers : n is odd; previous time is a zeroval */
  1478. lasttrofpntcnt = *trofpntcnt; /* count end-of-a-zero-section: but don't count as a real (new) trof */
  1479. zerotrof = 0;
  1480. }
  1481. *trofpntcnt = lasttrofpntcnt + 1;
  1482. realtrofpntcnt = reallasttrofpntcnt + 1;
  1483. } else if (dz->env[n] < lastenval) { /* can't be in a zero block, as zero is min val */
  1484. trofpnt[*trofpntcnt] = n-1; /* times are even numbers : n is odd */
  1485. lasttrofpntcnt = *trofpntcnt;
  1486. reallasttrofpntcnt = realtrofpntcnt;
  1487. } else if(dz->env[n] <= 0.0) { /* dz->env[n] == previous value SO zero value is continued */
  1488. zerotrof = 1;
  1489. }
  1490. lastenval = dz->env[n];
  1491. n+=2;
  1492. }
  1493. if(realtrofpntcnt < 2) {
  1494. sprintf(errstr,"NO SIGNIFICANT PEAKS FOUND IN ENVELOPE\n");
  1495. return(GOAL_FAILED);
  1496. }
  1497. return(FINISHED);
  1498. }
  1499. /************************** FIND_MIN_ENERGY_DOWNWARD_ZERO_CROSSING_POINT **************************/
  1500. int find_min_energy_downward_zero_crossing_point(int *n,int *trofpnt,int trofpntcnt,
  1501. double *scanarray,int *cutcnt,int *cut,int cutstart,dataptr dz)
  1502. {
  1503. int exit_status;
  1504. int check;
  1505. float starttime, val, *buf = dz->sampbuf[0];
  1506. int wsize, thissamp, hisamp, losamp, j, zc_cnt, at;
  1507. int endsamp, startsamp, seglen;
  1508. int newpos, diff, losampinbuf, hisampinbuf, here, there, localpeakcnt;
  1509. int k, first_downcross, mindiff, goalseglen, newseglen, thiscut;
  1510. double official_pitchlen;
  1511. int pitchseg_lolimit, pitchseg_hilimit;
  1512. int done;
  1513. int pitchwindow, ideal_place, last_startsamp, thiscutinbuf, lastcut, lastcutinbuf;
  1514. int seg1, seg2;
  1515. double rat;
  1516. endsamp = dz->total_samps_read;
  1517. startsamp = endsamp - dz->ssampsread;
  1518. j = trofpnt[*n];
  1519. starttime = dz->env[j];
  1520. wsize = read_validpitch_wsize_in_samps_from_brktable(starttime,0,dz);
  1521. thissamp = (int)round(starttime * (double)dz->infile->srate);
  1522. losamp = thissamp;
  1523. if((exit_status = read_value_from_brktable(starttime,0,dz))<0) /* get pitch at start of window */
  1524. return(exit_status);
  1525. if(losamp >= dz->insams[0])
  1526. return(FINISHED);
  1527. if(losamp >= endsamp || losamp < startsamp) {
  1528. newpos = (losamp/F_SECSIZE) * F_SECSIZE;
  1529. if((sndseekEx(dz->ifd[0],newpos,0)<0)){
  1530. sprintf(errstr,"sndseek() failed\n");
  1531. return SYSTEM_ERROR;
  1532. }
  1533. dz->total_samps_read = newpos;
  1534. if((exit_status = read_samps(buf,dz))<0)
  1535. return(exit_status);
  1536. endsamp = dz->total_samps_read;
  1537. startsamp = endsamp - dz->ssampsread;
  1538. }
  1539. hisamp = min(dz->insams[0],thissamp + wsize); /* get end-of-search area from wtime & half-wsize */
  1540. if(hisamp >= dz->insams[0])
  1541. hisamp = dz->insams[0];
  1542. if(hisamp > endsamp) {
  1543. newpos = (losamp/F_SECSIZE) * F_SECSIZE; /* if end-of--search beyond end of current buf */
  1544. /* adjust buffer to contain whole search area */
  1545. if((sndseekEx(dz->ifd[0],newpos,0)<0)){
  1546. sprintf(errstr,"sndseek() failed\n");
  1547. return SYSTEM_ERROR;
  1548. }
  1549. dz->total_samps_read = newpos;
  1550. if((exit_status = read_samps(buf,dz))<0)
  1551. return(exit_status);
  1552. endsamp = dz->total_samps_read;
  1553. startsamp = endsamp - dz->ssampsread;
  1554. }
  1555. losampinbuf = losamp - startsamp; /* get search ends relative to buffer */
  1556. hisampinbuf = hisamp - startsamp;
  1557. if(dz->param[0] > 0) {
  1558. pitchwindow = (int)round((double)dz->infile->srate/dz->param[0]);
  1559. ideal_place = cut[(*cutcnt) - 1] + pitchwindow;
  1560. ideal_place -= startsamp;
  1561. } else {
  1562. ideal_place = -1;
  1563. }
  1564. here = losampinbuf;
  1565. there = hisampinbuf;
  1566. zc_cnt = count_zerocrossings(losampinbuf,hisampinbuf,buf);
  1567. while(zc_cnt > 5) /* Divide segment into 4 quarters, making 3 overlapping areas, while any area has >= 5 zcrossings */
  1568. zc_cnt = triangulate_env(&here,&there,ideal_place,buf); /* and find area with least energy */
  1569. losamp = here + startsamp;
  1570. dz->zeroset = 0;
  1571. if((exit_status = find_the_local_peaks(&here,&there,buf,n,trofpntcnt,trofpnt,
  1572. &startsamp,&endsamp,losamp,cut,*cutcnt,scanarray,scanarray,&localpeakcnt,&first_downcross,dz) )<0)
  1573. return(exit_status);
  1574. if(exit_status == FINISHED)
  1575. dz->zeroset = 1;
  1576. if(dz->zeroset)
  1577. return(FINISHED);
  1578. if((exit_status = mark_cut(cutcnt,cut,localpeakcnt,scanarray,here,there,startsamp,first_downcross,starttime,1,dz))<0)
  1579. return(exit_status);
  1580. if((*cutcnt)-1 < cutstart) /* FIND LENGTH OF SEGMENT GENERATED */
  1581. seglen = cut[*cutcnt];
  1582. else
  1583. seglen = cut[*cutcnt] - cut[(*cutcnt)-1];
  1584. if(seglen == 0) { /* ELIMINATE ZERO-LENGTH SEGMENTS (CUTS AT SAME TIME) */
  1585. (*cutcnt)--;
  1586. } else if(*cutcnt > cutstart && dz->param[0] > 0) {
  1587. /* CHECK THE LENGTH OF THE WINDOW AGAINST WHAT WE'D PREDICT FROM THE PITCH VALUE */
  1588. check = 1;
  1589. while(check) {
  1590. official_pitchlen = (double)dz->infile->srate/dz->param[0];
  1591. pitchseg_lolimit = (int)round(official_pitchlen/PITCHERROR);
  1592. pitchseg_hilimit = (int)round(official_pitchlen * PITCHERROR);
  1593. /* IF SEGLEN IS ACCEPTABLE, BREAK */
  1594. if(seglen > pitchseg_lolimit && seglen < pitchseg_hilimit) {
  1595. break;
  1596. }
  1597. if(seglen < pitchseg_lolimit) { /* TOO SHORT ITEM, DELETE FROM CUTLIST */
  1598. (*cutcnt)--;
  1599. break;
  1600. }
  1601. /* TOO int ITEM */
  1602. /* BRUTE FORCE METHOD, CUT AT ANY DOWN ZEROCROSS NEAR THE RIGHT TIME */
  1603. /* TRY TO MAKE A CUT HALF-WAY THROUGH THE SEGMENT */
  1604. at = 0;
  1605. mindiff = seglen;
  1606. goalseglen = seglen/2; /* set the goal segement length to half the current seglen */
  1607. /* Geteach zero-crossing in this segment */
  1608. last_startsamp = -1;
  1609. thiscutinbuf = cut[*cutcnt] - startsamp;
  1610. lastcut = cut[(*cutcnt) - 1];
  1611. lastcutinbuf = lastcut - startsamp;
  1612. if(lastcutinbuf < 0) {
  1613. last_startsamp = startsamp;
  1614. if((sndseekEx(dz->ifd[0],lastcut,0)<0)){
  1615. sprintf(errstr,"sndseek() failed\n");
  1616. return SYSTEM_ERROR;
  1617. }
  1618. dz->total_samps_read = lastcut;
  1619. if((exit_status = read_samps(buf,dz))<0)
  1620. return(exit_status);
  1621. startsamp = dz->total_samps_read - dz->ssampsread;
  1622. thiscutinbuf -= lastcutinbuf; /* lastcutinbuf is -ve */
  1623. lastcutinbuf = 0;
  1624. }
  1625. done = 0;
  1626. k = lastcutinbuf;
  1627. val = buf[++k];
  1628. while(k < thiscutinbuf) {
  1629. if(val > 0.0) {
  1630. while(val >= 0.0) {
  1631. k++;
  1632. if(k >= thiscutinbuf) {
  1633. done = 1;
  1634. break;
  1635. }
  1636. val = buf[k];
  1637. }
  1638. }
  1639. if(done)
  1640. break;
  1641. if(val < 0.0) {
  1642. newseglen = k - lastcutinbuf;
  1643. diff = newseglen - goalseglen;
  1644. if(abs(diff) < mindiff) { /* if a segment cut from here is closer to the goallength, mark it */
  1645. mindiff = abs(diff);
  1646. at = k + startsamp;
  1647. } else if(diff > 0) { /* if not closer, and already above goal length, finished */
  1648. break;
  1649. }
  1650. while(val < 0.0) {
  1651. k++;
  1652. if(k >= thiscutinbuf) {
  1653. done = 1;
  1654. break;
  1655. }
  1656. val = buf[k];
  1657. }
  1658. }
  1659. if(done)
  1660. break;
  1661. if(val == 0.0) {
  1662. while(val == 0.0) {
  1663. k++;
  1664. if(k >= thiscutinbuf)
  1665. break;
  1666. val = buf[k];
  1667. }
  1668. }
  1669. }
  1670. if(last_startsamp >= 0) { /* rejiggle bufs */
  1671. if((sndseekEx(dz->ifd[0],startsamp,0)<0)){
  1672. sprintf(errstr,"sndseek() failed\n");
  1673. return SYSTEM_ERROR;
  1674. }
  1675. dz->total_samps_read = startsamp;
  1676. if((exit_status = read_samps(buf,dz))<0)
  1677. return(exit_status);
  1678. }
  1679. if(at) { /* if appropriate cutpoint found, mark it */
  1680. seg1 = (at - startsamp) - lastcutinbuf;
  1681. seg2 = thiscutinbuf - (at - startsamp);
  1682. rat = (double)seg1/(double)seg2;
  1683. if(rat < 2.0 && rat > .5) { /* if new cut is reasonable */
  1684. thiscut = cut[*cutcnt]; /* insert new cuts */
  1685. cut[*cutcnt] = at;
  1686. (*cutcnt)++;
  1687. cut[*cutcnt] = thiscut;
  1688. }
  1689. }
  1690. break;
  1691. }
  1692. }
  1693. return FINISHED;
  1694. }
  1695. /******************************** TRIANGULATE_ENV ********************************
  1696. *
  1697. * Segment divided into 4 quarters, to define 3 overlapping areas...
  1698. *
  1699. * 1st quarter 2nd quarter 3rd quarter 4th quarter
  1700. * ___________ ___________ ___________ ___________
  1701. * | || || || |
  1702. *
  1703. * |______Env0______________||_____Env2_______________|
  1704. *
  1705. * |_____Env1_______________|
  1706. *
  1707. * Find area with minimum energy.
  1708. */
  1709. int triangulate_env(int *here,int *there,int ideal_place,float *buf)
  1710. {
  1711. int localhere = *here, localthere = *there;
  1712. int seglen, this_zc_cnt[3], max_zc_cnt;
  1713. int quartlen, quart[5], n, m;
  1714. int oversize, use_1st_quart = 0, use_last_quart = 0;
  1715. double qsum[4], esum[3];
  1716. seglen = localthere - localhere;
  1717. quartlen = seglen/4;
  1718. oversize = seglen - (quartlen * 4);
  1719. if(*here > ideal_place)
  1720. use_1st_quart = 1;
  1721. if(*there < ideal_place)
  1722. use_last_quart =1;
  1723. if(oversize) { /* func only called if >=5 zero crossings: so >= 9 samples: so 'there' never <= 'here' */
  1724. localhere++; /* truncate examined area by 1 sample */
  1725. if(oversize > 1)
  1726. localthere--; /* truncate examined area by 1 more sample */
  1727. if(oversize > 2)
  1728. localhere++; /* truncate examined area by 1 more sample */
  1729. }
  1730. quart[0] = localhere; /* divide segment into 4 equal parts */
  1731. for(n = 0; n < 4; n++)
  1732. quart[n+1] = quart[n] + quartlen;
  1733. if(use_1st_quart)
  1734. max_zc_cnt = count_zerocrossings(quart[0],quart[2],buf);
  1735. else if(use_last_quart)
  1736. max_zc_cnt = count_zerocrossings(quart[2],quart[4],buf);
  1737. else {
  1738. max_zc_cnt = -1;
  1739. for(n = 0; n < 3; n++) { /* Find zcross count in each of 3 overalpping Envs */
  1740. this_zc_cnt[n] = count_zerocrossings(quart[n],quart[n+2],buf);
  1741. if(this_zc_cnt[n] > max_zc_cnt)
  1742. max_zc_cnt = this_zc_cnt[n];
  1743. }
  1744. }
  1745. if(max_zc_cnt < 5) /* If none of the Env-segs has >= 5 zcrossings, return withot doing anything */
  1746. return max_zc_cnt; /* causing calling loop to finish */
  1747. if(use_1st_quart) {
  1748. *here = quart[0];
  1749. *there = quart[2];
  1750. return max_zc_cnt;
  1751. } else if(use_last_quart) {
  1752. *here = quart[2];
  1753. *there = quart[4];
  1754. return max_zc_cnt;
  1755. }
  1756. for(n = 0; n < 4; n++) { /* Sum the abs-samples in each Quarter */
  1757. qsum[n] = 0.0;
  1758. for(m = quart[n];m <quart[n+1];m++)
  1759. qsum[n] += fabs(buf[m]);
  1760. }
  1761. for(n = 0; n < 3; n++) /* Sum the abs-samples in each Env */
  1762. esum[n] = qsum[n] + qsum[n+1];
  1763. if((flteq(esum[0],esum[1])) && (flteq(esum[0],esum[2]))) { /* esums are all equal */
  1764. if(this_zc_cnt[1] >= 5) { /* return middle seg limits, unless too few zcrossings */
  1765. *here = quart[1];
  1766. *there = quart[3];
  1767. return this_zc_cnt[1];
  1768. } else if(this_zc_cnt[0] >= 5) { /* else return start seg limits, unless too few zcrossings */
  1769. *here = quart[0];
  1770. *there = quart[2];
  1771. return this_zc_cnt[0];
  1772. } else { /* else return end seg limits */
  1773. *here = quart[2];
  1774. *there = quart[4];
  1775. return this_zc_cnt[2];
  1776. }
  1777. } else if((esum[0] <= esum[1]) && (esum[0] <= esum[2])) { /* esum[0] in Env0 has minimum energy */
  1778. if(this_zc_cnt[0] >= 5) { /* If Env0 has > 5 zcrossings */
  1779. *here = quart[0]; /* define this as the new working segment in which to find min energy */
  1780. *there = quart[2]; /* Else return without doing anything */
  1781. } /* (Calling process then drops out & uses segment we had at start of this func) */
  1782. return this_zc_cnt[0];
  1783. } else if((esum[1] <= esum[0]) && (esum[1] <= esum[2])) { /* esum[1] in Env1 has minimum energy */
  1784. if(this_zc_cnt[1] >= 5) {
  1785. *here = quart[1];
  1786. *there = quart[3];
  1787. }
  1788. return this_zc_cnt[1];
  1789. } /* else */ /* esum[2] in Env2 has minimum energy */
  1790. if(this_zc_cnt[2] >= 5) {
  1791. *here = quart[2];
  1792. *there = quart[4];
  1793. }
  1794. return this_zc_cnt[2];
  1795. }
  1796. /******************************** COUNT_ZEROCROSSINGS ********************************/
  1797. int count_zerocrossings(int here,int there,float *buf)
  1798. {
  1799. int done = 0, isup = 0;
  1800. int zc_cnt = 0;
  1801. float val = buf[here];
  1802. while(here < there) {
  1803. while(flteq(val,0.0)) { /* only accessed if segment starts with zeros */
  1804. here++;
  1805. if(here >= there) {
  1806. done = 1;
  1807. break;
  1808. }
  1809. val = buf[here];
  1810. }
  1811. if(done)
  1812. break;
  1813. while(val >= 0.0) {
  1814. if(isup == -1)
  1815. zc_cnt++;
  1816. isup = 1;
  1817. here++;
  1818. if(here >= there) {
  1819. done = 1;
  1820. break;
  1821. }
  1822. val = buf[here];
  1823. }
  1824. if(done)
  1825. break;
  1826. while(val < 0.0) {
  1827. if(isup == 1)
  1828. zc_cnt++;
  1829. isup = -1;
  1830. here++;
  1831. if(here >= there) {
  1832. done = 1;
  1833. break;
  1834. }
  1835. val = buf[here];
  1836. }
  1837. }
  1838. return zc_cnt;
  1839. }
  1840. /******************************** FIND_THE_LOCAL_PEAKS ********************************/
  1841. int find_the_local_peaks(int *here,int *there,float *buf,int *n,int trofpntcnt,int *trofpnt,
  1842. int *startsamp,int *endsamp,int losamp, int *cut, int cutcnt, double *localpeak, double *scanarray,
  1843. int *localpeakcnt,int *first_downcross,dataptr dz)
  1844. {
  1845. int exit_status, notfound = 0, finished = 0, /*below,*/ bufinc = 0;
  1846. int maxat=0;
  1847. float maxval=0.0f, val;
  1848. int wsize, hisamp,losampinbuf,hisampinbuf;
  1849. int orighere, origthere;
  1850. *first_downcross = -1;
  1851. wsize = *there - *here;
  1852. while(!finished) {
  1853. hisamp = min(dz->insams[0],losamp + wsize); /* get end-of-search area from wtime & half-wsize */
  1854. if(hisamp >= dz->insams[0])
  1855. hisamp = dz->insams[0];
  1856. losampinbuf = losamp - *startsamp; /* get search ends relative to buffer */
  1857. hisampinbuf = hisamp - *startsamp;
  1858. if(hisampinbuf >= dz->buflen) {
  1859. if((sndseekEx(dz->ifd[0],losamp,0)<0)){
  1860. sprintf(errstr,"sndseek() failed\n");
  1861. return SYSTEM_ERROR;
  1862. }
  1863. dz->total_samps_read = losamp;
  1864. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  1865. return(exit_status);
  1866. *endsamp = dz->total_samps_read;
  1867. *startsamp = *endsamp - dz->ssampsread;
  1868. losampinbuf = losamp - *startsamp; /* get search ends relative to buffer */
  1869. hisampinbuf = hisamp - *startsamp;
  1870. bufinc = 0;
  1871. }
  1872. *here = losampinbuf;
  1873. /* IGNORE EDGES OF WINDOW before the first, and after the last, zero crossing */
  1874. /* MOVE START SEARCH TO FIRST ZERO CROSSING */
  1875. if(!bufinc) {
  1876. val = buf[*here];
  1877. *first_downcross = -1;
  1878. if(val >= 0.0) {
  1879. while(val >= 0.0) {
  1880. (*here)++;
  1881. if(*here >= hisampinbuf) {
  1882. notfound = 1; /* no zero-cross found */
  1883. break;
  1884. }
  1885. val = buf[*here];
  1886. }
  1887. if(notfound) {
  1888. wsize += 20; /* no zero-cross found, return to loop head */
  1889. bufinc = 1;
  1890. continue; /* and move end of search window */
  1891. }
  1892. // VAL is just after zero cross downwards
  1893. *first_downcross = *here; /* mark 1st down-zerocross in search area */
  1894. } else if (val <= 0.0) {
  1895. while(val <= 0.0) {
  1896. (*here)++;
  1897. if(*here >= hisampinbuf) {
  1898. notfound = 1; /* no zero-cross found */
  1899. break;
  1900. }
  1901. val = buf[*here];
  1902. }
  1903. if(notfound) {
  1904. wsize += 20; /* no zero-cross found, return to loop head */
  1905. bufinc = 1;
  1906. continue;
  1907. }
  1908. // VAL is just after zero cross upwards
  1909. }
  1910. }
  1911. /* MOVE END OF SEARCH TO LAST ZERO CROSSING */
  1912. *there = hisampinbuf - 1;
  1913. val = buf[*there];
  1914. if(val >= 0.0) {
  1915. // below = 0;
  1916. while(val >= 0.0) {
  1917. (*there)--;
  1918. if(*there < losampinbuf) {
  1919. break;
  1920. }
  1921. val = buf[*there];
  1922. }
  1923. } else if(val <= 0.0) {
  1924. // below = 1;
  1925. while(val <= 0.0) {
  1926. (*there)--;
  1927. if(*there < losampinbuf) {
  1928. break;
  1929. }
  1930. val = buf[*there];
  1931. }
  1932. }
  1933. if(*there <= *here) { /* There is ONLY ONE zero-crossing found */
  1934. if(buf[*here] >= 0.0) { /* This is an upward-crossing zero, NOT a downward crossing zero */
  1935. notfound = 1; /* no DOWN-zero-cross found, return to loop head */
  1936. wsize += 20;
  1937. bufinc = 1;
  1938. continue; /* and move end of search window */
  1939. }
  1940. cut[cutcnt] = *here + *startsamp; /* return the single downward-crossing zero */
  1941. *first_downcross = *here;
  1942. dz->zeroset = 1;
  1943. return FINISHED;
  1944. } /* ELSE more than one zero-cross found */
  1945. /* therefore at least one intervening (+ or -) peak exists */
  1946. (*there)++; /* move end search to the value AFTER the last zero-crossing */
  1947. finished = 1; /* break from search loop */
  1948. }
  1949. orighere = *here;
  1950. origthere = *there;
  1951. /* STORE PEAKS BETWEEN ZERO-CROSSINGS */
  1952. val = buf[*here];
  1953. while(*here < *there) {
  1954. if(val >= 0.0) {
  1955. maxval = val;
  1956. maxat = *here;
  1957. while(val >= 0.0) {
  1958. (*here)++;
  1959. if(*here >= *there)
  1960. break;
  1961. val = buf[*here];
  1962. if(val > maxval) {
  1963. maxval = val;
  1964. maxat = *here;
  1965. }
  1966. }
  1967. } else if(val <= 0.0) {
  1968. maxval = val;
  1969. maxat = *here;
  1970. while(val <= 0.0) {
  1971. (*here)++;
  1972. if(*here >= *there)
  1973. break;
  1974. val = buf[*here];
  1975. if(val < maxval) {
  1976. maxval = val;
  1977. maxat = *here;
  1978. }
  1979. }
  1980. }
  1981. if(*first_downcross < 0)
  1982. dz->zeroset = 1;
  1983. if((maxval > 0.0) && (*first_downcross < 0))
  1984. *first_downcross = *here;
  1985. *localpeak++ = (double)maxval;
  1986. *localpeak++ = (double)(maxat + *startsamp);
  1987. }
  1988. *localpeakcnt = (localpeak - scanarray)/2;
  1989. if(*localpeakcnt == 1) {
  1990. if(!dz->zeroset) { /* If only 1 peak, the cut points are at the first_downcross if NOT zeroset */
  1991. *here = *first_downcross;
  1992. } else {
  1993. *here = orighere; // REDUNDANT, as, if dz->zeroset then "mark_cut" is not called.
  1994. *there = origthere;
  1995. }
  1996. }
  1997. return CONTINUE;
  1998. }
  1999. /******************************** MARK_CUT ********************************/
  2000. int mark_cut(int *cutcnt,int *cut,int localpeakcnt,double *startarray,int here,int there,
  2001. int startsamp,int first_downcross,double starttime,int msg,dataptr dz)
  2002. {
  2003. double localpeak1, localpeak2, localpeak3, maxlocalpeak, minenergy, energy;
  2004. int localpeakat1, localpeakat2 , at = 0, k, m, thissampinbuf;
  2005. int up;
  2006. double *localpeak = startarray;
  2007. switch(localpeakcnt) {
  2008. case(0):
  2009. if(msg)
  2010. sprintf(errstr,"FAILED TO LOCATE CUT POINT NEAR %lf secs: NO LOCAL PEAK FOUND: IMPOSSIBLE!!\n",starttime);
  2011. return(PROGRAM_ERROR);
  2012. case(1): /* SINGLE PEAK */
  2013. cut[*cutcnt] = here + startsamp; /* return location of zero crossing after peak */
  2014. break;
  2015. case(2): /* TWO PEAKS */
  2016. if(*localpeak > 0.0) { /* FIRST PEAK IS ABOVE ZERO: find downcross after this */
  2017. here = (int)round(*(localpeak+1)); /* location of 1st local peak */
  2018. here -= startsamp; /* location in buf */
  2019. here = next_zero_cross(here,dz); /* find following down-zerocross */
  2020. cut[*cutcnt] = here + startsamp; /* return its absolute location */
  2021. } else { /* FIRST PEAK IS BELOW ZERO */
  2022. if(fabs(*localpeak) < *(localpeak+2)) /* initial peak is lower energy */
  2023. cut[*cutcnt] = here + startsamp; /* return absolute-position of its start */
  2024. cut[*cutcnt] = there + startsamp; /*final peak is lower energy, return absolute-pos of its end */
  2025. }
  2026. break;
  2027. case(3):
  2028. localpeak1 = *localpeak++; /* THREE PEAKS */
  2029. localpeakat1 = (int)round(*localpeak++); /* Find location of (abs) max of the 3 */
  2030. maxlocalpeak = *localpeak;
  2031. at = 1;
  2032. localpeak2 = *localpeak++;
  2033. localpeakat2 = (int)round(*localpeak++);
  2034. if(localpeak2 > maxlocalpeak) {
  2035. maxlocalpeak = localpeak2;
  2036. at = 2;
  2037. }
  2038. localpeak3 = *localpeak++;
  2039. if(localpeak3 > maxlocalpeak) {
  2040. maxlocalpeak = localpeak3;
  2041. at = 3;
  2042. }
  2043. up = 0; /* Is first peak +ve or -ve */
  2044. if(localpeak1 > 0.0)
  2045. up = 1;
  2046. switch(at) { /* Select on basis of where max peak is */
  2047. case(1): /* 1st peak is max */
  2048. if(up) {
  2049. cut[*cutcnt] = there + startsamp; /* +ve cycle, return end of last peak */
  2050. } else {
  2051. here = localpeakat2 - startsamp;
  2052. here = next_zero_cross(here,dz); /* -ve cycle, return zero after peak2 */
  2053. cut[*cutcnt] = here + startsamp;
  2054. }
  2055. break;
  2056. case(2): /* 2nd peak is max */
  2057. if(localpeak1 > localpeak3) { /* 3rd peak is minimum */
  2058. if(up) {
  2059. cut[*cutcnt] = there + startsamp; /* +ve cycle, return end of peak3 */
  2060. } else {
  2061. here = localpeakat2 - startsamp;
  2062. here = next_zero_cross(here,dz); /* -ve cycle, return start of peak3 */
  2063. cut[*cutcnt] = here + startsamp;
  2064. }
  2065. } else { /* 1st peak is minimum */
  2066. if(up) {
  2067. here = localpeakat1 - startsamp;
  2068. here = next_zero_cross(here,dz); /* +ve cycle, return end of peak1 */
  2069. cut[*cutcnt] = here + startsamp;
  2070. } else {
  2071. cut[*cutcnt] = here + startsamp; /* -ve cycle, return start of peak1 */
  2072. }
  2073. }
  2074. break;
  2075. case(3): /* 3rd peak is max */
  2076. if(up) {
  2077. here = localpeakat1 - startsamp;
  2078. here = next_zero_cross(here,dz); /* +ve cycle, return end of peak1 */
  2079. cut[*cutcnt] = here + startsamp;
  2080. } else {
  2081. cut[*cutcnt] = here + startsamp; /* -ve cycle, return start of peak1 */
  2082. }
  2083. break;
  2084. }
  2085. break;
  2086. default: /* MORE THAN 3 PEAKS */
  2087. localpeak = startarray;
  2088. minenergy = HUGE; /* find minimum energy of each PAIR of peaks */
  2089. for(k = 0,m = 2; m < localpeakcnt * 2; k+=2,m+=2) {
  2090. energy = fabs(localpeak[k]) + fabs(localpeak[m]);
  2091. if(energy < minenergy) {
  2092. minenergy = energy;
  2093. at = k;
  2094. }
  2095. }
  2096. thissampinbuf = (int)round(localpeak[at+1]);
  2097. thissampinbuf -= startsamp;
  2098. if(localpeak[at] > 0.0) { /* if min energy is at a pair that starts +ve */
  2099. thissampinbuf = next_zero_cross(thissampinbuf,dz);
  2100. cut[*cutcnt] = thissampinbuf + startsamp; /* return end of that pair's 1st peak */
  2101. } else {
  2102. thissampinbuf = previous_zero_cross(thissampinbuf,first_downcross,dz);
  2103. cut[*cutcnt] = thissampinbuf + startsamp; /* else return start of that pair's 1st peak */
  2104. }
  2105. }
  2106. return(FINISHED);
  2107. }
  2108. /***************************** SMOOTH_CUTS *****************************/
  2109. int smooth_cuts(int *cut,int *cutcnt,int cutstart,dataptr dz)
  2110. {
  2111. int exit_status;
  2112. int n, k, seg0, seg1, seg2, minseg, end, start, *thiscut, srchlen, minlen;
  2113. int pitchseglim, pitchseglo=0, realend, lastcutval;
  2114. double pitchseg, lastpitchseg=0.0, time, big_seg, this_seg, last_seg, big_int, this_int, last_int;
  2115. int last_cut, this_cut, next_cut;
  2116. double last_ratio, next_ratio;
  2117. if((sndseekEx(dz->ifd[0],0,0)<0)){
  2118. sprintf(errstr,"sndseek() failed\n");
  2119. return SYSTEM_ERROR;
  2120. }
  2121. dz->total_samps_read = 0;
  2122. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  2123. return(exit_status);
  2124. for(n=3 + cutstart;n<*cutcnt;n++) {
  2125. lastcutval = 0;
  2126. end = cut[n];
  2127. realend = end;
  2128. time = (double)cut[n-3]/(double)dz->infile->srate;
  2129. if((exit_status = read_value_from_brktable(time,0,dz))<0)
  2130. return(exit_status); /* Get pitch at start of cut segment */
  2131. if(dz->param[0] > 0.0) { /* if it's a true pitch ... */
  2132. pitchseg = (double)dz->infile->srate/dz->param[0]; /* Find corresponding segment length */
  2133. pitchseglim = (int)round(pitchseg * ALMOST_OCT); /* Go to almost an 8va up */
  2134. pitchseglo = (int)round(pitchseg/ALMOST_OCT); /* Go to almost an 8va down */
  2135. pitchseglim += cut[n-3]; /* Prevent autocorrelation-search going beyond 8va */
  2136. if(end > pitchseglim) {
  2137. end = pitchseglim; /* Typically, end of search is ~2* expected pitchseg len */
  2138. lastcutval = cut[n-2]; /* & we save origval in case new val is to be INTERPOLATED. */
  2139. } /* But if 3segs is smaller, set endofsearch to endof 3segs */
  2140. } else
  2141. pitchseg = -1.0;
  2142. start = cut[n-3];
  2143. thiscut = &(cut[n-2]);
  2144. seg0 = cut[n-2] - cut[n-3];
  2145. seg1 = cut[n-1] - cut[n-2];
  2146. seg2 = cut[n] - cut[n-1];
  2147. minseg = min(seg0,seg1);
  2148. minseg = min(minseg,seg2);
  2149. srchlen = cut[n] - cut[n-3];
  2150. if((minlen = minseg/2) <= 0) /* if previous segs tiny, e.g. just 1 seg, this val gets 0 */
  2151. minlen = min(srchlen/6,pitchseglo); /* use either ~8va below pitch, or half the average of 3seglen */
  2152. if(n >= 3) {
  2153. last_cut = cut[n-2] - cut[n-3];
  2154. this_cut = cut[n-1] - cut[n-2];
  2155. next_cut = cut[n] - cut[n-1];
  2156. if(((last_cut > this_cut) && (next_cut > this_cut)) || ((last_cut < this_cut) && (next_cut < this_cut))) {
  2157. if(last_cut > this_cut) {
  2158. last_ratio = (double)last_cut/(double)this_cut;
  2159. next_ratio = (double)next_cut/(double)this_cut;
  2160. } else {
  2161. last_ratio = (double)this_cut/(double)last_cut;
  2162. next_ratio = (double)this_cut/(double)next_cut;
  2163. }
  2164. if((last_ratio > 1.3) || (next_ratio > 1.3)) {
  2165. if((exit_status = auto_correlate(start,thiscut,end,realend,minlen,pitchseg,0,dz))<0)
  2166. return(exit_status);
  2167. }
  2168. }
  2169. }
  2170. if(cut[n-2] >= cut[n-1]) { /* If next cut is now too near to new cut ... */
  2171. for(k = n;k<*cutcnt;k++) /* e.g. 0 20 30 40 --> 0 20 40 40 .... omit duplicate */
  2172. cut[k-1] = cut[k]; /* OR 0 20 30 40 --> 0 20 50 40 .... omit skipped val */
  2173. (*cutcnt)--;
  2174. n--;
  2175. } else if(lastcutval > 0) { /* If new cut will fit between previous, and original value here */
  2176. /* e.g. originally 20 [200] 220 240 --> 20 40 220 240 (200 stored as lastcutval) */
  2177. if(lastcutval - cut[n-2] > pitchseglo) {
  2178. for(k = *cutcnt;k>=n-1;k--) /* then reinsert orig val .... */
  2179. cut[k+1] = cut[k]; /* e.g. 20 40 220 240 --> 20 40 200 220 240 */
  2180. cut[n-1] = lastcutval;
  2181. (*cutcnt)++;
  2182. }
  2183. } /* Eliminate segs that are 8va up (twice too short) */
  2184. if((n > cutstart+3) && (lastpitchseg > 0.0) && (pitchseg > 0.0)) {
  2185. pitchseg = (pitchseg + lastpitchseg)/2.0;
  2186. this_seg = (double)(cut[n-2] - cut[n-3]);
  2187. if((big_seg = (double)(cut[n-2] - cut[n-4])) > pitchseg)
  2188. big_int = big_seg/pitchseg;
  2189. else
  2190. big_int = pitchseg/big_seg;
  2191. if(this_seg > pitchseg)
  2192. this_int = this_seg/pitchseg;
  2193. else
  2194. this_int = pitchseg/this_seg;
  2195. if((last_seg = (double)(cut[n-3] - cut[n-4])) > pitchseg)
  2196. last_int = last_seg/pitchseg;
  2197. else
  2198. last_int = pitchseg/last_seg;
  2199. if((big_int < this_int) && (big_int < last_int)) {
  2200. for(k = n-2;k < *cutcnt;k++)
  2201. cut[k-1] = cut[k];
  2202. (*cutcnt)--;
  2203. n--;
  2204. }
  2205. }
  2206. lastpitchseg = pitchseg;
  2207. }
  2208. return FINISHED;
  2209. }
  2210. /****************************** SILENCE_ZERO_SIGNAL_AREAS *********************************/
  2211. int silence_zero_signal_areas(int *outsegs,int *silence,int outcnt,dataptr dz)
  2212. {
  2213. double *frqdata = dz->brk[0];
  2214. int n, segcnt = 0;
  2215. int zeropnt[2]={0}, zerocnt = 0, brklen = dz->brksize[0] * 2, frqindx, timindx, nufrqindx, nutimindx;
  2216. n = 0;
  2217. timindx = 0;
  2218. frqindx = 1;
  2219. while (n < dz->brksize[0]) {
  2220. zerocnt = 0;
  2221. if(frqdata[frqindx] < 0.0) {
  2222. zeropnt[0] = (int)round(frqdata[timindx] * (double)dz->infile->srate);
  2223. zerocnt = 1;
  2224. nufrqindx =frqindx + 2;
  2225. nutimindx =timindx + 2;
  2226. while(nufrqindx < brklen) {
  2227. if(frqdata[nufrqindx] < 0.0) {
  2228. zeropnt[1] = (int)round(frqdata[nutimindx] * (double)dz->infile->srate);
  2229. zerocnt = 2;
  2230. frqindx = nufrqindx;
  2231. timindx = nutimindx;
  2232. n++;
  2233. nufrqindx += 2;
  2234. nutimindx += 2;
  2235. } else {
  2236. break;
  2237. }
  2238. }
  2239. while(outsegs[segcnt] < zeropnt[0]) {
  2240. if((segcnt+=2) >= outcnt)
  2241. return FINISHED;
  2242. }
  2243. segcnt-=2;
  2244. silence[segcnt/2] = 1;
  2245. if (zerocnt > 1) {
  2246. while(outsegs[segcnt] <= zeropnt[1]) {
  2247. silence[segcnt/2] = 1;
  2248. segcnt += 2;
  2249. if(segcnt >= outcnt)
  2250. return FINISHED;
  2251. }
  2252. }
  2253. }
  2254. n++;
  2255. timindx += 2;
  2256. frqindx += 2;
  2257. }
  2258. return(FINISHED);
  2259. }
  2260. /****************************** SILENCE_LOLEVEL_FOFS *********************************/
  2261. int silence_lolevel_fofs(int *outsegs,int *silence,int outcnt,dataptr dz)
  2262. {
  2263. int exit_status;
  2264. int n, m, totalsamps = 0, endsegindx, levelcnt, ipos, levelsiz = (outcnt)/2;
  2265. double maxsamp = 0.0, maxlocalsamp = 0.0, *level, lolim;
  2266. float *ibuf = dz->sampbuf[0];
  2267. if((level = (double *)malloc(levelsiz * sizeof(double))) == NULL) {
  2268. sprintf(errstr,"INSUFFICIENT MEMORY establishing level check array.\n");
  2269. return(MEMORY_ERROR);
  2270. }
  2271. if((sndseekEx(dz->ifd[0],0,0)<0)){
  2272. sprintf(errstr,"sndseek() failed\n");
  2273. return SYSTEM_ERROR;
  2274. }
  2275. dz->total_samps_read = 0;
  2276. if((exit_status = read_samps(ibuf,dz))<0)
  2277. return(exit_status);
  2278. endsegindx = 1;
  2279. levelcnt = 0;
  2280. while(dz->ssampsread > 0) {
  2281. ipos = 0;
  2282. while(ipos < dz->ssampsread) {
  2283. maxsamp = max(maxsamp,fabs(ibuf[ipos]));
  2284. maxlocalsamp = max(maxlocalsamp,fabs(ibuf[ipos]));
  2285. ipos++;
  2286. totalsamps++;
  2287. if(totalsamps >= outsegs[endsegindx]) {
  2288. if(levelcnt < levelsiz) {
  2289. level[levelcnt++] = maxlocalsamp;
  2290. maxlocalsamp = 0.0;
  2291. endsegindx += 2;
  2292. }
  2293. }
  2294. }
  2295. if((exit_status = read_samps(ibuf,dz))<0)
  2296. return(exit_status);
  2297. }
  2298. if((sndseekEx(dz->ifd[0],0,0)<0)){
  2299. sprintf(errstr,"sndseek() failed\n");
  2300. return SYSTEM_ERROR;
  2301. }
  2302. dz->total_samps_read = 0;
  2303. if((exit_status = read_samps(ibuf,dz))<0)
  2304. return(exit_status);
  2305. lolim = maxsamp * dbtogain(dz->param[1]);
  2306. n = 0;
  2307. m = 0;
  2308. while(n < outcnt) {
  2309. if(level[m] < lolim)
  2310. silence[m] = 1;
  2311. n += 2;
  2312. m++;
  2313. }
  2314. return(FINISHED);
  2315. }
  2316. /*************************** CREATE_TWEET_SNDBUFS **************************/
  2317. int create_tweet_sndbufs(dataptr dz)
  2318. {
  2319. int bigbufsize;
  2320. if(dz->sbufptr == 0 || dz->sampbuf==0) {
  2321. sprintf(errstr,"buffer pointers not allocated: create_fofex_sndbufs()\n");
  2322. return(PROGRAM_ERROR);
  2323. }
  2324. bigbufsize = (int)(size_t) Malloc(-1);
  2325. dz->buflen = bigbufsize/sizeof(float);
  2326. if((dz->bigbuf = (float *)malloc(bigbufsize * 2)) == NULL) {
  2327. sprintf(errstr,"INSUFFICIENT MEMORY to create initial sound buffer.\n");
  2328. return(PROGRAM_ERROR);
  2329. }
  2330. dz->sampbuf[0] = dz->bigbuf; // ibuf
  2331. dz->sampbuf[1] = dz->bigbuf + dz->buflen; // ovflw
  2332. return(FINISHED);
  2333. }
  2334. /*************************** RECREATE_TWEET_SNDBUFS **************************/
  2335. int recreate_tweet_sndbufs(dataptr dz)
  2336. {
  2337. int n;
  2338. int bigbufsize;
  2339. free(dz->bigbuf);
  2340. dz->bufcnt = 3;
  2341. bigbufsize = (int)(size_t) Malloc(-1);
  2342. bigbufsize = max(dz->buflen * sizeof(float),(unsigned int)bigbufsize);
  2343. dz->buflen = bigbufsize/sizeof(float);
  2344. if((dz->bigbuf = (float *)malloc(bigbufsize * (dz->bufcnt+1))) == NULL) {
  2345. sprintf(errstr,"INSUFFICIENT MEMORY to recreate sound buffers.\n");
  2346. return(PROGRAM_ERROR);
  2347. }
  2348. for(n=0;n<dz->bufcnt;n++)
  2349. dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  2350. dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
  2351. return(FINISHED);
  2352. }
  2353. /*************************** EXTRACT_FORMANT_SHAPE **************************/
  2354. int extract_formant_shape(double *env,int segdur,int maxoutdur,dataptr dz)
  2355. {
  2356. int phase = 0, maxposfirst, phasecnt;
  2357. float *chpbuf = dz->sampbuf[2];
  2358. double maxval, lastval, diff, frac, ratio;
  2359. int n = 0, m, k, step, maxpos = 0, maxposend, lastpos;
  2360. memset((char *)env,0,maxoutdur * sizeof(double));
  2361. while(chpbuf[n] == 0.0) {
  2362. n++;
  2363. if(n >= segdur)
  2364. return FINISHED;
  2365. }
  2366. if(chpbuf[n] > 0.0)
  2367. phase = 1;
  2368. else
  2369. phase = -1;
  2370. maxposfirst = -1;
  2371. phasecnt = 0;
  2372. maxval = 0.0;
  2373. while(n < segdur) {
  2374. switch(phase) {
  2375. case(1): // Find absolute maximum sample in a wavset
  2376. if(chpbuf[n] > 0.0) {
  2377. if(chpbuf[n] > maxval) {
  2378. maxval = chpbuf[n];
  2379. maxpos = n;
  2380. }
  2381. } else {
  2382. if(fabs(chpbuf[n]) > maxval) {
  2383. maxval = fabs(chpbuf[n]);
  2384. maxpos = n;
  2385. }
  2386. phase = -phase;
  2387. phasecnt++;
  2388. }
  2389. break;
  2390. case(-1):
  2391. if(chpbuf[n] < 0.0) {
  2392. if(fabs(chpbuf[n]) > maxval) {
  2393. maxval = fabs(chpbuf[n]);
  2394. maxpos = n;
  2395. }
  2396. } else {
  2397. if(chpbuf[n] > maxval) {
  2398. maxval = chpbuf[n];
  2399. maxpos = n;
  2400. }
  2401. phase = -phase;
  2402. phasecnt++;
  2403. }
  2404. break;
  2405. }
  2406. if(phasecnt == 2) {
  2407. if(maxposfirst < 0)
  2408. maxposfirst = maxpos;
  2409. env[maxpos] = maxval; // and store it in corresponding position in envelope
  2410. maxval = 0.0;
  2411. phasecnt = 0;
  2412. }
  2413. n++;
  2414. }
  2415. env[maxpos] = maxval;
  2416. maxposend = maxpos;
  2417. k = 0;
  2418. lastpos = 0;
  2419. lastval = 0.0;
  2420. n = 0;
  2421. while(n < segdur) { // Interpolate between stored (non-zero) vals
  2422. if(env[n] > 0.0) {
  2423. step = n - lastpos;
  2424. diff = env[n] - lastval;
  2425. for(m= 0,k = lastpos;m < step; k++,m++) {
  2426. ratio = (double)m/(double)step;
  2427. frac = diff * ratio;
  2428. env[k] = lastval + frac;
  2429. }
  2430. lastval = env[n];
  2431. lastpos = n;
  2432. }
  2433. n++;
  2434. }
  2435. step = n - lastpos; // Interpolate down to zero end
  2436. diff = 0.0 - lastval;
  2437. for(m= 0,k = lastpos;m < step; k++,m++) {
  2438. ratio = (double)m/(double)step;
  2439. frac = diff * ratio;
  2440. env[k] = lastval + frac;
  2441. }
  2442. for(n=0;n < maxposfirst;n++) // Check start and end to see if signal rises above interpolated envelope vals
  2443. env[n] = max(env[n],fabs(chpbuf[n]));
  2444. for(n=maxposend;n < segdur;n++)
  2445. env[n] = max(env[n],fabs(chpbuf[n]));
  2446. return FINISHED;
  2447. }
  2448. /******************************** IMPULSE ********************************/
  2449. int impulse(int seglen,double time,dataptr dz)
  2450. {
  2451. int exit_status;
  2452. int n, m, k, pkts = 0, impulse_halflen;
  2453. float *chpbuf = dz->sampbuf[2];
  2454. double sharpness, range, val, maxsamp, normaliser, srate = (double)dz->infile->srate;
  2455. double halfsum, sumup, sumdn, adjustup, adjustdn;
  2456. memset((char *)chpbuf,0,dz->buflen * sizeof(float));
  2457. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  2458. return exit_status;
  2459. impulse_halflen = seglen/2;
  2460. if(seglen < 4)
  2461. return FINISHED; // if seglen too short, "output" silence
  2462. switch(dz->mode) {
  2463. case(0):
  2464. pkts = dz->iparam[TWT_PKCNT];
  2465. break;
  2466. case(1):
  2467. pkts = (int)round((double)dz->iparam[TWT_PKCNT] * ((double)seglen/srate));
  2468. break;
  2469. }
  2470. maxsamp = 0.0;
  2471. if(dz->mode == 2) { // Noise
  2472. sumup = 0.0;
  2473. sumdn = 0.0;
  2474. for(n = 0;n<impulse_halflen*2;n++) {
  2475. val = (drand48() * 2.0) - 1.0;
  2476. if(val > 0.0)
  2477. sumup += val;
  2478. else if (val < 0.0)
  2479. sumdn -= val;
  2480. chpbuf[n] = (float)val;
  2481. }
  2482. halfsum = (sumup + sumdn)/2.0;
  2483. adjustup = halfsum/sumdn;
  2484. adjustdn = halfsum/sumdn;
  2485. for(n = 0;n<impulse_halflen*2;n++) {
  2486. if(chpbuf[n] > 0.0)
  2487. chpbuf[n] = (float)(chpbuf[n] * adjustup);
  2488. else if(chpbuf[n] < 0.0)
  2489. chpbuf[n] = (float)(chpbuf[n] * adjustdn);
  2490. maxsamp = max(maxsamp,fabs(chpbuf[n]));
  2491. }
  2492. normaliser = 1.0/maxsamp;
  2493. } else {
  2494. if(seglen < pkts * 4)
  2495. range = (double)(seglen/4); // A cycle must have at least 4 samples
  2496. else
  2497. range = (double)pkts;
  2498. range *= PI;
  2499. sharpness = 1.0/dz->param[TWT_CHIRP];
  2500. for(n = 0,m=impulse_halflen,k=impulse_halflen-1;n<impulse_halflen;n++,m++,k--) {
  2501. val = (double)n/(double)impulse_halflen;
  2502. val = pow(val,sharpness);
  2503. val *= range;
  2504. val = sin(val);
  2505. chpbuf[m] = (float)-val;
  2506. chpbuf[k] = (float)val;
  2507. maxsamp = max(maxsamp,fabs(chpbuf[k]));
  2508. }
  2509. }
  2510. normaliser = 1.0/maxsamp;
  2511. for(n=0;n < impulse_halflen * 2;n++)
  2512. chpbuf[n] = (float)(chpbuf[n] * normaliser);
  2513. return FINISHED;
  2514. }
  2515. /************************ HANDLE_THE_SPECIAL_DATA *********************/
  2516. int handle_the_special_data(int *cmdlinecnt,char ***cmdline,dataptr dz)
  2517. {
  2518. int exit_status;
  2519. if(!sloom) {
  2520. if(*cmdlinecnt <= 0) {
  2521. sprintf(errstr,"Insufficient parameters on command line.\n");
  2522. return(USAGE_ONLY);
  2523. }
  2524. }
  2525. if((exit_status = get_exclude_data((*cmdline)[0],dz))<0)
  2526. return(exit_status);
  2527. (*cmdline)++;
  2528. (*cmdlinecnt)--;
  2529. return(FINISHED);
  2530. }
  2531. /*************************** GET_EXCLUDE_DATA ***********************/
  2532. int get_exclude_data(char *filename,dataptr dz)
  2533. {
  2534. FILE *fp;
  2535. double dummy = 0.0, lasttime, srate = (double)dz->infile->srate;
  2536. int cnt, badcnt, *times;
  2537. char temp[200], temp2[4], *q;
  2538. if(sloom) {
  2539. temp[0] = NUMERICVAL_MARKER; // Reads a zero instead of a filename
  2540. temp[1] = ENDOFSTR;
  2541. temp2[0] = filename[0];
  2542. temp2[1] = ENDOFSTR;
  2543. if(!strcmp(temp2,temp)) {
  2544. dz->itemcnt = 0;
  2545. return FINISHED;
  2546. }
  2547. } else {
  2548. if(!strcmp(filename,"0")) {
  2549. dz->itemcnt = 0;
  2550. return FINISHED;
  2551. }
  2552. }
  2553. if((fp = fopen(filename,"r"))==NULL) {
  2554. sprintf(errstr, "Can't open file %s to read data.\n",filename);
  2555. return(DATA_ERROR);
  2556. }
  2557. cnt = 0;
  2558. badcnt = 0;
  2559. lasttime = -1.0;
  2560. while(fgets(temp,200,fp)==temp) {
  2561. q = temp;
  2562. if(*q == ';') // Allow comments in file
  2563. continue;
  2564. while(get_float_from_within_string(&q,&dummy)) {
  2565. if(cnt == 0 && dummy < 0.0) {
  2566. sprintf(errstr,"Time (%lf) is less than zero in file %s.\n",dummy,filename);
  2567. return(DATA_ERROR);
  2568. }
  2569. if(dummy <= lasttime) {
  2570. sprintf(errstr,"Times (%lf & %lf) in file %s are not in increasing order.\n",lasttime,dummy,filename);
  2571. return(DATA_ERROR);
  2572. }
  2573. if(dummy > dz->duration) {
  2574. badcnt++; // Rounding error could make a valid end-of-file time not exactly tally with "duration"
  2575. if(badcnt > 1) { // So allow 1 overflow time, but not more than 1
  2576. sprintf(errstr,"Time (%lf),in file %s, is beyond end of infile (%lf).\n",dummy,filename,dz->duration);
  2577. return(DATA_ERROR);
  2578. }
  2579. }
  2580. lasttime = dummy;
  2581. cnt++;
  2582. }
  2583. }
  2584. if(cnt == 0) {
  2585. sprintf(errstr,"No data in file %s\n",filename);
  2586. return(DATA_ERROR);
  2587. }
  2588. if(((dz->itemcnt = cnt/2) * 2) != cnt) {
  2589. sprintf(errstr,"Data not paired correctly in file %s\n",filename);
  2590. return(DATA_ERROR);
  2591. }
  2592. if((dz->lparray[0] = (int *)malloc(cnt * sizeof(int)))==NULL) {
  2593. sprintf(errstr,"INSUFFICIENT MEMORY for data in file %s.\n",filename);
  2594. return(MEMORY_ERROR);
  2595. }
  2596. times = dz->lparray[0];
  2597. rewind(fp);
  2598. cnt = 0;
  2599. while(fgets(temp,200,fp)==temp) {
  2600. q = temp;
  2601. if(*q == ';') // Allow comments in file
  2602. continue;
  2603. while(get_float_from_within_string(&q,&dummy))
  2604. times[cnt++] = (int)round(dummy * srate);
  2605. }
  2606. if(flteq(dummy,dz->duration)) // Force any eof time to be at sample-end of infile
  2607. times[cnt - 1] = dz->insams[0];
  2608. if(fclose(fp)<0) {
  2609. fprintf(stdout,"WARNING: Failed to close file %s.\n",filename);
  2610. fflush(stdout);
  2611. }
  2612. return(FINISHED);
  2613. }
  2614. /******************************** TWEET_PARAM_PREPROCESS ********************************/
  2615. int tweet_param_preprocess(dataptr dz)
  2616. {
  2617. int n, m;
  2618. if(dz->brksize[TWT_CHIRP]) { // Divide by 10 then Convert to a power of 10
  2619. for(n=0,m=1;n < dz->brksize[TWT_CHIRP];n++,m+=2) // Vals 0 10 20 30
  2620. dz->brk[TWT_CHIRP][m] = pow(10.0,(dz->brk[TWT_CHIRP][m]/10.0)); // -> 0 1 2 3
  2621. } else // -> 1 10 100 1000
  2622. dz->param[TWT_CHIRP] = pow(10.0,(dz->param[TWT_CHIRP]/10.0));
  2623. return FINISHED;
  2624. }
  2625. /**************************** CHECK_TWEET_PARAM_VALIDITY_AND_CONSISTENCY *****************************/
  2626. int check_tweet_param_validity_and_consistency(dataptr dz)
  2627. {
  2628. if(dz->brksize[0] == 0) {
  2629. sprintf(errstr,"PITCH PARAMETER MUST BE IN A BREAKPOINT FILE.\n");
  2630. return(DATA_ERROR);
  2631. }
  2632. /* EXTRA SMOOTHING OF PITCH DATA */
  2633. smooth_oct_glitches(dz);
  2634. return FINISHED;
  2635. }
  2636. /************************* SMOOTH_OCT_GLITCHES *******************/
  2637. void smooth_oct_glitches(dataptr dz)
  2638. {
  2639. int n, m, jumpcnt, start, end, k, datalen, endtime_index, jump[2];
  2640. int octglitch;
  2641. double interval, *pitchdata = dz->brk[0], time[2];
  2642. datalen = dz->brksize[0] * 2;
  2643. endtime_index = datalen - 2;
  2644. jumpcnt = 0;
  2645. m = 1;
  2646. n = 3;
  2647. while(n < datalen) {
  2648. interval = pitchdata[n]/pitchdata[m];
  2649. if(interval > 2.0) {
  2650. jump[jumpcnt] = n;
  2651. time[jumpcnt] = pitchdata[n-1];
  2652. jumpcnt++;
  2653. }
  2654. else if(interval < 0.5) {
  2655. jump[jumpcnt] = -n;
  2656. time[jumpcnt] = pitchdata[n-1];
  2657. jumpcnt++;
  2658. }
  2659. if(jumpcnt == 2) {
  2660. octglitch = 0;
  2661. if((jump[0] < 0) && (jump[1] > 0)) {
  2662. octglitch = -1;
  2663. } else if((jump[0] > 0) && (jump[1] < 0) ) {
  2664. octglitch = 1;
  2665. }
  2666. if(octglitch && (time[1] - time[0] < MINSPEECHGLITCH)) {
  2667. start = (int)abs(jump[0]);
  2668. end = (int)abs(jump[1]);
  2669. k = start;
  2670. if(octglitch > 0) {
  2671. while(k < end) {
  2672. pitchdata[k] /= 2.0;
  2673. k += 2;
  2674. }
  2675. } else {
  2676. while(k < end) {
  2677. pitchdata[k] *= 2.0;
  2678. k += 2;
  2679. }
  2680. }
  2681. jumpcnt = 0;
  2682. } else {
  2683. jump[0] = jump[1];
  2684. time[0] = time[1];
  2685. jumpcnt = 1;
  2686. }
  2687. }
  2688. n += 2;
  2689. m += 2;
  2690. }
  2691. if(jumpcnt) {
  2692. if(time[0] < MINSPEECHGLITCH) { // SINGLE LEAP AT START
  2693. k = 1;
  2694. end = (int)abs(jump[0]);
  2695. if(jump[0] > 0) {
  2696. while(k < end) {
  2697. pitchdata[k] *= 2.0;
  2698. k += 2;
  2699. }
  2700. } else {
  2701. while(k < end) {
  2702. pitchdata[k] /= 2.0;
  2703. k += 2;
  2704. }
  2705. }
  2706. } else if(pitchdata[endtime_index] - time[0] < MINSPEECHGLITCH) { // SINGLE LEAP LEFT AT END
  2707. k = (int)abs(jump[0]);
  2708. end = datalen;
  2709. if(jump[0] > 0) {
  2710. while(k < end) {
  2711. pitchdata[k] /= 2.0;
  2712. k += 2;
  2713. }
  2714. } else {
  2715. while(k < end) {
  2716. pitchdata[k] *= 2.0;
  2717. k += 2;
  2718. }
  2719. }
  2720. }
  2721. }
  2722. }
  2723. /*************************** GETMAXSAMPR ******************************/
  2724. float getmaxsampr(int startsamp, int sampcnt,float *buffer)
  2725. {
  2726. int i, endsamp = startsamp + sampcnt;
  2727. float thisval, thismaxsamp = -1;
  2728. for(i = startsamp; i<endsamp; i++) {
  2729. if((thisval = (float)fabs(buffer[i]))>thismaxsamp)
  2730. thismaxsamp = thisval;
  2731. }
  2732. return(thismaxsamp);
  2733. }
  2734. /**************************** READ_VALIDPITCH_WSIZE_IN_SAMPS_FROM_BRKTABLE *****************************/
  2735. int read_validpitch_wsize_in_samps_from_brktable(double thistime,int kk,dataptr dz)
  2736. {
  2737. double dnval = 0.0, upval = 0.0, val, time;
  2738. double diff, mindiff = HUGE;
  2739. double dntimediff = -1.0, uptimediff = -1.0;
  2740. int n, m, wsize, here = 0;
  2741. for(n = 0,m = 0;n < dz->brksize[kk];n++,m+=2) {
  2742. time = dz->brk[kk][m];
  2743. if((diff = fabs(time - thistime)) < mindiff) {
  2744. mindiff = diff;
  2745. here = m;
  2746. }
  2747. n++;
  2748. }
  2749. time = dz->brk[kk][here];
  2750. val = dz->brk[kk][here+1];
  2751. if(val <= 0.0) { /* no pitch */
  2752. m = here;
  2753. m -= 2;
  2754. while(m >= 0) {
  2755. if((dnval = dz->brk[kk][m+1]) > 0.0) {
  2756. dntimediff = time - dz->brk[kk][m];
  2757. break;
  2758. }
  2759. m -= 2;
  2760. }
  2761. m = here;
  2762. m += 2;
  2763. while(m < (dz->brksize[kk] * 2)) {
  2764. if((upval = dz->brk[kk][m+1]) > 0.0) {
  2765. uptimediff = dz->brk[kk][m] - time;
  2766. break;
  2767. }
  2768. m += 2;
  2769. }
  2770. if(dntimediff < 0.0)
  2771. val = upval;
  2772. else if(uptimediff < 0.0)
  2773. val = dnval;
  2774. else if(uptimediff < dntimediff)
  2775. val = upval;
  2776. else
  2777. val = dnval;
  2778. }
  2779. wsize = (int)round((double)dz->infile->srate/val);
  2780. return wsize;
  2781. }
  2782. /**************************** NEXT_ZERO_CROSS *****************************/
  2783. int next_zero_cross(int here,dataptr dz)
  2784. {
  2785. float *buf = dz->sampbuf[0];
  2786. float val = buf[here];
  2787. while((val = buf[here]) >= 0.0)
  2788. here++;
  2789. return here;
  2790. }
  2791. /**************************** PREVIOUS_ZERO_CROSS *****************************/
  2792. int previous_zero_cross(int here,int firstzero,dataptr dz)
  2793. {
  2794. float *buf = dz->sampbuf[0];
  2795. float val;
  2796. while((val = buf[here]) < 0.0) {
  2797. here--;
  2798. if(here <= firstzero)
  2799. return firstzero;
  2800. }
  2801. here++;
  2802. return here;
  2803. }
  2804. /******************************** AUTO_CORRELATE ********************************
  2805. * *at
  2806. * (cut to search realend
  2807. * start adjust) end of 3segs
  2808. * ___________ ______ _____________i___________
  2809. * | | | i |
  2810. * i
  2811. *
  2812. *
  2813. *
  2814. * start = start of the segment.
  2815. * end = end of the search area for correlation between segs.
  2816. * *at = starts out as the original cut position, and may be changed by this process.
  2817. * realend = end of the group of 3 segs: if no cutsite found before 'end', extend search towards 'realend'
  2818. * (cutsites are always at downward-crossing zeros)
  2819. * minlen = minimum length of adjacent stretches of sound to compare
  2820. * pitchseg = length of seg corresponding to pitch (if any) at this place.
  2821. * if the new cutpoint is further from the pitchseg val than the original cut (*at)
  2822. * the search can be restricted to a smaller range then defiend by 'end'.
  2823. */
  2824. int auto_correlate(int start,int *at,int end,int realend,int minlen,double pitchseg,int kk,dataptr dz)
  2825. {
  2826. float *buf = dz->sampbuf[0];
  2827. int startbuf = 0, startinbuf, atinbuf, orig_atinbuf, maxinbuf, n, m, oldlen, newlen;
  2828. int newlen2=0, atinbuf2, orig_maxinbuf;
  2829. double max_auto, max_auto2, thisauto, time;
  2830. int finished, unpitched = 0, extended = 0;
  2831. if(end > dz->total_samps_read) {
  2832. if((sndseekEx(dz->ifd[kk],start,0)<0)){
  2833. sprintf(errstr,"sndseek() failed\n");
  2834. return SYSTEM_ERROR;
  2835. }
  2836. dz->total_samps_read = start;
  2837. dz->samps_left = dz->insams[kk] - start;
  2838. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[0], dz->buflen,dz->ifd[kk],0)) < 0) {
  2839. sprintf(errstr,"Can't read samples from input soundfile %d\n",kk+1);
  2840. return(SYSTEM_ERROR);
  2841. }
  2842. dz->total_samps_read += dz->ssampsread;
  2843. dz->samps_left -= dz->ssampsread;
  2844. }
  2845. //NEW
  2846. startbuf = dz->total_samps_read - dz->ssampsread;
  2847. startinbuf = start - startbuf;
  2848. atinbuf = *at - startbuf;
  2849. maxinbuf = end - startbuf;
  2850. orig_atinbuf = atinbuf;
  2851. orig_maxinbuf = maxinbuf;
  2852. finished = 0;
  2853. // oldlen = *at - startinbuf;
  2854. oldlen = atinbuf - startinbuf;
  2855. do {
  2856. while(!finished) {
  2857. atinbuf2 = -1;
  2858. n = startinbuf;
  2859. m = startinbuf + minlen;
  2860. m = next_down_zcross(m,maxinbuf,buf); /* starting with a segment which ends at first down_zcross after minlen */
  2861. if(m > maxinbuf || m < 0)
  2862. break;
  2863. max_auto = autocorrelate(n,m,buf); /* autocorrelate two minsize segments */
  2864. max_auto2 = max_auto;
  2865. atinbuf = m;
  2866. for(;;) { /* gradually expand size to next (etc) down_zcross, & autocorrelate */
  2867. if((m = next_down_zcross(m,maxinbuf,buf)) < 0)
  2868. break;
  2869. if((thisauto = autocorrelate(n,m,buf)) > max_auto) {
  2870. max_auto = thisauto;
  2871. atinbuf = m;
  2872. } else if(thisauto > max_auto2) {
  2873. max_auto2 = thisauto;
  2874. atinbuf2 = m; /* Save best and 2nd best lengths (tested by correlation) */
  2875. }
  2876. }
  2877. if(pitchseg < 0.0) { /* If an unpitched seg, use closest pitch to set arbitrary 'ideal' seg size */
  2878. unpitched = 1;
  2879. time = (double)(*at)/(double)dz->infile->srate;
  2880. pitchseg = (double)read_validpitch_wsize_in_samps_from_brktable(time,kk,dz);
  2881. }
  2882. newlen = atinbuf - startinbuf;
  2883. if(atinbuf2 >= 0)
  2884. newlen2 = atinbuf2 - startinbuf;
  2885. *at = atinbuf + startbuf; /* Compare best-correlated cuts, with existing cut */
  2886. if(fabs((double)newlen - pitchseg) <= fabs((double)oldlen - pitchseg)) {
  2887. if(atinbuf2 >= 0) { /* If 2nd best correlation point exists & is closer to pitch than best, use it */
  2888. if(fabs((double)newlen2 - pitchseg) < fabs((double)newlen - pitchseg))
  2889. *at = atinbuf2 + startbuf;
  2890. } /* Else, If best new value is closer to pitch than original: use it */
  2891. return FINISHED;
  2892. /* If best cut(s) are worse than existing cut, */
  2893. } else if(extended) { /* if already EXTENDED the search, no point in looking at smaller range */
  2894. *at = orig_atinbuf + startbuf; /* Reset, and break from inner ('while') loop */
  2895. break;
  2896. } else { /* Otherwise, set end of search to the down_zcross PRIOR to the one found */
  2897. maxinbuf = last_down_zcross(maxinbuf,startinbuf,buf);
  2898. if(maxinbuf <= 0) { /* If can't get any smaller, break from inner 'while' loop */
  2899. *at = orig_atinbuf + startbuf;
  2900. break;
  2901. } /* Otherwise continue search in 'while' loop */
  2902. }
  2903. if(unpitched)
  2904. pitchseg = -1.0;
  2905. } /* If inner loop search has failed */
  2906. if(end < realend) { /* if the search end is less than the realend of the 3segments, EXTEND the search */
  2907. maxinbuf = next_down_zcross(orig_maxinbuf,dz->buflen,buf);
  2908. if(maxinbuf < 0)
  2909. break;
  2910. end = maxinbuf + startbuf;
  2911. orig_maxinbuf = maxinbuf;
  2912. extended = 1;
  2913. }
  2914. } while(end < realend);
  2915. return FINISHED;
  2916. }
  2917. /******************************** AUTOCORRELATE ********************************/
  2918. double autocorrelate(int n,int m,float *buf)
  2919. {
  2920. int j, k;
  2921. double sum = 0.0;
  2922. for(j = n,k = m;j<m;j++,k++)
  2923. sum += (buf[j] * buf[k]);
  2924. sum = sum/(double)(m-n);
  2925. return sum;
  2926. }
  2927. /******************************** NEXT_DOWN_ZCROSS ********************************/
  2928. int next_down_zcross(int here,int hibound,float *buf)
  2929. {
  2930. double val = buf[here];
  2931. while(val <= 0.0) {
  2932. here++;
  2933. if(here >= hibound)
  2934. return -1;
  2935. val = buf[here];
  2936. }
  2937. while(val > 0.0) {
  2938. here++;
  2939. if(here >= hibound)
  2940. return -1;
  2941. val = buf[here];
  2942. }
  2943. return here;
  2944. }
  2945. /******************************** LAST_DOWN_ZCROSS ********************************/
  2946. int last_down_zcross(int here,int lobound,float *buf)
  2947. {
  2948. double val = buf[here];
  2949. while(val <= 0.0) {
  2950. here--;
  2951. if(here < lobound)
  2952. return -1;
  2953. val = buf[here];
  2954. }
  2955. while(val >= 0.0) {
  2956. here--;
  2957. if(here < lobound)
  2958. return -1;
  2959. val = buf[here];
  2960. }
  2961. while(val < 0.0) {
  2962. here--;
  2963. if(here < lobound)
  2964. return -1;
  2965. val = buf[here];
  2966. }
  2967. here++;
  2968. return here;
  2969. }