specross.c 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415
  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 <pnames.h>
  25. #include <speccon.h>
  26. #include <standalone.h>
  27. #include <tkglobals.h>
  28. //#include <blur.h>
  29. #include <filetype.h>
  30. #include <modeno.h>
  31. //#include <formants.h>
  32. #include <cdpmain.h>
  33. //#include <special.h>
  34. #include <logic.h>
  35. #include <globcon.h>
  36. #include <cdpmain.h>
  37. #include <sfsys.h>
  38. #include <osbind.h>
  39. #include <ctype.h>
  40. #include <string.h>
  41. #if defined unix || defined __GNUC__
  42. #define round(x) lround((x))
  43. #endif
  44. #ifndef HUGE
  45. #define HUGE 3.40282347e+38F
  46. #endif
  47. static int check_consistency_of_pitch_params(dataptr dz);
  48. static int specpitch_preprocess(dataptr dz);
  49. static int spectral_interp_on_pitch(dataptr dz);
  50. static int extract_pitch_and_harmonics(int fileno,double minfrq,dataptr dz);
  51. static int get_atk_time(float *hratios,int maxharmonics,dataptr dz);
  52. static int interp_spectra(int atk_window,dataptr dz);
  53. static int specpitch(float *pichstor,dataptr dz);
  54. static int extract_harmonic_contour(float fundamental,float *thishratios,dataptr dz);
  55. static int pitch_and_harms_interp(int maxharmonics,double minfrq,float *hratios,float *pichstor,int wlen,int fileno,dataptr dz);
  56. static int close_to_frq_already_in_ring(chvptr *there,double frq1,dataptr dz);
  57. static int substitute_in_ring(int vc,chvptr here,chvptr there,dataptr dz);
  58. static int insert_in_ring(int vc, chvptr here, dataptr dz);
  59. static int put_ring_frqs_in_ascending_order(chvptr **partials,float *minamp,dataptr dz);
  60. static int found_pitch(chvptr *partials,double lo_loud_partial,double hi_loud_partial,float minamp,dataptr dz);
  61. static int smooth_spurious_octave_leaps(float *pichstor,int pitchno,float minamp,dataptr dz);
  62. static int equivalent_pitches(double frq1, double frq2, dataptr dz);
  63. static int is_peak_at(double frq,int window_offset,float minamp,dataptr dz);
  64. static int enough_partials_are_harmonics(chvptr *partials,dataptr dz);
  65. static int local_peak(int thiscc,double frq, float *thisbuf, dataptr dz);
  66. static int is_a_harmonic(double frq1,double frq2,dataptr dz);
  67. static int spec_interp(int outwinno,dataptr dz);
  68. static float get_newlevel(int outwinno,int harmno,int ampchan,dataptr dz);
  69. static int amplitude_scaling(int atk_window,dataptr dz);
  70. static int last_window_in_peak(int peak);
  71. char errstr[2400];
  72. const char* cdp_version = "7.1.0";
  73. /* extern */ int sloom = 0;
  74. /* extern */ int sloombatch = 0;
  75. /* extern */ int anal_infiles = 1;
  76. /* extern */ int is_converted_to_stereo = -1;
  77. /* CDP LIBRARY FUNCTIONS TRANSFERRED HERE */
  78. static int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist);
  79. static int set_vflgs(aplptr ap,char *optflags,int optcnt,char *optlist,
  80. char *varflags,int vflagcnt, int vparamcnt,char *varlist);
  81. static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz);
  82. static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz);
  83. static int mark_parameter_types(dataptr dz,aplptr ap);
  84. static int establish_application(dataptr dz);
  85. static int application_init(dataptr dz);
  86. static int initialise_vflags(dataptr dz);
  87. static int setup_input_param_defaultval_stores(int tipc,aplptr ap);
  88. static int setup_and_init_input_param_activity(dataptr dz,int tipc);
  89. static int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q);
  90. static int assign_file_data_storage(int infilecnt,dataptr dz);
  91. //static int store_wordlist(char *filename,dataptr dz);
  92. static int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt);
  93. static int extend_stable_pitch_to_start(dataptr dz);
  94. /* CDP LIB FUNCTION MODIFIED TO AVOID CALLING setup_particular_application() */
  95. static int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz);
  96. /* SIMPLIFICATION OF LIB FUNC TO APPLY TO JUST THIS FUNCTION */
  97. static int parse_infile_and_check_type(char **cmdline,dataptr dz);
  98. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz);
  99. static int setup_specross_application(dataptr dz);
  100. static int setup_specross_param_ranges_and_defaults(dataptr dz);
  101. static int open_the_first_infile(char *filename,dataptr dz);
  102. static int handle_the_extra_infiles(char ***cmdline,int *cmdlinecnt,dataptr dz);
  103. /* BYPASS LIBRARY GLOBAL FUNCTION TO GO DIRECTLY TO SPECIFIC APPLIC FUNCTIONS */
  104. //static int do_analjoin(dataptr dz) ;
  105. /**************************************** MAIN *********************************************/
  106. int main(int argc,char *argv[])
  107. {
  108. int exit_status;
  109. /* FILE *fp = NULL; */
  110. dataptr dz = NULL;
  111. // char *special_data_string = NULL;
  112. char **cmdline;
  113. int cmdlinecnt;
  114. // aplptr ap;
  115. int is_launched = FALSE;
  116. /* CHECK FOR SOUNDLOOM */
  117. //TW UPDATE
  118. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  119. fprintf(stdout,"%s\n",cdp_version);
  120. fflush(stdout);
  121. return 0;
  122. }
  123. if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  124. sloom = 0;
  125. sloombatch = 1;
  126. }
  127. if(sflinit("cdp")){
  128. sfperror("cdp: initialisation\n");
  129. return(FAILED);
  130. }
  131. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  132. if((exit_status = establish_datastructure(&dz))<0) {
  133. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  134. return(FAILED);
  135. }
  136. if(!sloom) {
  137. /* INITIAL CHECK OF CMDLINE DATA */
  138. if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) {
  139. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  140. return(FAILED);
  141. }
  142. cmdline = argv; /* GET PRE_DATA, ALLOCATE THE APPLICATION, CHECK FOR EXTRA INFILES */
  143. cmdlinecnt = argc;
  144. // get_process_and_mode_from_cmdline -->
  145. if (!strcmp(argv[0],"partials")) {
  146. dz->process = SPECROSS;
  147. dz->mode = 0;
  148. } else
  149. usage1();
  150. cmdline++;
  151. cmdlinecnt--;
  152. // THERE IS NO MODE WITH THIS PROGRAM
  153. // setup_particular_application =
  154. if((exit_status = setup_specross_application(dz))<0) {
  155. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  156. return(FAILED);
  157. }
  158. if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) {
  159. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  160. return(FAILED);
  161. }
  162. } else {
  163. //parse_TK_data() =
  164. if((exit_status = parse_sloom_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) { /* includes setup_particular_application() */
  165. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);/* and cmdlinelength check = sees extra-infiles */
  166. return(exit_status);
  167. }
  168. }
  169. // ap = dz->application;
  170. // parse_infile_and_hone_type() =
  171. if((exit_status = parse_infile_and_check_type(cmdline,dz))<0) {
  172. exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  173. return(FAILED);
  174. }
  175. // setup_param_ranges_and_defaults = MOVED IN THIS CASE ONLY TO LATER
  176. /* OPEN FIRST INFILE AND STORE DATA, AND INFORMATION, APPROPRIATELY */
  177. if((exit_status = open_the_first_infile(cmdline[0],dz))<0) {
  178. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  179. return(FAILED);
  180. }
  181. cmdlinecnt--;
  182. cmdline++;
  183. if((exit_status = handle_the_extra_infiles(&cmdline,&cmdlinecnt,dz))<0) {
  184. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  185. return(FAILED);
  186. }
  187. if((exit_status = setup_specross_param_ranges_and_defaults(dz))<0) {
  188. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  189. return(FAILED);
  190. }
  191. // FOR display_virutal_time
  192. dz->tempsize = dz->insams[1];
  193. // handle_outfile
  194. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,is_launched,dz))<0) {
  195. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  196. return(FAILED);
  197. }
  198. // handle_formants
  199. // handle_formant_quiksearch
  200. // handle_special_data
  201. if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) { // CDP LIB
  202. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  203. return(FAILED);
  204. }
  205. // check_param_validity_and_consistency =
  206. if((exit_status = check_consistency_of_pitch_params(dz))<0) {
  207. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  208. return(FAILED);
  209. }
  210. is_launched = TRUE;
  211. if((exit_status = allocate_triple_buffer(dz))<0){
  212. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  213. return(FAILED);
  214. }
  215. // param_preprocess =
  216. if((exit_status = specpitch_preprocess(dz))<0){
  217. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  218. return(FAILED);
  219. }
  220. // spec_process_file
  221. if((exit_status = spectral_interp_on_pitch(dz))<0) {
  222. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  223. return(FAILED);
  224. }
  225. if((exit_status = complete_output(dz))<0) {
  226. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  227. return(FAILED);
  228. }
  229. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz);
  230. free(dz);
  231. return(SUCCEEDED);
  232. }
  233. /**********************************************
  234. REPLACED CDP LIB FUNCTIONS
  235. **********************************************/
  236. /****************************** SET_PARAM_DATA *********************************/
  237. int set_param_data(aplptr ap, int special_data,int maxparamcnt,int paramcnt,char *paramlist)
  238. {
  239. ap->special_data = (char)special_data;
  240. ap->param_cnt = (char)paramcnt;
  241. ap->max_param_cnt = (char)maxparamcnt;
  242. if(ap->max_param_cnt>0) {
  243. if((ap->param_list = (char *)malloc((size_t)(ap->max_param_cnt+1)))==NULL) {
  244. sprintf(errstr,"INSUFFICIENT MEMORY: for param_list\n");
  245. return(MEMORY_ERROR);
  246. }
  247. strcpy(ap->param_list,paramlist);
  248. }
  249. return(FINISHED);
  250. }
  251. /****************************** SET_VFLGS *********************************/
  252. int set_vflgs
  253. (aplptr ap,char *optflags,int optcnt,char *optlist,char *varflags,int vflagcnt, int vparamcnt,char *varlist)
  254. {
  255. ap->option_cnt = (char) optcnt; /*RWD added cast */
  256. if(optcnt) {
  257. if((ap->option_list = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  258. sprintf(errstr,"INSUFFICIENT MEMORY: for option_list\n");
  259. return(MEMORY_ERROR);
  260. }
  261. strcpy(ap->option_list,optlist);
  262. if((ap->option_flags = (char *)malloc((size_t)(optcnt+1)))==NULL) {
  263. sprintf(errstr,"INSUFFICIENT MEMORY: for option_flags\n");
  264. return(MEMORY_ERROR);
  265. }
  266. strcpy(ap->option_flags,optflags);
  267. }
  268. ap->vflag_cnt = (char) vflagcnt;
  269. ap->variant_param_cnt = (char) vparamcnt;
  270. if(vflagcnt) {
  271. if((ap->variant_list = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  272. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_list\n");
  273. return(MEMORY_ERROR);
  274. }
  275. strcpy(ap->variant_list,varlist);
  276. if((ap->variant_flags = (char *)malloc((size_t)(vflagcnt+1)))==NULL) {
  277. sprintf(errstr,"INSUFFICIENT MEMORY: for variant_flags\n");
  278. return(MEMORY_ERROR);
  279. }
  280. strcpy(ap->variant_flags,varflags);
  281. }
  282. return(FINISHED);
  283. }
  284. /***************************** APPLICATION_INIT **************************/
  285. int application_init(dataptr dz)
  286. {
  287. int exit_status;
  288. int storage_cnt, n;
  289. int tipc, brkcnt;
  290. aplptr ap = dz->application;
  291. if(ap->vflag_cnt>0)
  292. initialise_vflags(dz);
  293. tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  294. ap->total_input_param_cnt = (char)tipc;
  295. if(tipc>0) {
  296. if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  297. return(exit_status);
  298. if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  299. return(exit_status);
  300. if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  301. return(exit_status);
  302. }
  303. brkcnt = tipc;
  304. if(brkcnt>0) {
  305. if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  306. return(exit_status);
  307. }
  308. if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  309. if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  310. return(exit_status);
  311. if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  312. return(exit_status);
  313. }
  314. if((exit_status = mark_parameter_types(dz,ap))<0)
  315. return(exit_status);
  316. // establish_infile_constants() replaced by
  317. dz->infilecnt = -2; /* flags 2 or more */
  318. // establish_bufptrs_and_extra_buffers
  319. dz->extra_bufcnt = 0;
  320. dz->bptrcnt = 5;
  321. // setup_internal_arrays_and_array_pointers()
  322. dz->fptr_cnt = 2;
  323. dz->array_cnt = 5;
  324. if((dz->fptr = (float **)malloc(dz->fptr_cnt * sizeof(float *)))==NULL) {
  325. sprintf(errstr,"INSUFFICIENT MEMORY for internal float-pointer arrays.\n");
  326. return(MEMORY_ERROR);
  327. }
  328. if(dz->array_cnt > 0) {
  329. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  330. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  331. return(MEMORY_ERROR);
  332. }
  333. for(n=0;n<dz->array_cnt;n++)
  334. dz->parray[n] = NULL;
  335. }
  336. for(n=0;n<dz->fptr_cnt;n++)
  337. dz->fptr[n] = NULL;
  338. return establish_spec_bufptrs_and_extra_buffers(dz);
  339. }
  340. /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/
  341. /* RWD mallo changed to calloc; helps debug verison run as release! */
  342. int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz)
  343. {
  344. if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) {
  345. sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n");
  346. return(MEMORY_ERROR);
  347. }
  348. if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) {
  349. sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n");
  350. return(MEMORY_ERROR);
  351. }
  352. if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  353. sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n");
  354. return(MEMORY_ERROR);
  355. }
  356. if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) {
  357. sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n");
  358. return(MEMORY_ERROR);
  359. }
  360. return(FINISHED);
  361. }
  362. /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/
  363. int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz)
  364. {
  365. int n;
  366. for(n=0;n<storage_cnt;n++) {
  367. dz->is_int[n] = (char)0;
  368. dz->no_brk[n] = (char)0;
  369. }
  370. return(FINISHED);
  371. }
  372. /***************************** MARK_PARAMETER_TYPES **************************/
  373. int mark_parameter_types(dataptr dz,aplptr ap)
  374. {
  375. int n, m; /* PARAMS */
  376. for(n=0;n<ap->max_param_cnt;n++) {
  377. switch(ap->param_list[n]) {
  378. case('0'): break; /* dz->is_active[n] = 0 is default */
  379. case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break;
  380. case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break;
  381. case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break;
  382. case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break;
  383. default:
  384. sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n");
  385. return(PROGRAM_ERROR);
  386. }
  387. } /* OPTIONS */
  388. for(n=0,m=ap->max_param_cnt;n<ap->option_cnt;n++,m++) {
  389. switch(ap->option_list[n]) {
  390. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  391. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  392. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  393. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  394. default:
  395. sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n");
  396. return(PROGRAM_ERROR);
  397. }
  398. } /* VARIANTS */
  399. for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) {
  400. switch(ap->variant_list[n]) {
  401. case('0'): break;
  402. case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  403. case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break;
  404. case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break;
  405. case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break;
  406. default:
  407. sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n");
  408. return(PROGRAM_ERROR);
  409. }
  410. } /* INTERNAL */
  411. for(n=0,
  412. m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; n<ap->internal_param_cnt; n++,m++) {
  413. switch(ap->internal_param_list[n]) {
  414. case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */
  415. case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break;
  416. case('d'): dz->no_brk[m] = (char)1; break;
  417. default:
  418. sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n");
  419. return(PROGRAM_ERROR);
  420. }
  421. }
  422. return(FINISHED);
  423. }
  424. /***************************** ESTABLISH_APPLICATION **************************/
  425. int establish_application(dataptr dz)
  426. {
  427. aplptr ap;
  428. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  429. sprintf(errstr,"establish_application()\n");
  430. return(MEMORY_ERROR);
  431. }
  432. ap = dz->application;
  433. memset((char *)ap,0,sizeof(struct applic));
  434. return(FINISHED);
  435. }
  436. /************************* INITIALISE_VFLAGS *************************/
  437. int initialise_vflags(dataptr dz)
  438. {
  439. int n;
  440. if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) {
  441. sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n");
  442. return(MEMORY_ERROR);
  443. }
  444. for(n=0;n<dz->application->vflag_cnt;n++)
  445. dz->vflag[n] = FALSE;
  446. return FINISHED;
  447. }
  448. /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/
  449. int setup_input_param_defaultval_stores(int tipc,aplptr ap)
  450. {
  451. int n;
  452. if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) {
  453. sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n");
  454. return(MEMORY_ERROR);
  455. }
  456. for(n=0;n<tipc;n++)
  457. ap->default_val[n] = 0.0;
  458. return(FINISHED);
  459. }
  460. /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/
  461. int setup_and_init_input_param_activity(dataptr dz,int tipc)
  462. {
  463. int n;
  464. if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) {
  465. sprintf(errstr,"setup_and_init_input_param_activity()\n");
  466. return(MEMORY_ERROR);
  467. }
  468. for(n=0;n<tipc;n++)
  469. dz->is_active[n] = (char)0;
  470. return(FINISHED);
  471. }
  472. /************************* SETUP_SPECROSS_APPLICATION *******************/
  473. int setup_specross_application(dataptr dz)
  474. {
  475. int exit_status;
  476. aplptr ap;
  477. if((exit_status = establish_application(dz))<0) // GLOBAL
  478. return(FAILED);
  479. ap = dz->application;
  480. // SEE parstruct FOR EXPLANATION of next 2 functions
  481. if((exit_status = set_param_data(ap,0 ,9,9,"dididdddD" ))<0)
  482. return(FAILED);
  483. if((exit_status = set_vflgs(ap, "",0,"" ,"ap" ,2,0,"00" ))<0)
  484. return(FAILED);
  485. // THERE IS NO NEED TO set_formant_flags in this case....
  486. // Following only needed if internal params are linked to dz structure
  487. if((exit_status = set_internalparam_data("d",ap))<0)
  488. return(FAILED);
  489. // set_legal_infile_structure -->
  490. dz->has_otherfile = FALSE;
  491. // assign_process_logic -->
  492. dz->input_data_type = TWO_ANALFILES;
  493. dz->process_type = BIG_ANALFILE;
  494. dz->outfiletype = ANALFILE_OUT;
  495. return application_init(dz); //GLOBAL
  496. }
  497. /******************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS ********************************/
  498. int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt)
  499. {
  500. int n;
  501. if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  502. sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n");
  503. return(MEMORY_ERROR);
  504. }
  505. if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) {
  506. sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n");
  507. return(MEMORY_ERROR);
  508. }
  509. if((dz->brksize = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  510. sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n");
  511. return(MEMORY_ERROR);
  512. }
  513. if((dz->firstval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  514. sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n");
  515. return(MEMORY_ERROR);
  516. }
  517. if((dz->lastind = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  518. sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n");
  519. return(MEMORY_ERROR);
  520. }
  521. if((dz->lastval = (double *)malloc(brkcnt * sizeof(double)))==NULL) {
  522. sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n");
  523. return(MEMORY_ERROR);
  524. }
  525. if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int)))==NULL) {
  526. sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n");
  527. return(MEMORY_ERROR);
  528. }
  529. for(n=0;n<brkcnt;n++) {
  530. dz->brk[n] = NULL;
  531. dz->brkptr[n] = NULL;
  532. dz->brkinit[n] = 0;
  533. dz->brksize[n] = 0;
  534. }
  535. return(FINISHED);
  536. }
  537. /************************* PARSE_INFILE_AND_CHECK_TYPE *******************/
  538. int parse_infile_and_check_type(char **cmdline,dataptr dz)
  539. {
  540. int exit_status;
  541. infileptr infile_info;
  542. if(!sloom) {
  543. if((infile_info = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  544. sprintf(errstr,"INSUFFICIENT MEMORY for infile structure to test file data.");
  545. return(MEMORY_ERROR);
  546. } else if((exit_status = cdparse(cmdline[0],infile_info))<0) {
  547. sprintf(errstr,"Failed tp parse input file %s\n",cmdline[0]);
  548. return(PROGRAM_ERROR);
  549. } else if(infile_info->filetype != ANALFILE) {
  550. sprintf(errstr,"File %s is not of correct type\n",cmdline[0]);
  551. return(DATA_ERROR);
  552. } else if((exit_status = copy_parse_info_to_main_structure(infile_info,dz))<0) {
  553. sprintf(errstr,"Failed to copy file parsing information\n");
  554. return(PROGRAM_ERROR);
  555. }
  556. free(infile_info);
  557. }
  558. if((exit_status = set_chunklens_and_establish_windowbufs(dz))<0)
  559. return(exit_status);
  560. return(FINISHED);
  561. }
  562. /************************* SETUP_SPECROSS_PARAM_RANGES_AND_DEFAULTS *******************/
  563. int setup_specross_param_ranges_and_defaults(dataptr dz)
  564. {
  565. int exit_status;
  566. aplptr ap = dz->application;
  567. // set_param_ranges()
  568. ap->total_input_param_cnt = (char)(ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt);
  569. // setup_input_param_range_stores()
  570. if((exit_status = setup_input_param_range_stores(ap->total_input_param_cnt,ap))<0)
  571. return(FAILED);
  572. // get_param_ranges()
  573. ap->lo[PICH_RNGE] = 0.0;
  574. ap->hi[PICH_RNGE] = 6.0;
  575. ap->default_val[PICH_RNGE] = 1.0;
  576. ap->lo[PICH_VALID] = 0.0;
  577. ap->hi[PICH_VALID] = (double)min(dz->wlength,dz->insams[1]/dz->wanted);;
  578. ap->default_val[PICH_VALID] = (double)BLIPLEN;
  579. ap->lo[PICH_SRATIO] = 0.0;
  580. ap->hi[PICH_SRATIO] = SIGNOIS_MAX;
  581. ap->default_val[PICH_SRATIO]= SILENCE_RATIO;
  582. ap->lo[PICH_MATCH] = 1.0;
  583. ap->hi[PICH_MATCH] = (double)MAXIMI;
  584. ap->default_val[PICH_MATCH] = (double)ACCEPTABLE_MATCH;
  585. ap->lo[PICH_HILM] = SPEC_MINFRQ;
  586. ap->hi[PICH_HILM] = dz->nyquist/MAXIMI;
  587. ap->default_val[PICH_HILM] = dz->nyquist/MAXIMI;
  588. ap->lo[PICH_LOLM] = SPEC_MINFRQ;
  589. ap->hi[PICH_LOLM] = dz->nyquist/MAXIMI;
  590. ap->default_val[PICH_LOLM] = SPEC_MINFRQ;
  591. ap->lo[PICH_THRESH] = 0.0;
  592. ap->hi[PICH_THRESH] = 1.0;
  593. ap->default_val[PICH_THRESH]= .02;
  594. ap->lo[SPCMPLEV] = 0.0;
  595. ap->hi[SPCMPLEV] = 1.0;
  596. ap->default_val[SPCMPLEV] = 1.0;
  597. ap->lo[SPECHINT] = 0.0;
  598. ap->hi[SPECHINT] = 1.0;
  599. ap->default_val[SPECHINT] = 1.0;
  600. dz->maxmode = 0;
  601. if(!sloom)
  602. put_default_vals_in_all_params(dz);
  603. return(FINISHED);
  604. // initialise_param_values()
  605. return(FINISHED);
  606. }
  607. /********************************* PARSE_SLOOM_DATA *********************************/
  608. int parse_sloom_data(int argc,char *argv[],char ***cmdline,int *cmdlinecnt,dataptr dz)
  609. {
  610. int exit_status;
  611. int cnt = 1, infilecnt;
  612. int filesize, insams, inbrksize;
  613. double dummy;
  614. int true_cnt = 0;
  615. // aplptr ap;
  616. while(cnt<=PRE_CMDLINE_DATACNT) {
  617. if(cnt > argc) {
  618. sprintf(errstr,"Insufficient data sent from TK\n");
  619. return(DATA_ERROR);
  620. }
  621. switch(cnt) {
  622. case(1):
  623. if(sscanf(argv[cnt],"%d",&dz->process)!=1) {
  624. sprintf(errstr,"Cannot read process no. sent from TK\n");
  625. return(DATA_ERROR);
  626. }
  627. break;
  628. case(2):
  629. if(sscanf(argv[cnt],"%d",&dz->mode)!=1) {
  630. sprintf(errstr,"Cannot read mode no. sent from TK\n");
  631. return(DATA_ERROR);
  632. }
  633. if(dz->mode > 0)
  634. dz->mode--;
  635. //setup_particular_application() =
  636. if((exit_status = setup_specross_application(dz))<0)
  637. return(exit_status);
  638. // ap = dz->application;
  639. break;
  640. case(3):
  641. if(sscanf(argv[cnt],"%d",&infilecnt)!=1) {
  642. sprintf(errstr,"Cannot read infilecnt sent from TK\n");
  643. return(DATA_ERROR);
  644. }
  645. if(infilecnt < 1) {
  646. true_cnt = cnt + 1;
  647. cnt = PRE_CMDLINE_DATACNT; /* force exit from loop after assign_file_data_storage */
  648. }
  649. if((exit_status = assign_file_data_storage(infilecnt,dz))<0)
  650. return(exit_status);
  651. break;
  652. case(INPUT_FILETYPE+4):
  653. if(sscanf(argv[cnt],"%d",&dz->infile->filetype)!=1) {
  654. sprintf(errstr,"Cannot read filetype sent from TK (%s)\n",argv[cnt]);
  655. return(DATA_ERROR);
  656. }
  657. break;
  658. case(INPUT_FILESIZE+4):
  659. if(sscanf(argv[cnt],"%d",&filesize)!=1) {
  660. sprintf(errstr,"Cannot read infilesize sent from TK\n");
  661. return(DATA_ERROR);
  662. }
  663. dz->insams[0] = filesize;
  664. break;
  665. case(INPUT_INSAMS+4):
  666. if(sscanf(argv[cnt],"%d",&insams)!=1) {
  667. sprintf(errstr,"Cannot read insams sent from TK\n");
  668. return(DATA_ERROR);
  669. }
  670. dz->insams[0] = insams;
  671. break;
  672. case(INPUT_SRATE+4):
  673. if(sscanf(argv[cnt],"%d",&dz->infile->srate)!=1) {
  674. sprintf(errstr,"Cannot read srate sent from TK\n");
  675. return(DATA_ERROR);
  676. }
  677. break;
  678. case(INPUT_CHANNELS+4):
  679. if(sscanf(argv[cnt],"%d",&dz->infile->channels)!=1) {
  680. sprintf(errstr,"Cannot read channels sent from TK\n");
  681. return(DATA_ERROR);
  682. }
  683. break;
  684. case(INPUT_STYPE+4):
  685. if(sscanf(argv[cnt],"%d",&dz->infile->stype)!=1) {
  686. sprintf(errstr,"Cannot read stype sent from TK\n");
  687. return(DATA_ERROR);
  688. }
  689. break;
  690. case(INPUT_ORIGSTYPE+4):
  691. if(sscanf(argv[cnt],"%d",&dz->infile->origstype)!=1) {
  692. sprintf(errstr,"Cannot read origstype sent from TK\n");
  693. return(DATA_ERROR);
  694. }
  695. break;
  696. case(INPUT_ORIGRATE+4):
  697. if(sscanf(argv[cnt],"%d",&dz->infile->origrate)!=1) {
  698. sprintf(errstr,"Cannot read origrate sent from TK\n");
  699. return(DATA_ERROR);
  700. }
  701. break;
  702. case(INPUT_MLEN+4):
  703. if(sscanf(argv[cnt],"%d",&dz->infile->Mlen)!=1) {
  704. sprintf(errstr,"Cannot read Mlen sent from TK\n");
  705. return(DATA_ERROR);
  706. }
  707. break;
  708. case(INPUT_DFAC+4):
  709. if(sscanf(argv[cnt],"%d",&dz->infile->Dfac)!=1) {
  710. sprintf(errstr,"Cannot read Dfac sent from TK\n");
  711. return(DATA_ERROR);
  712. }
  713. break;
  714. case(INPUT_ORIGCHANS+4):
  715. if(sscanf(argv[cnt],"%d",&dz->infile->origchans)!=1) {
  716. sprintf(errstr,"Cannot read origchans sent from TK\n");
  717. return(DATA_ERROR);
  718. }
  719. break;
  720. case(INPUT_SPECENVCNT+4):
  721. if(sscanf(argv[cnt],"%d",&dz->infile->specenvcnt)!=1) {
  722. sprintf(errstr,"Cannot read specenvcnt sent from TK\n");
  723. return(DATA_ERROR);
  724. }
  725. dz->specenvcnt = dz->infile->specenvcnt;
  726. break;
  727. case(INPUT_WANTED+4):
  728. if(sscanf(argv[cnt],"%d",&dz->wanted)!=1) {
  729. sprintf(errstr,"Cannot read wanted sent from TK\n");
  730. return(DATA_ERROR);
  731. }
  732. break;
  733. case(INPUT_WLENGTH+4):
  734. if(sscanf(argv[cnt],"%d",&dz->wlength)!=1) {
  735. sprintf(errstr,"Cannot read wlength sent from TK\n");
  736. return(DATA_ERROR);
  737. }
  738. break;
  739. case(INPUT_OUT_CHANS+4):
  740. if(sscanf(argv[cnt],"%d",&dz->out_chans)!=1) {
  741. sprintf(errstr,"Cannot read out_chans sent from TK\n");
  742. return(DATA_ERROR);
  743. }
  744. break;
  745. /* RWD these chanegs to samps - tk will have to deal with that! */
  746. case(INPUT_DESCRIPTOR_BYTES+4):
  747. if(sscanf(argv[cnt],"%d",&dz->descriptor_samps)!=1) {
  748. sprintf(errstr,"Cannot read descriptor_samps sent from TK\n");
  749. return(DATA_ERROR);
  750. }
  751. break;
  752. case(INPUT_IS_TRANSPOS+4):
  753. if(sscanf(argv[cnt],"%d",&dz->is_transpos)!=1) {
  754. sprintf(errstr,"Cannot read is_transpos sent from TK\n");
  755. return(DATA_ERROR);
  756. }
  757. break;
  758. case(INPUT_COULD_BE_TRANSPOS+4):
  759. if(sscanf(argv[cnt],"%d",&dz->could_be_transpos)!=1) {
  760. sprintf(errstr,"Cannot read could_be_transpos sent from TK\n");
  761. return(DATA_ERROR);
  762. }
  763. break;
  764. case(INPUT_COULD_BE_PITCH+4):
  765. if(sscanf(argv[cnt],"%d",&dz->could_be_pitch)!=1) {
  766. sprintf(errstr,"Cannot read could_be_pitch sent from TK\n");
  767. return(DATA_ERROR);
  768. }
  769. break;
  770. case(INPUT_DIFFERENT_SRATES+4):
  771. if(sscanf(argv[cnt],"%d",&dz->different_srates)!=1) {
  772. sprintf(errstr,"Cannot read different_srates sent from TK\n");
  773. return(DATA_ERROR);
  774. }
  775. break;
  776. case(INPUT_DUPLICATE_SNDS+4):
  777. if(sscanf(argv[cnt],"%d",&dz->duplicate_snds)!=1) {
  778. sprintf(errstr,"Cannot read duplicate_snds sent from TK\n");
  779. return(DATA_ERROR);
  780. }
  781. break;
  782. case(INPUT_BRKSIZE+4):
  783. if(sscanf(argv[cnt],"%d",&inbrksize)!=1) {
  784. sprintf(errstr,"Cannot read brksize sent from TK\n");
  785. return(DATA_ERROR);
  786. }
  787. if(inbrksize > 0) {
  788. switch(dz->input_data_type) {
  789. case(WORDLIST_ONLY):
  790. break;
  791. case(PITCH_AND_PITCH):
  792. case(PITCH_AND_TRANSPOS):
  793. case(TRANSPOS_AND_TRANSPOS):
  794. dz->tempsize = inbrksize;
  795. break;
  796. case(BRKFILES_ONLY):
  797. case(UNRANGED_BRKFILE_ONLY):
  798. case(DB_BRKFILES_ONLY):
  799. case(ALL_FILES):
  800. case(ANY_NUMBER_OF_ANY_FILES):
  801. if(dz->extrabrkno < 0) {
  802. sprintf(errstr,"Storage location number for brktable not established by CDP.\n");
  803. return(DATA_ERROR);
  804. }
  805. if(dz->brksize == NULL) {
  806. sprintf(errstr,"CDP has not established storage space for input brktable.\n");
  807. return(PROGRAM_ERROR);
  808. }
  809. dz->brksize[dz->extrabrkno] = inbrksize;
  810. break;
  811. default:
  812. sprintf(errstr,"TK sent brktablesize > 0 for input_data_type [%d] not using brktables.\n",
  813. dz->input_data_type);
  814. return(PROGRAM_ERROR);
  815. }
  816. break;
  817. }
  818. break;
  819. case(INPUT_NUMSIZE+4):
  820. if(sscanf(argv[cnt],"%d",&dz->numsize)!=1) {
  821. sprintf(errstr,"Cannot read numsize sent from TK\n");
  822. return(DATA_ERROR);
  823. }
  824. break;
  825. case(INPUT_LINECNT+4):
  826. if(sscanf(argv[cnt],"%d",&dz->linecnt)!=1) {
  827. sprintf(errstr,"Cannot read linecnt sent from TK\n");
  828. return(DATA_ERROR);
  829. }
  830. break;
  831. case(INPUT_ALL_WORDS+4):
  832. if(sscanf(argv[cnt],"%d",&dz->all_words)!=1) {
  833. sprintf(errstr,"Cannot read all_words sent from TK\n");
  834. return(DATA_ERROR);
  835. }
  836. break;
  837. case(INPUT_ARATE+4):
  838. if(sscanf(argv[cnt],"%f",&dz->infile->arate)!=1) {
  839. sprintf(errstr,"Cannot read arate sent from TK\n");
  840. return(DATA_ERROR);
  841. }
  842. break;
  843. case(INPUT_FRAMETIME+4):
  844. if(sscanf(argv[cnt],"%lf",&dummy)!=1) {
  845. sprintf(errstr,"Cannot read frametime sent from TK\n");
  846. return(DATA_ERROR);
  847. }
  848. dz->frametime = (float)dummy;
  849. break;
  850. case(INPUT_WINDOW_SIZE+4):
  851. if(sscanf(argv[cnt],"%f",&dz->infile->window_size)!=1) {
  852. sprintf(errstr,"Cannot read window_size sent from TK\n");
  853. return(DATA_ERROR);
  854. }
  855. break;
  856. case(INPUT_NYQUIST+4):
  857. if(sscanf(argv[cnt],"%lf",&dz->nyquist)!=1) {
  858. sprintf(errstr,"Cannot read nyquist sent from TK\n");
  859. return(DATA_ERROR);
  860. }
  861. break;
  862. case(INPUT_DURATION+4):
  863. if(sscanf(argv[cnt],"%lf",&dz->duration)!=1) {
  864. sprintf(errstr,"Cannot read duration sent from TK\n");
  865. return(DATA_ERROR);
  866. }
  867. break;
  868. case(INPUT_MINBRK+4):
  869. if(sscanf(argv[cnt],"%lf",&dz->minbrk)!=1) {
  870. sprintf(errstr,"Cannot read minbrk sent from TK\n");
  871. return(DATA_ERROR);
  872. }
  873. break;
  874. case(INPUT_MAXBRK+4):
  875. if(sscanf(argv[cnt],"%lf",&dz->maxbrk)!=1) {
  876. sprintf(errstr,"Cannot read maxbrk sent from TK\n");
  877. return(DATA_ERROR);
  878. }
  879. break;
  880. case(INPUT_MINNUM+4):
  881. if(sscanf(argv[cnt],"%lf",&dz->minnum)!=1) {
  882. sprintf(errstr,"Cannot read minnum sent from TK\n");
  883. return(DATA_ERROR);
  884. }
  885. break;
  886. case(INPUT_MAXNUM+4):
  887. if(sscanf(argv[cnt],"%lf",&dz->maxnum)!=1) {
  888. sprintf(errstr,"Cannot read maxnum sent from TK\n");
  889. return(DATA_ERROR);
  890. }
  891. break;
  892. default:
  893. sprintf(errstr,"case switch item missing: parse_sloom_data()\n");
  894. return(PROGRAM_ERROR);
  895. }
  896. cnt++;
  897. }
  898. if(cnt!=PRE_CMDLINE_DATACNT+1) {
  899. sprintf(errstr,"Insufficient pre-cmdline params sent from TK\n");
  900. return(DATA_ERROR);
  901. }
  902. if(true_cnt)
  903. cnt = true_cnt;
  904. *cmdlinecnt = 0;
  905. while(cnt < argc) {
  906. if((exit_status = get_tk_cmdline_word(cmdlinecnt,cmdline,argv[cnt]))<0)
  907. return(exit_status);
  908. cnt++;
  909. }
  910. return(FINISHED);
  911. }
  912. /********************************* GET_TK_CMDLINE_WORD *********************************/
  913. int get_tk_cmdline_word(int *cmdlinecnt,char ***cmdline,char *q)
  914. {
  915. if(*cmdlinecnt==0) {
  916. if((*cmdline = (char **)malloc(sizeof(char *)))==NULL) {
  917. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  918. return(MEMORY_ERROR);
  919. }
  920. } else {
  921. if((*cmdline = (char **)realloc(*cmdline,((*cmdlinecnt)+1) * sizeof(char *)))==NULL) {
  922. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline array.\n");
  923. return(MEMORY_ERROR);
  924. }
  925. }
  926. if(((*cmdline)[*cmdlinecnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  927. sprintf(errstr,"INSUFFICIENT MEMORY for TK cmdline item %d.\n",(*cmdlinecnt)+1);
  928. return(MEMORY_ERROR);
  929. }
  930. strcpy((*cmdline)[*cmdlinecnt],q);
  931. (*cmdlinecnt)++;
  932. return(FINISHED);
  933. }
  934. /****************************** ASSIGN_FILE_DATA_STORAGE *********************************/
  935. int assign_file_data_storage(int infilecnt,dataptr dz)
  936. {
  937. int exit_status;
  938. int no_sndfile_system_files = FALSE;
  939. dz->infilecnt = infilecnt;
  940. if((exit_status = allocate_filespace(dz))<0)
  941. return(exit_status);
  942. if(no_sndfile_system_files)
  943. dz->infilecnt = 0;
  944. return(FINISHED);
  945. }
  946. /************************** OPEN_THE_FIRST_INFILE *****************************/
  947. int open_the_first_infile(char *filename,dataptr dz)
  948. {
  949. if((dz->ifd[0] = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
  950. sprintf(errstr,"Failure to open file %s for input.\n",filename);
  951. return(SYSTEM_ERROR);
  952. }
  953. if(dz->infilecnt<=0 || dz->infile->filetype!=ANALFILE) {
  954. sprintf(errstr,"%s is wrong type of file for this process.\n",filename);
  955. return(DATA_ERROR);
  956. }
  957. dz->samps_left = dz->insams[0];
  958. return(FINISHED);
  959. }
  960. /************************ HANDLE_THE_EXTRA_INFILES *********************/
  961. int handle_the_extra_infiles(char ***cmdline,int *cmdlinecnt,dataptr dz)
  962. {
  963. /* OPEN ANY FURTHER INFILES, CHECK COMPATIBILITY, STORE DATA AND INFO */
  964. int exit_status, n;
  965. char *filename;
  966. if(dz->infilecnt > 1) {
  967. for(n=1;n<dz->infilecnt;n++) {
  968. filename = (*cmdline)[0];
  969. if((exit_status = handle_other_infile(n,filename,dz))<0)
  970. return(exit_status);
  971. (*cmdline)++;
  972. (*cmdlinecnt)--;
  973. }
  974. } else {
  975. sprintf(errstr,"Insufficient input files for this process\n");
  976. return(DATA_ERROR);
  977. }
  978. return(FINISHED);
  979. }
  980. /************************ HANDLE_THE_OUTFILE *********************/
  981. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,int is_launched,dataptr dz)
  982. {
  983. char *filename = NULL;
  984. int n;
  985. int stype = SAMP_FLOAT;
  986. if(sloom) {
  987. filename = (*cmdline)[0];
  988. } else {
  989. if(*cmdlinecnt<=0) {
  990. sprintf(errstr,"Insufficient cmdline parameters.\n");
  991. return(USAGE_ONLY);
  992. }
  993. filename = (*cmdline)[0];
  994. if(filename[0]=='-' && filename[1]=='f') {
  995. sprintf(errstr,"-f flag used incorrectly on command line (output is not a sound file).\n");
  996. return(USAGE_ONLY);
  997. }
  998. if(file_has_invalid_startchar(filename) || value_is_numeric(filename)) {
  999. sprintf(errstr,"Outfile name %s has invalid start character(s) or looks too much like a number.\n",filename);
  1000. return(DATA_ERROR);
  1001. }
  1002. }
  1003. dz->true_outfile_stype = stype;
  1004. dz->outfilesize = dz->insams[1]; /* With specros, outfile is always size of 2nd infile */
  1005. if((dz->ofd = sndcreat_formatted(filename,dz->outfilesize,stype,
  1006. dz->infile->channels,dz->infile->srate,CDP_CREATE_NORMAL)) < 0) {
  1007. sprintf(errstr,"Cannot open output file %s\n", filename);
  1008. return(DATA_ERROR);
  1009. }
  1010. dz->outchans = dz->infile->channels;
  1011. dz->needpeaks = 1;
  1012. dz->outpeaks = (CHPEAK *) malloc(sizeof(CHPEAK) * dz->outchans);
  1013. if(dz->outpeaks==NULL)
  1014. return MEMORY_ERROR;
  1015. dz->outpeakpos = (unsigned int *) malloc(sizeof(unsigned int) * dz->outchans);
  1016. if(dz->outpeakpos==NULL)
  1017. return MEMORY_ERROR;
  1018. for(n=0;n < dz->outchans;n++){
  1019. dz->outpeaks[n].value = 0.0f;
  1020. dz->outpeaks[n].position = 0;
  1021. dz->outpeakpos[n] = 0;
  1022. }
  1023. strcpy(dz->outfilename,filename);
  1024. (*cmdline)++;
  1025. (*cmdlinecnt)--;
  1026. return(FINISHED);
  1027. }
  1028. /************ CHECK_CONSISTENCY_OF_PITCH_PARAMS *************/
  1029. int check_consistency_of_pitch_params(dataptr dz)
  1030. {
  1031. if(dz->param[PICH_HILM] <= dz->param[PICH_LOLM]) {
  1032. sprintf(errstr,"Impossible pitch range specified.\n");
  1033. return(USER_ERROR);
  1034. }
  1035. return(FINISHED);
  1036. }
  1037. /************************** SPECPITCH_PREPROCESS ******************************/
  1038. int specpitch_preprocess(dataptr dz)
  1039. {
  1040. dz->param[PICH_RNGE] = pow(SEMITONE_INTERVAL,fabs(dz->param[PICH_RNGE]));
  1041. /* convert dB to gain */
  1042. dz->param[PICH_SRATIO] /= 20.0;
  1043. dz->param[PICH_SRATIO] = pow(10.0,dz->param[PICH_SRATIO]);
  1044. dz->param[PICH_SRATIO] = 1.0/dz->param[PICH_SRATIO];
  1045. if((dz->pitches = (float *)malloc(dz->wlength * sizeof(float)))==NULL) {
  1046. sprintf(errstr,"INSUFFICIENT MEMORY for pitches array.\n");
  1047. return(MEMORY_ERROR);
  1048. }
  1049. if((dz->pitches2 = (float *)malloc((dz->insams[1]/dz->wanted) * sizeof(float)))==NULL) {
  1050. sprintf(errstr,"INSUFFICIENT MEMORY for pitches array.\n");
  1051. return(MEMORY_ERROR);
  1052. }
  1053. initrand48();
  1054. dz->param[PICH_PICH2] = 0.0;
  1055. return setup_ring(dz);
  1056. }
  1057. /******************************** USAGE ********************************/
  1058. int usage1(void)
  1059. {
  1060. sprintf(errstr,
  1061. "INTERPOLATE PARTIALS OF PITCHED SRC1 TOWARDS THOSE OF PITCHED SRC 2\n"
  1062. "USAGE: specross partials analfile1 analfile2 outanalfile\n"
  1063. " tuning minwin signois harmcnt lo ho thresh level interp\n");
  1064. return(USAGE_ONLY);
  1065. }
  1066. int usage2(char *str)
  1067. {
  1068. if(!strcmp(str,"partials")) {
  1069. fprintf(stdout,
  1070. "USAGE: specross partials analfile1 analfile2 outanalfile\n"
  1071. " tuning minwin signois harmcnt lo hi thresh level interp [-a -p]\n"
  1072. "\n"
  1073. "INTERPOLATE PARTIALS OF PITCHED SRC2 TOWARDS THOSE OF PITCHED SRC 1\n"
  1074. "TUNING Range(semitones) within which harmonics 'in tune' (Default 1)\n"
  1075. "MINWIN Minimum number of adjacent windows that must be pitched,\n"
  1076. " for a pitch-value to be registered (Default %d).\n"
  1077. "SIGNOIS Signal to noise ratio, in decibels. (Default %.0lfdB)\n"
  1078. " Windows > signois dB below maximum level in sound, assumed\n"
  1079. " to be noise, & any detected pitch is assumed spurious.\n"
  1080. "HARMCNT Number of the %d loudest peaks in spectrum which must be\n"
  1081. " harmonics to confirm sound is pitched: Default %d.\n"
  1082. "LO Lowest acceptable frq for a pitch (Default %.0lfHz).\n"
  1083. "HI Highest acceptable frq for valid pitch (Default nyquist/%d).\n"
  1084. "THRESH Min acceptable level of any partial found, if it is to be used\n"
  1085. " in reconstructed spectrum (level relative to loudest partial)\n"
  1086. "LEVEL level of output (default 1.0). Use if reapplying infile1\n"
  1087. " to several infile2s, whose relative level is important.\n"
  1088. "INTERP Interp between file2 and file1: can vary through time\n"
  1089. " (brkpnt time vals will be scaled to duration of infil1).\n"
  1090. "-a Retain loudness countour file2, under file1 contour,\n"
  1091. "-p Extend 1st stable pitch of file1 to start of file.\n",
  1092. BLIPLEN,SILENCE_RATIO,MAXIMI,ACCEPTABLE_MATCH,MINPITCH,MAXIMI);
  1093. } else
  1094. fprintf(stdout,"Unknown option '%s'\n",str);
  1095. return(USAGE_ONLY);
  1096. }
  1097. int usage3(char *str1,char *str2)
  1098. {
  1099. sprintf(errstr,"Insufficient parameters on command line.\n");
  1100. return(USAGE_ONLY);
  1101. }
  1102. /************************* redundant functions: to ensure libs compile OK *******************/
  1103. int assign_process_logic(dataptr dz)
  1104. {
  1105. return(FINISHED);
  1106. }
  1107. void set_legal_infile_structure(dataptr dz)
  1108. {}
  1109. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  1110. {
  1111. return(FINISHED);
  1112. }
  1113. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  1114. {
  1115. return(FINISHED);
  1116. }
  1117. int setup_internal_arrays_and_array_pointers(dataptr dz)
  1118. {
  1119. return(FINISHED);
  1120. }
  1121. int establish_bufptrs_and_extra_buffers(dataptr dz)
  1122. {
  1123. return(FINISHED);
  1124. }
  1125. int read_special_data(char *str,dataptr dz)
  1126. {
  1127. return(FINISHED);
  1128. }
  1129. int inner_loop
  1130. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1131. {
  1132. return(FINISHED);
  1133. }
  1134. /******************************** SPECTRAL_INTERP_ON_PITCH ********************************/
  1135. int spectral_interp_on_pitch(dataptr dz)
  1136. {
  1137. int exit_status;
  1138. int atk_window;
  1139. float minfrq = (float)dz->chwidth;
  1140. char z1[8],z2[8];
  1141. int minpitch = (int)ceil(unchecked_hztomidi(dz->chwidth));
  1142. int oct = (minpitch/12) - 5;
  1143. minpitch %= 12;
  1144. switch(minpitch) {
  1145. case(0): strcpy(z1,"C"); break;
  1146. case(1): strcpy(z1,"C#"); break;
  1147. case(2): strcpy(z1,"D"); break;
  1148. case(3): strcpy(z1,"D#"); break;
  1149. case(4): strcpy(z1,"E"); break;
  1150. case(5): strcpy(z1,"F"); break;
  1151. case(6): strcpy(z1,"F#"); break;
  1152. case(7): strcpy(z1,"G"); break;
  1153. case(8): strcpy(z1,"G#"); break;
  1154. case(9): strcpy(z1,"A"); break;
  1155. case(10): strcpy(z1,"A#"); break;
  1156. case(11): strcpy(z1,"B"); break;
  1157. }
  1158. sprintf(z2,"%d",oct);
  1159. strcat(z1,z2);
  1160. fprintf(stdout,"INFO: Minimum pitch resolvable at this channel count = %s (C0 = middle C)\n",z1);
  1161. // fprintf(stdout,"INFO: Extracting pitch and harmonics from source 1.\n");
  1162. fflush(stdout);
  1163. if((exit_status = extract_pitch_and_harmonics(0,minfrq,dz)) < 0) /* get harmonic data for src 1 */
  1164. return(exit_status);
  1165. atk_window = get_atk_time(dz->fptr[0],dz->itemcnt,dz);
  1166. if(atk_window >= dz->insams[1]/dz->wanted) {
  1167. sprintf(errstr,"Attack time on 1st source is at or beyond end of 2nd.\n");
  1168. return(GOAL_FAILED);
  1169. }
  1170. // fprintf(stdout,"INFO: Extracting pitch and harmonics from source 2.\n");
  1171. // fflush(stdout);
  1172. if((exit_status = extract_pitch_and_harmonics(1,minfrq,dz)) < 0) /* get harmonic data for src 2 */
  1173. return(exit_status); /* pitchdata (and windowcnt) replaces data of 1st file */
  1174. // fprintf(stdout,"INFO: Interpolating harmonics.\n");
  1175. // fflush(stdout);
  1176. if((exit_status = interp_spectra(atk_window,dz))<0)
  1177. return(exit_status);
  1178. return(FINISHED);
  1179. }
  1180. /*********************** EXTRACT_PITCH_AND_HARMONICS ***********************/
  1181. int extract_pitch_and_harmonics(int fileno,double minfrq,dataptr dz)
  1182. {
  1183. int exit_status, firstwindow = 1, maxharmonics = 0, z;
  1184. int wins_in_buf, bigarraysize = 0, check, n, m, wlen, maxwlen;
  1185. float *thishratios, *pichstor;
  1186. // float lastfrq;
  1187. if(fileno == 0) {
  1188. pichstor = dz->pitches;
  1189. wlen = dz->wlength;
  1190. } else {
  1191. pichstor = dz->pitches2;
  1192. wlen = dz->insams[1]/dz->wanted;
  1193. }
  1194. z = 2 + fileno;
  1195. maxwlen = max(dz->wlength,dz->insams[1]/dz->wanted);
  1196. if((dz->parray[z] = (double *)malloc(maxwlen * sizeof(double)))==NULL) {
  1197. sprintf(errstr,"No memory to store evelope of file %d.\n",fileno + 1);
  1198. return(MEMORY_ERROR);
  1199. }
  1200. memset((char *)(dz->parray[z]),0,maxwlen * sizeof(double));
  1201. dz->total_samps_read = 0;
  1202. dz->total_windows = 0;
  1203. dz->samps_left = dz->insams[fileno];
  1204. while(dz->samps_left > 0) {
  1205. if((dz->ssampsread = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[fileno],0)) < 0) {
  1206. sprintf(errstr,"Can't read samples from input soundfile %d\n",fileno+1);
  1207. return(SYSTEM_ERROR);
  1208. }
  1209. dz->samps_left -= dz->ssampsread;
  1210. dz->total_samps_read += dz->ssampsread;
  1211. wins_in_buf = dz->ssampsread / dz->wanted;
  1212. dz->flbufptr[0] = dz->bigfbuf;
  1213. for(n=0;n<wins_in_buf;n++) {
  1214. if(firstwindow) {
  1215. pichstor[n] = (float)NOT_PITCH;
  1216. firstwindow = 0;
  1217. } else {
  1218. if((exit_status = specpitch(pichstor,dz))<0)
  1219. return(exit_status);
  1220. if(pichstor[dz->total_windows] >= minfrq)
  1221. maxharmonics = max(maxharmonics,(int)floor(dz->nyquist/pichstor[dz->total_windows]));
  1222. }
  1223. dz->parray[z][dz->total_windows] = 0.0; /* store loudness of window */
  1224. for(m = 0;m<dz->wanted;m+=2)
  1225. dz->parray[z][dz->total_windows] += dz->flbufptr[0][m];
  1226. dz->flbufptr[0] += dz->wanted;
  1227. dz->total_windows++;
  1228. }
  1229. }
  1230. if(dz->vflag[STABLE_PITCH] && fileno == 0) {
  1231. if((exit_status = extend_stable_pitch_to_start(dz))<0) {
  1232. fprintf(stdout,"INFO: No stable pitch found.\n");
  1233. fflush(stdout);
  1234. }
  1235. }
  1236. if(maxharmonics == 0) {
  1237. sprintf(errstr,"No pitch found in source %d.\n",fileno+1);
  1238. return(DATA_ERROR);
  1239. }
  1240. if(fileno == 0)
  1241. dz->itemcnt = maxharmonics;
  1242. else
  1243. dz->unspecified_filecnt = maxharmonics; /* spare structure variable used */
  1244. /* CREATE ARRAY TO STORE HARMONIC-RATIOS DATA */
  1245. for(n=0;n<wlen;n++) {
  1246. check = bigarraysize;
  1247. bigarraysize += maxharmonics * sizeof(float);
  1248. if(bigarraysize < check) {
  1249. sprintf(errstr,"Memory size for source 1 too large for integer arithmetic.\n");
  1250. return(MEMORY_ERROR);
  1251. }
  1252. }
  1253. if((dz->fptr[fileno] = (float *)malloc(bigarraysize))==NULL) {
  1254. sprintf(errstr,"Insufficient memory to store spectral data of source %d\n",fileno+1);
  1255. return(MEMORY_ERROR);
  1256. }
  1257. memset((char *)dz->fptr[fileno],0,bigarraysize); /* Default all harmonic amplitudes to zero */
  1258. /* USE PITCH INFO TO EXTRACT AMPLITUDES OF HARMONICS IN EACH WINDOW */
  1259. thishratios = dz->fptr[fileno];
  1260. if((sndseekEx(dz->ifd[fileno],0,0)<0)){
  1261. sprintf(errstr,"sndseek() failed\n");
  1262. return SYSTEM_ERROR;
  1263. }
  1264. dz->total_samps_read = 0;
  1265. dz->total_windows = 0;
  1266. dz->samps_left = dz->insams[fileno];
  1267. while(dz->samps_left > 0) {
  1268. if((dz->ssampsread = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[fileno],0)) < 0) {
  1269. sprintf(errstr,"Can't read samples from input soundfile %d.\n",fileno + 1);
  1270. return(SYSTEM_ERROR);
  1271. }
  1272. dz->samps_left -= dz->ssampsread;
  1273. dz->total_samps_read += dz->ssampsread;
  1274. wins_in_buf = dz->ssampsread / dz->wanted;
  1275. dz->flbufptr[0] = dz->bigfbuf;
  1276. for(n=0;n<wins_in_buf;n++) {
  1277. if(pichstor[dz->total_windows] >= minfrq)
  1278. extract_harmonic_contour(pichstor[dz->total_windows],thishratios,dz);
  1279. thishratios += maxharmonics;
  1280. dz->flbufptr[0] += dz->wanted;
  1281. dz->total_windows++;
  1282. }
  1283. }
  1284. // lastfrq = (float)NOT_PITCH; /* i.e. no pitch yet found */
  1285. /* INTERPOLATE PITCH AND HRATIOS THROUGH UNPITCHED AREAS */
  1286. pitch_and_harms_interp(maxharmonics,minfrq,dz->fptr[fileno],pichstor,wlen,fileno,dz);
  1287. return FINISHED;
  1288. }
  1289. /*********************** PITCH_AND_HARMS_INTERP ***********************/
  1290. /* INTERPOLATE PITCH AND HRATIOS THROUGH UNPITCHED AREAS */
  1291. int pitch_and_harms_interp(int maxharmonics,double minfrq,float *hratios,float *pichstor,int wlen,int fileno,dataptr dz)
  1292. {
  1293. int n, m, k, i, j, startharms, endharms, winstep;
  1294. float startharm, endharm, lastfrq = (float)NOT_PITCH; /* i.e. no pitch yet found */
  1295. double endpitch, lastpitch, pitchstep, thispitch, interp, harmstep;
  1296. for(n=0,m=0;n<dz->total_windows;n++,m+=maxharmonics) {
  1297. if(pichstor[n] < minfrq) { /* NO PITCH IN THIS WINDOW */
  1298. if(lastfrq < minfrq) /* No pitch, so far, in sound */
  1299. continue;
  1300. else { /* Previous window had a valid pitch */
  1301. startharms = m - maxharmonics; /* start of hratios in previous (pitched) window */
  1302. k = n + 1;
  1303. while(k < wlen) { /* Search forward for next valid pitch */
  1304. if(pichstor[k] < minfrq)
  1305. k++;
  1306. else
  1307. break;
  1308. }
  1309. if(k == wlen) { /* No more pitched windows before end of snd */
  1310. while(n < wlen) { /* Copy previous pitch + hratios into all last windows */
  1311. pichstor[n] = lastfrq;
  1312. //NEW : ONLY INTERP MARMONICS IN 1ST SOUND: NO PITCH IN Snd2 = HARMONICS ZERO
  1313. if(fileno==0) {
  1314. for(i = 0; i < maxharmonics; i++) {
  1315. hratios[m] = hratios[startharms + i];
  1316. m++;
  1317. }
  1318. }
  1319. n++;
  1320. }
  1321. } else { /* Interpolate between last valid pitch and next */
  1322. winstep = k - n + 1;
  1323. endpitch = unchecked_hztomidi(pichstor[k]);
  1324. lastpitch = unchecked_hztomidi(lastfrq);
  1325. pitchstep = (endpitch - lastpitch)/(double)winstep;
  1326. thispitch = lastpitch;
  1327. endharms = k * maxharmonics;
  1328. for(j = 1; n < k; n++,j++) { /* j counts interp steps, n continues to count pitches */
  1329. interp = (double)j/(double)winstep;
  1330. thispitch += pitchstep;
  1331. pichstor[n] = (float)miditohz(thispitch); /* interpolated pitch */
  1332. //NEW : ONLY INTERP MARMONICS IN 1ST SOUND
  1333. if(fileno==0) {
  1334. for(i = 0; i < maxharmonics; i++) { /* interpolate between hratios */
  1335. if(fileno==0) {
  1336. startharm = hratios[startharms + i];
  1337. endharm = hratios[endharms + i];
  1338. harmstep = (endharm - startharm) * interp;
  1339. hratios[m] = (float)(startharm + harmstep);
  1340. m++; /* m counts hratios */
  1341. }
  1342. }
  1343. }
  1344. }
  1345. lastfrq = pichstor[k]; /* Remember last valid pitch */
  1346. }
  1347. }
  1348. } else { /* FOUND VALID PITCH */
  1349. if(lastfrq < minfrq) { /* no pitch previously found, This is first found */
  1350. for(k = 0,j = 0; k < n; k++,j += maxharmonics) {
  1351. pichstor[k] = pichstor[n]; /* copy current pitch into all previous windows */
  1352. //NEW : ONLY INTERP MARMONICS IN 1ST SOUND
  1353. if(fileno==0) {
  1354. for(i=0;i < maxharmonics;i++) /* copy current hratios into all previous windows */
  1355. hratios[j+i] = hratios[m+i];
  1356. }
  1357. }
  1358. }
  1359. lastfrq = pichstor[n]; /* Remember last valid pitch */
  1360. }
  1361. }
  1362. return FINISHED;
  1363. }
  1364. /*********************** EXTRACT_HARMONIC_CONTOUR ***************************/
  1365. #define EIGHT_OVER_SEVEN (1.142857143)
  1366. int extract_harmonic_contour(float fundamental,float *thishratios,dataptr dz)
  1367. {
  1368. int harmno, n, cc, vc, try_again, all_finished /*, valid_amps */;
  1369. double partialfrq, maxamp, frqratio, normdval;
  1370. float frq, amp;
  1371. dz->clength = dz->wanted / 2;
  1372. harmno = 0;
  1373. partialfrq = fundamental * (harmno+1);
  1374. thishratios[harmno] = 0.0;
  1375. all_finished = 0;
  1376. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  1377. frq = dz->flbufptr[0][FREQ];
  1378. amp = dz->flbufptr[0][AMPP];
  1379. try_again = 1;
  1380. while(try_again) {
  1381. try_again = 0;
  1382. if(frq <= partialfrq) {
  1383. frqratio = partialfrq / fabs(frq);
  1384. if(frqratio < EIGHT_OVER_SEVEN) /* if approx equal to harmonic frq */
  1385. thishratios[harmno] =
  1386. (float)max((double)amp,thishratios[harmno]);/* store max amp val found for this harmonic */
  1387. /* else, in between valid harmonic values */
  1388. } else {
  1389. frqratio = fabs(frq) / partialfrq; /* ELSE frq > partialfrq */
  1390. if(frqratio < EIGHT_OVER_SEVEN) { /* if approx equal to harmonic frq */
  1391. thishratios[harmno] =
  1392. (float)max((double)amp,thishratios[harmno]);/* store max amp val found for this harmonic */
  1393. } else {
  1394. harmno++; /* else move to next harmonic */
  1395. thishratios[harmno] = 0.0;
  1396. partialfrq = fundamental * (harmno + 1);
  1397. if(partialfrq >= dz->nyquist) { /* if no more harmonics, break */
  1398. harmno--;
  1399. all_finished = 1;
  1400. break;
  1401. }
  1402. try_again = 1;
  1403. }
  1404. }
  1405. }
  1406. if(all_finished)
  1407. break;
  1408. }
  1409. maxamp = 0.0;
  1410. for(n = 0;n<=harmno;n++)
  1411. maxamp = max((double)thishratios[n],maxamp); /* Find loudest partial */
  1412. if(maxamp <= FLTERR) { /* If no significant level */
  1413. for(n = 0;n<=harmno;n++) /* set all partials to zero */
  1414. thishratios[n] = 0.0f;
  1415. }
  1416. // valid_amps = 0;
  1417. for(n = 0;n<=harmno;n++) {
  1418. normdval = thishratios[n]/maxamp;
  1419. if(normdval < dz->param[PICH_THRESH]) /* if partial below threshold */
  1420. thishratios[n] = 0.0f; /* set it to zero */
  1421. }
  1422. return FINISHED;
  1423. }
  1424. /****************************** SPECPITCH *******************************
  1425. *
  1426. * (1) Ignore partials below low limit of pitch.
  1427. * (2) If this channel data is louder than any existing piece of data in ring.
  1428. * (Ring data is ordered loudness-wise)...
  1429. * (3) If this freq is too close to an existing frequency..
  1430. * (4) and if it is louder than that existing frequency data..
  1431. * (5) Substitute in in the ring.
  1432. * (6) Otherwise, (its a new frq) insert it into the ring.
  1433. */
  1434. int specpitch(float *pichstor,dataptr dz)
  1435. {
  1436. int exit_status;
  1437. int vc;
  1438. chvptr here, there, *partials;
  1439. float minamp;
  1440. double loudest_partial_frq, nextloudest_partial_frq, lo_loud_partial, hi_loud_partial;
  1441. if((partials = (chvptr *)malloc(MAXIMI * sizeof(chvptr)))==NULL) {
  1442. sprintf(errstr,"INSUFFICIENT MEMORY for partials array.\n");
  1443. return(MEMORY_ERROR);
  1444. }
  1445. if((exit_status = initialise_ring_vals(MAXIMI,-1.0,dz))<0)
  1446. return(exit_status);
  1447. if((exit_status = rectify_frqs(dz->flbufptr[0],dz))<0)
  1448. return(exit_status);
  1449. for(vc=0;vc<dz->wanted;vc+=2) {
  1450. here = dz->ringhead;
  1451. if(dz->flbufptr[0][FREQ] > dz->param[PICH_LOLM]) { /* 1 */
  1452. do {
  1453. if(dz->flbufptr[0][AMPP] > here->val) { /* 2 */
  1454. if((exit_status = close_to_frq_already_in_ring(&there,(double)dz->flbufptr[0][FREQ],dz))<0)
  1455. return(exit_status);
  1456. if(exit_status==TRUE) {
  1457. if(dz->flbufptr[0][AMPP] > there->val) { /* 4 */
  1458. if((exit_status = substitute_in_ring(vc,here,there,dz))<0) /* 5 */
  1459. return(exit_status);
  1460. }
  1461. } else { /* 6 */
  1462. if((exit_status = insert_in_ring(vc,here,dz))<0)
  1463. return(exit_status);
  1464. }
  1465. break;
  1466. }
  1467. } while((here = here->next)!=dz->ringhead);
  1468. }
  1469. }
  1470. loudest_partial_frq = dz->flbufptr[0][dz->ringhead->loc + 1];
  1471. nextloudest_partial_frq = dz->flbufptr[0][dz->ringhead->next->loc + 1];
  1472. if(loudest_partial_frq < nextloudest_partial_frq) {
  1473. lo_loud_partial = loudest_partial_frq;
  1474. hi_loud_partial = nextloudest_partial_frq;
  1475. } else {
  1476. lo_loud_partial = nextloudest_partial_frq;
  1477. hi_loud_partial = loudest_partial_frq;
  1478. }
  1479. if((exit_status = put_ring_frqs_in_ascending_order(&partials,&minamp,dz))<0)
  1480. return(exit_status);
  1481. if((exit_status = found_pitch(partials,lo_loud_partial,hi_loud_partial,minamp,dz))<0)
  1482. return(exit_status);
  1483. if(exit_status==TRUE && dz->param[PICH_PICH2]>=MINPITCH)
  1484. pichstor[dz->total_windows] = (float)dz->param[PICH_PICH2];
  1485. else
  1486. pichstor[dz->total_windows] = (float)NOT_PITCH;
  1487. return smooth_spurious_octave_leaps(pichstor,dz->total_windows,minamp,dz);
  1488. }
  1489. /**************************** CLOSE_TO_FRQ_ALREADY_IN_RING *******************************/
  1490. int close_to_frq_already_in_ring(chvptr *there,double frq1,dataptr dz)
  1491. {
  1492. #define EIGHT_OVER_SEVEN (1.142857143)
  1493. double frq2, frqratio;
  1494. *there = dz->ringhead;
  1495. do {
  1496. if((*there)->val > 0.0) {
  1497. frq2 = dz->flbufptr[0][(*there)->loc + 1];
  1498. if(frq1 > frq2)
  1499. frqratio = frq1/frq2;
  1500. else
  1501. frqratio = frq2/frq1;
  1502. if(frqratio < EIGHT_OVER_SEVEN)
  1503. return(TRUE);
  1504. }
  1505. } while((*there = (*there)->next) != dz->ringhead);
  1506. return(FALSE);
  1507. }
  1508. /******************************* SUBSITUTE_IN_RING **********************/
  1509. int substitute_in_ring(int vc,chvptr here,chvptr there,dataptr dz)
  1510. {
  1511. chvptr spare, previous;
  1512. if(here!=there) {
  1513. if(there==dz->ringhead) {
  1514. sprintf(errstr,"IMPOSSIBLE! in substitute_in_ring()\n");
  1515. return(PROGRAM_ERROR);
  1516. }
  1517. spare = there;
  1518. there->next->last = there->last; /* SPLICE REDUNDANT STRUCT FROM RING */
  1519. there->last->next = there->next;
  1520. previous = here->last;
  1521. previous->next = spare; /* SPLICE ITS ADDRESS-SPACE BACK INTO RING */
  1522. spare->last = previous; /* IMMEDIATELY BEFORE HERE */
  1523. here->last = spare;
  1524. spare->next = here;
  1525. if(here==dz->ringhead) /* IF HERE IS RINGHEAD, MOVE RINGHEAD */
  1526. dz->ringhead = spare;
  1527. here = spare; /* POINT TO INSERT LOCATION */
  1528. }
  1529. here->val = dz->flbufptr[0][AMPP]; /* IF here==there */
  1530. here->loc = vc; /* THIS WRITES OVER VAL IN EXISTING RING LOCATION */
  1531. return(FINISHED);
  1532. }
  1533. /*************************** INSERT_IN_RING ***************************/
  1534. int insert_in_ring(int vc, chvptr here, dataptr dz)
  1535. {
  1536. chvptr previous, newend, spare;
  1537. if(here==dz->ringhead) {
  1538. dz->ringhead = dz->ringhead->last;
  1539. spare = dz->ringhead;
  1540. } else {
  1541. if(here==dz->ringhead->last)
  1542. spare = here;
  1543. else {
  1544. spare = dz->ringhead->last;
  1545. newend = dz->ringhead->last->last; /* cut ENDADR (spare) out of ring */
  1546. dz->ringhead->last = newend;
  1547. newend->next = dz->ringhead;
  1548. previous = here->last;
  1549. here->last = spare; /* reuse spare address at new loc by */
  1550. spare->next = here; /* inserting it back into ring before HERE */
  1551. previous->next = spare;
  1552. spare->last = previous;
  1553. }
  1554. }
  1555. spare->val = dz->flbufptr[0][vc]; /* Store new val in spare ring location */
  1556. spare->loc = vc;
  1557. return(FINISHED);
  1558. }
  1559. /************************** PUT_RING_FRQS_IN_ASCENDING_ORDER **********************/
  1560. int put_ring_frqs_in_ascending_order(chvptr **partials,float *minamp,dataptr dz)
  1561. {
  1562. int k;
  1563. chvptr start, ggot, here = dz->ringhead;
  1564. float minpitch;
  1565. *minamp = (float)MAXFLOAT;
  1566. for(k=0;k<MAXIMI;k++) {
  1567. if((*minamp = min(dz->flbufptr[0][here->loc],*minamp))>=(float)MAXFLOAT) {
  1568. sprintf(errstr,"Problem with amplitude out of range: put_ring_frqs_in_ascending_order()\n");
  1569. return(PROGRAM_ERROR);
  1570. }
  1571. (here->loc)++; /* CHANGE RING TO POINT TO FRQS, not AMPS */
  1572. here->val = dz->flbufptr[0][here->loc];
  1573. here = here->next;
  1574. }
  1575. here = dz->ringhead;
  1576. minpitch = dz->flbufptr[0][here->loc];
  1577. for(k=1;k<MAXIMI;k++) {
  1578. start = ggot = here;
  1579. while((here = here->next)!=start) { /* Find lowest frq */
  1580. if(dz->flbufptr[0][here->loc] < minpitch) {
  1581. minpitch = dz->flbufptr[0][here->loc];
  1582. ggot = here;
  1583. }
  1584. }
  1585. (*partials)[k-1] = ggot; /* Save its address */
  1586. here = ggot->next; /* Move to next ring site */
  1587. minpitch = dz->flbufptr[0][here->loc]; /* Preset minfrq to val there */
  1588. ggot->last->next = here; /* Unlink ringsite ggot */
  1589. here->last = ggot->last;
  1590. }
  1591. (*partials)[k-1] = here; /* Remaining ringsite is maximum */
  1592. here = dz->ringhead = (*partials)[0]; /* Reconstruct ring */
  1593. for(k=1;k<MAXIMI;k++) {
  1594. here->next = (*partials)[k];
  1595. (*partials)[k]->last = here;
  1596. here = here->next;
  1597. }
  1598. here->next = dz->ringhead; /* Close up ring */
  1599. dz->ringhead->last = here;
  1600. return(FINISHED);
  1601. }
  1602. /****************************** FOUND_PITCH **************************/
  1603. #define MAXIMUM_PARTIAL (64)
  1604. int found_pitch(chvptr *partials,double lo_loud_partial,double hi_loud_partial,float minamp,dataptr dz)
  1605. {
  1606. int n, m, k, maximi_less_one = MAXIMUM_PARTIAL - 1, endd = 0;
  1607. double whole_number_ratio, comparison_frq;
  1608. for(n=1;n<maximi_less_one;n++) {
  1609. for(m=n+1;m<MAXIMUM_PARTIAL;m++) { /* NOV 7 */
  1610. whole_number_ratio = (double)m/(double)n;
  1611. comparison_frq = lo_loud_partial * whole_number_ratio;
  1612. if(equivalent_pitches(comparison_frq,hi_loud_partial,dz))
  1613. endd = (MAXIMUM_PARTIAL/m) * n; /* explanation at foot of file */
  1614. else if(comparison_frq > hi_loud_partial)
  1615. break;
  1616. for(k=n;k<=endd;k+=n) {
  1617. dz->param[PICH_PICH2] = lo_loud_partial/(double)k;
  1618. if(dz->param[PICH_PICH2]>dz->param[PICH_HILM])
  1619. continue;
  1620. if(dz->param[PICH_PICH2]<dz->param[PICH_LOLM])
  1621. break;
  1622. if(is_peak_at(dz->param[PICH_PICH2],0,minamp,dz)){
  1623. if(dz->iparam[PICH_MATCH] <= 2)
  1624. return TRUE;
  1625. else if(enough_partials_are_harmonics(partials,dz))
  1626. return TRUE;
  1627. }
  1628. }
  1629. }
  1630. }
  1631. return(FALSE);
  1632. }
  1633. /************************ SMOOTH_SPURIOUS_OCTAVE_LEAPS ***************************/
  1634. int smooth_spurious_octave_leaps(float *pichstor,int pitchno,float minamp,dataptr dz)
  1635. {
  1636. #define ALMOST_TWO (1.75)
  1637. double thispitch = pichstor[pitchno];
  1638. double startpitch, lastpitch;
  1639. int k = 0;
  1640. if(pitchno<=0)
  1641. return(FINISHED);
  1642. lastpitch = pichstor[pitchno-1];
  1643. if(lastpitch > dz->param[PICH_LOLM] && thispitch > dz->param[PICH_LOLM]) { /* OCTAVE ADJ HERE */
  1644. if(thispitch > lastpitch) { /* OCTAVE ADJ FORWARDS */
  1645. startpitch = thispitch;
  1646. while(thispitch/lastpitch > ALMOST_TWO)
  1647. thispitch /= 2.0;
  1648. if(thispitch!=startpitch) {
  1649. if(thispitch < dz->param[PICH_LOLM])
  1650. return(FINISHED);
  1651. if(is_peak_at(thispitch,0L,minamp,dz))
  1652. pichstor[pitchno] = (float)thispitch;
  1653. else
  1654. pichstor[pitchno] = (float)startpitch;
  1655. }
  1656. return(FINISHED);
  1657. } else {
  1658. while(pitchno>=1) { /* OCTAVE ADJ BCKWARDS */
  1659. k++;
  1660. if((thispitch = pichstor[pitchno--])<dz->param[PICH_LOLM])
  1661. return(FINISHED);
  1662. if((lastpitch = pichstor[pitchno])<dz->param[PICH_LOLM])
  1663. return(FINISHED);
  1664. startpitch = lastpitch;
  1665. while(lastpitch/thispitch > ALMOST_TWO)
  1666. lastpitch /= 2.0;
  1667. if(lastpitch!=startpitch) {
  1668. if(lastpitch < dz->param[PICH_LOLM])
  1669. return(FINISHED);
  1670. if(is_peak_at(lastpitch,k,minamp,dz))
  1671. pichstor[pitchno] = (float)lastpitch;
  1672. else
  1673. pichstor[pitchno] = (float)startpitch;
  1674. }
  1675. }
  1676. }
  1677. }
  1678. return(FINISHED);
  1679. }
  1680. /**************************** EQUIVALENT_PITCHES *************************/
  1681. int equivalent_pitches(double frq1, double frq2, dataptr dz)
  1682. {
  1683. double ratio;
  1684. int iratio;
  1685. double intvl;
  1686. ratio = frq1/frq2;
  1687. iratio = round(ratio);
  1688. if(iratio!=1)
  1689. return(FALSE);
  1690. if(ratio > iratio)
  1691. intvl = ratio/(double)iratio;
  1692. else
  1693. intvl = (double)iratio/ratio;
  1694. if(intvl > dz->param[PICH_RNGE])
  1695. return FALSE;
  1696. return TRUE;
  1697. }
  1698. /*************************** IS_PEAK_AT ***************************/
  1699. #define PEAK_LIMIT (.05)
  1700. int is_peak_at(double frq,int window_offset,float minamp,dataptr dz)
  1701. {
  1702. float *thisbuf;
  1703. int cc, vc, searchtop, searchbot;
  1704. if(window_offset) { /* BAKTRAK ALONG BIGBUF, IF NESS */
  1705. if((thisbuf = dz->flbufptr[0] - (window_offset * dz->wanted)) < dz->bigfbuf)
  1706. return(FALSE);
  1707. }else
  1708. thisbuf = dz->flbufptr[0];
  1709. cc = (int)((frq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  1710. searchtop = min(dz->clength,cc + CHANSCAN + 1);
  1711. searchbot = max(0,cc - CHANSCAN);
  1712. for(cc = searchbot ,vc = searchbot*2; cc < searchtop; cc++, vc += 2) {
  1713. if(!equivalent_pitches((double)thisbuf[vc+1],frq,dz))
  1714. continue;
  1715. if(thisbuf[vc] < minamp * PEAK_LIMIT)
  1716. continue;
  1717. if(local_peak(cc,frq,thisbuf,dz))
  1718. return TRUE;
  1719. }
  1720. return FALSE;
  1721. }
  1722. /**************************** ENOUGH_PARTIALS_ARE_HARMONICS *************************/
  1723. int enough_partials_are_harmonics(chvptr *partials,dataptr dz)
  1724. {
  1725. int n, good_match = 0;
  1726. double thisfrq;
  1727. for(n=0;n<MAXIMI;n++) {
  1728. if((thisfrq = dz->flbufptr[0][partials[n]->loc]) < dz->param[PICH_PICH2])
  1729. continue;
  1730. if(is_a_harmonic(thisfrq,dz->param[PICH_PICH2],dz)){
  1731. if(++good_match >= dz->iparam[PICH_MATCH])
  1732. return TRUE;
  1733. }
  1734. }
  1735. return FALSE;
  1736. }
  1737. /**************************** IS_A_HARMONIC *************************/
  1738. int is_a_harmonic(double frq1,double frq2,dataptr dz)
  1739. {
  1740. double ratio = frq1/frq2;
  1741. int iratio = round(ratio);
  1742. double intvl;
  1743. ratio = frq1/frq2;
  1744. iratio = round(ratio);
  1745. if(ratio > iratio)
  1746. intvl = ratio/(double)iratio;
  1747. else
  1748. intvl = (double)iratio/ratio;
  1749. if(intvl > dz->param[PICH_RNGE])
  1750. return(FALSE);
  1751. return(TRUE);
  1752. }
  1753. /***************************** LOCAL_PEAK **************************/
  1754. int local_peak(int thiscc,double frq, float *thisbuf, dataptr dz)
  1755. {
  1756. int thisvc = thiscc * 2;
  1757. int cc, vc, searchtop, searchbot;
  1758. double frqtop = frq * SEMITONE_INTERVAL;
  1759. double frqbot = frq / SEMITONE_INTERVAL;
  1760. searchtop = (int)((frqtop + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  1761. searchtop = min(dz->clength,searchtop + PEAKSCAN + 1);
  1762. searchbot = (int)((frqbot + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  1763. searchbot = max(0,searchbot - PEAKSCAN);
  1764. for(cc = searchbot ,vc = searchbot*2; cc < searchtop; cc++, vc += 2) {
  1765. if(thisbuf[thisvc] < thisbuf[vc])
  1766. return(FALSE);
  1767. }
  1768. return(TRUE);
  1769. }
  1770. /***************************** GET_ATK_TIME *****************************/
  1771. int get_atk_time(float *hratios,int maxharmonics,dataptr dz)
  1772. {
  1773. int i;
  1774. int n, m = 0, maxloc = 0;
  1775. double sum, maxsum = 0.0, atk_time, duration1;
  1776. for(n = 0;n<dz->total_windows;n++) {
  1777. sum = 0.0;
  1778. for(i = 0; i <maxharmonics;i++)
  1779. sum += hratios[m++];
  1780. if(sum > maxsum) {
  1781. maxsum = sum;
  1782. maxloc = n;
  1783. }
  1784. }
  1785. atk_time = maxloc * dz->frametime;
  1786. duration1 = (dz->insams[1]/dz->wanted) * dz->frametime;
  1787. fprintf(stdout,"INFO: Attack time of 1st sound at %.3lf secs\n",atk_time);
  1788. if((atk_time > dz->duration/2.0) && (atk_time > duration1/2.0))
  1789. fprintf(stdout,"WARNING: Attack time of 1st sound not close to start of sound (duration %.3lf secs).\n",dz->duration);
  1790. fflush(stdout);
  1791. return maxloc;
  1792. }
  1793. /***************************** INTERP_SPECTRA *****************************/
  1794. int interp_spectra(int atk_window,dataptr dz)
  1795. {
  1796. int exit_status;
  1797. int outwinno, wins0, wins1, endlen0, endlen1;
  1798. double time = 0.0,postatk_ratio;
  1799. if((sndseekEx(dz->ifd[1],0,0)<0)){
  1800. sprintf(errstr,"sndseek() failed\n");
  1801. return SYSTEM_ERROR;
  1802. }
  1803. dz->total_samps_read = 0;
  1804. dz->total_windows = 0;
  1805. dz->samps_left = dz->insams[1];
  1806. dz->flbufptr[0] = dz->bigfbuf;
  1807. wins0 = dz->insams[0]/dz->wanted;
  1808. wins1 = dz->insams[1]/dz->wanted;
  1809. endlen0 = wins0 - atk_window;
  1810. endlen1 = wins1 - atk_window;
  1811. if(dz->vflag[AMP_SCALING]) {
  1812. if((exit_status = amplitude_scaling(atk_window,dz))<0)
  1813. return(exit_status);
  1814. }
  1815. postatk_ratio = (double)endlen0/(double)endlen1;
  1816. while(dz->samps_left > 0) {
  1817. if((dz->ssampsread = fgetfbufEx(dz->bigfbuf, dz->wanted,dz->ifd[1],0)) < 0) {
  1818. sprintf(errstr,"Can't reread samples to do spectral interpolation.\n");
  1819. return(SYSTEM_ERROR);
  1820. }
  1821. dz->samps_left -= dz->ssampsread;
  1822. dz->total_samps_read += dz->ssampsread;
  1823. if(dz->brksize[SPECHINT]) {
  1824. if((exit_status = read_value_from_brktable(time,SPECHINT,dz))<0)
  1825. return(exit_status);
  1826. time += dz->frametime;
  1827. }
  1828. if(dz->total_windows > 0) { /* Skip Window 0, no significant data */
  1829. if( dz->total_windows <= atk_window) /* Before attack, do straight interp */
  1830. outwinno = dz->total_windows;
  1831. else { /* After attack, ratio of durations of tails must be considered */
  1832. outwinno = round((dz->total_windows - atk_window) * postatk_ratio);
  1833. if((outwinno += atk_window) >= wins0)
  1834. outwinno = wins0 - 1;
  1835. }
  1836. spec_interp(outwinno,dz);
  1837. }
  1838. if((exit_status = write_samps(dz->flbufptr[0],dz->wanted,dz))<0)
  1839. return(exit_status);
  1840. dz->total_windows++;
  1841. }
  1842. return(FINISHED);
  1843. }
  1844. /***************************** SPEC_INTERP *****************************/
  1845. int spec_interp(int outwinno,dataptr dz)
  1846. {
  1847. int harmno = 0, cc, vc, gotpartial, try_again, all_finished = 0;
  1848. float /*amp,*/ frq, newlevel;
  1849. double partialfrq, frqratio, fundamental = dz->pitches2[dz->total_windows];
  1850. partialfrq = fundamental * (harmno + 1);
  1851. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  1852. gotpartial = 0;
  1853. frq = dz->flbufptr[0][FREQ];
  1854. // amp = dz->flbufptr[0][AMPP];
  1855. try_again = 1;
  1856. while(try_again) {
  1857. try_again = 0;
  1858. if(frq <= partialfrq) {
  1859. frqratio = partialfrq / fabs(frq);
  1860. if(frqratio < EIGHT_OVER_SEVEN) { /* if approx equal to harmonic frq, got a partial */
  1861. if((newlevel = get_newlevel(outwinno,harmno,AMPP,dz)) > 0.0) {
  1862. dz->flbufptr[0][AMPP] = newlevel;
  1863. gotpartial = 1;
  1864. }
  1865. }
  1866. } else {
  1867. frqratio = fabs(frq) / partialfrq; /* ELSE frq > partialfrq */
  1868. if(frqratio < EIGHT_OVER_SEVEN) { /* if approx equal to harmonic frq */
  1869. if((newlevel = get_newlevel(outwinno,harmno,AMPP,dz)) > 0.0) {
  1870. dz->flbufptr[0][AMPP] = newlevel;
  1871. gotpartial = 1;
  1872. }
  1873. } else {
  1874. harmno++; /* else move to next harmonic */
  1875. partialfrq = fundamental * (harmno + 1);
  1876. if(partialfrq >= dz->nyquist) { /* if no more harmonics, break */
  1877. harmno--;
  1878. all_finished = 1;
  1879. break;
  1880. }
  1881. try_again = 1;
  1882. }
  1883. }
  1884. }
  1885. if(!gotpartial) /* Zero non-partial data */
  1886. dz->flbufptr[0][AMPP] = 0.0;
  1887. if(all_finished) { /* In no more partials, zero rest of channels */
  1888. while(cc < dz->clength) {
  1889. dz->flbufptr[0][AMPP] = 0.0;
  1890. cc ++;
  1891. vc += 2;
  1892. }
  1893. break;
  1894. }
  1895. }
  1896. return FINISHED;
  1897. }
  1898. /***************************** GET_NEWLEVEL ********************************/
  1899. float get_newlevel(int outwinno,int harmno,int ampchan,dataptr dz)
  1900. {
  1901. double src1level, src2level, diff, newlevel, scalefact;
  1902. int loc;
  1903. /* For source 1 */
  1904. if(harmno >= dz->itemcnt) /* if harmonic number higher than max harmlevel stored */
  1905. src1level = 0.0; /* set level to zero */
  1906. else { /* otherwise get level of this harmonic from store */
  1907. loc = (outwinno * dz->itemcnt) + harmno;
  1908. src1level = dz->fptr[0][loc];
  1909. src1level *= dz->param[SPCMPLEV];
  1910. } /* simil for source 2 */
  1911. if(harmno >= dz->unspecified_filecnt)
  1912. src2level = 0.0;
  1913. else {
  1914. loc = (dz->total_windows * dz->unspecified_filecnt) + harmno;
  1915. src2level = dz->fptr[1][loc];
  1916. }
  1917. if(src2level <= 0.0) /* If src2 (to be transformed) has a zero level harmonic, return ZERO output */
  1918. return 0.0;
  1919. diff = (src1level - src2level) * dz->param[SPECHINT]; /* Interpolate between levels of harmonics */
  1920. newlevel = src2level + diff;
  1921. //ENV_SCALING
  1922. scalefact = dz->parray[2][dz->total_windows]; /* scaling is applied when interp val is 1*/
  1923. /* scaling is NOT applied when interp is zero */
  1924. scalefact = 1.0 + ((scalefact - 1.0) * dz->param[SPECHINT]);
  1925. newlevel *= scalefact;
  1926. return (float)((dz->flbufptr[0][ampchan] * newlevel)/src2level); /* derive new level from existing level */
  1927. }
  1928. /**************************** READ_DATA_FROM_INTERP_FILE *******************************/
  1929. int read_data_from_interp_file(char *filename,dataptr dz)
  1930. {
  1931. int cnt;
  1932. int n, m;
  1933. char temp[200], *p;
  1934. double val, lasttime = -1.0, duration, ratio;
  1935. if((dz->fp = fopen(filename,"r"))==NULL) {
  1936. sprintf(errstr,"Cannot open datafile %s\n",filename);
  1937. return(DATA_ERROR);
  1938. }
  1939. cnt = 0;
  1940. while(fgets(temp,200,dz->fp)!=NULL) {
  1941. p = temp;
  1942. if(*p == ';') // Allow comments in file
  1943. continue;
  1944. while(get_float_from_within_string(&p,&val))
  1945. cnt++;
  1946. }
  1947. if(cnt == 0) {
  1948. sprintf(errstr,"No data in file %s\n",filename);
  1949. return(DATA_ERROR);
  1950. }
  1951. if(!EVEN(cnt)) {
  1952. sprintf(errstr,"Values incorrectly paired in file %s\n",filename);
  1953. return(DATA_ERROR);
  1954. }
  1955. if((dz->brk[SPECHINT] = (double *)malloc(cnt * sizeof(double)))==NULL) {
  1956. sprintf(errstr,"Insufficient memory to store interp file data.\n");
  1957. return(MEMORY_ERROR);
  1958. }
  1959. fseek(dz->fp,0,0);
  1960. cnt = 0;
  1961. while(fgets(temp,200,dz->fp)!=NULL) {
  1962. p = temp;
  1963. if(*p == ';') // Allow comments in file
  1964. continue;
  1965. while(get_float_from_within_string(&p,&val)) {
  1966. if(EVEN(cnt)) {
  1967. if(cnt == 0) {
  1968. if(val != 0.0) {
  1969. sprintf(errstr,"First time in brkfile %s must be zero\n",filename);
  1970. return(DATA_ERROR);
  1971. }
  1972. } else if(val <= lasttime) {
  1973. sprintf(errstr,"Times do not advance at line %d in file %s\n",cnt+1,filename);
  1974. return(DATA_ERROR);
  1975. }
  1976. lasttime = val;
  1977. } else {
  1978. if(val < 0.0 || val > 1.0) {
  1979. sprintf(errstr,"Values out of range (0-1) at line %d in file %s\n",cnt+1,filename);
  1980. return(DATA_ERROR);
  1981. }
  1982. }
  1983. dz->brk[SPECHINT][cnt] = (float)val;
  1984. }
  1985. }
  1986. dz->brksize[SPECHINT] = cnt/2;
  1987. if(dz->brksize[SPECHINT] == 1) {
  1988. dz->param[SPECHINT] = dz->brk[SPECHINT][1];
  1989. free(dz->brk[SPECHINT]);
  1990. dz->brksize[SPECHINT] = 0;
  1991. return FINISHED;
  1992. }
  1993. duration = (dz->insams[1]/dz->wanted) * dz->frametime;
  1994. ratio = duration/lasttime;
  1995. for(n=0,m=0;n<dz->brksize[SPECHINT];n++,m+=2) /* Scale interp file to duration of source */
  1996. dz->brk[SPECHINT][m] *= ratio;
  1997. return FINISHED;
  1998. }
  1999. /************************************ AMPLITUDE_SCALING ******************************
  2000. *
  2001. * How this works:
  2002. * Calculate envelope of snd1 and snd2.
  2003. * Calculate peaks in envelope of snd2.
  2004. * Scaling multiplies loudness of snd 1 by normalised level in snd2.
  2005. * In this way, the envelope contour of snd2 is shaped by the level of snd 1,
  2006. * so e.g. if snd 1 drops grad in level , but snd2 fluctuates,
  2007. * scaling will force the fluctuations to drop gradiaully in overall level, in way snd1 does.
  2008. *
  2009. * The idea is to maintain the amplitude fluctations of snd2 under the gross env of sound1.
  2010. */
  2011. #define SIGNOIS_SPEC (1500.0)
  2012. #define SPEC_ENV_RATIO (10) /* number of analwindows in an envelope window */
  2013. int amplitude_scaling(int atk_window,dataptr dz)
  2014. {
  2015. double *window_level0 = dz->parray[2];
  2016. double *window_level1 = dz->parray[3];
  2017. double maxenvval, minenvval, step, here, val, valdiff, ratio;
  2018. double scale_at_last_peak, scale_at_this_peak, scalestep, scalehere,snd1maxlevel;
  2019. int wlen0, wlen1, posttail_wlen0, posttail_wlen1, z, m, k, n, lastn, envlen, peakcnt, peakstep, maxwlen, peakno;
  2020. int *peak;
  2021. int gotpeak;
  2022. /* ENVELOPE OF 1st SND */
  2023. wlen0 = dz->insams[0]/dz->wanted;
  2024. wlen1 = dz->insams[1]/dz->wanted;
  2025. maxwlen = max(wlen0,wlen1);
  2026. if((dz->parray[4] = (double *)malloc(maxwlen * sizeof(double)))==NULL) {
  2027. sprintf(errstr,"Insufficient memory for amplitude-scaling.\n");
  2028. return(MEMORY_ERROR);
  2029. }
  2030. maxenvval = 0.0;
  2031. for(n=0;n<wlen0;n++)
  2032. maxenvval = max(maxenvval,window_level0[n]);
  2033. minenvval = maxenvval/SIGNOIS_SPEC;
  2034. /* Zero v. quiet windowsums */
  2035. for(n=0;n<wlen0;n++) {
  2036. if(window_level0[n] < minenvval)
  2037. window_level0[n] = 0.0;
  2038. }
  2039. /* Scale to size of other Snd */
  2040. posttail_wlen0 = wlen0 - atk_window;
  2041. posttail_wlen1 = wlen1 - atk_window;
  2042. step = (double)posttail_wlen0/(double)posttail_wlen1;
  2043. here = (double)atk_window;
  2044. dz->parray[4][0] = window_level0[0];
  2045. k = atk_window;
  2046. lastn = atk_window;
  2047. if(step >= 1.0) {
  2048. while(here < (double)wlen0) {
  2049. here += step;
  2050. n = (int)floor(here);
  2051. val = window_level0[lastn];
  2052. for(z = lastn;z<= n;z++)
  2053. val = max(window_level0[z],val);
  2054. dz->parray[4][k] = val;
  2055. lastn = n;
  2056. if(++k >= wlen1)
  2057. break;
  2058. }
  2059. } else {
  2060. while(here < (double)wlen0) {
  2061. here += step;
  2062. n = (int)floor(here);
  2063. m = (int)ceil(here);
  2064. if(m==n)
  2065. dz->parray[4][k] = window_level0[m];
  2066. else {
  2067. valdiff = window_level0[m] - window_level0[n];
  2068. ratio = (int)round(here - (double)n);
  2069. valdiff *= ratio;
  2070. dz->parray[4][k] = window_level0[n] + valdiff;
  2071. }
  2072. if(++k >= wlen1)
  2073. break;
  2074. }
  2075. }
  2076. memcpy((char *)window_level0,(char *)dz->parray[4],wlen1 * sizeof(double));
  2077. /* Get envelope of spectrum */
  2078. envlen = wlen1/SPEC_ENV_RATIO;
  2079. if(envlen * SPEC_ENV_RATIO < wlen1)
  2080. envlen++;
  2081. if((dz->parray[0] = (double *)malloc(envlen * sizeof(double)))==NULL) {
  2082. sprintf(errstr,"No memory for envelope of file 1.\n");
  2083. return(MEMORY_ERROR);
  2084. }
  2085. snd1maxlevel = 0.0;
  2086. for(n=0,k=0;n<wlen1;n+=SPEC_ENV_RATIO,k++) {
  2087. maxenvval = 0.0;
  2088. if(n+SPEC_ENV_RATIO >= wlen1) {
  2089. for(m=n;m<wlen1;m++)
  2090. maxenvval = max(maxenvval,window_level0[m]);
  2091. } else {
  2092. for(m=0;m<SPEC_ENV_RATIO;m++)
  2093. maxenvval = max(maxenvval,window_level0[n+m]);
  2094. }
  2095. dz->parray[0][k] = maxenvval;
  2096. snd1maxlevel = max(snd1maxlevel,maxenvval);
  2097. }
  2098. /* ENVELOPE OF 2nd SND */
  2099. maxenvval = 0.0;
  2100. for(n=0;n<wlen1;n++)
  2101. maxenvval = max(maxenvval,window_level1[n]);
  2102. minenvval = maxenvval/SIGNOIS_SPEC;
  2103. /* Zero v. quiet windowsums */
  2104. for(n=0;n<wlen1;n++) {
  2105. if(window_level1[n] < minenvval)
  2106. window_level1[n] = 0.0;
  2107. }
  2108. if((dz->parray[1] = (double *)malloc(envlen * sizeof(double)))==NULL) {
  2109. sprintf(errstr,"No memory for envelope of file 2.\n");
  2110. return(MEMORY_ERROR);
  2111. }
  2112. for(n=0,k=0;n<wlen1;n+=SPEC_ENV_RATIO,k++) {
  2113. maxenvval = 0.0;
  2114. if(n+SPEC_ENV_RATIO >= wlen1) {
  2115. for(m=n;m<wlen1;m++)
  2116. maxenvval = max(maxenvval,window_level1[m]);
  2117. } else {
  2118. for(m=0;m<SPEC_ENV_RATIO;m++)
  2119. maxenvval = max(maxenvval,window_level1[n+m]);
  2120. }
  2121. dz->parray[1][k] = maxenvval;
  2122. }
  2123. /* Get peaks in 2nd snd */
  2124. if((peak = (int *)malloc(k * sizeof(int)))==NULL) {
  2125. sprintf(errstr,"No memory for envelope peaks.\n");
  2126. return(MEMORY_ERROR);
  2127. }
  2128. peakno = 0;
  2129. gotpeak = 0;
  2130. for(n = 1;n<envlen;n++) {
  2131. if(!gotpeak) {
  2132. if(dz->parray[1][n] < dz->parray[1][n-1]) {
  2133. peak[peakno++] = (int)(n-1);
  2134. gotpeak = 1;
  2135. }
  2136. } else {
  2137. if(dz->parray[1][n] > dz->parray[1][n-1])
  2138. gotpeak = 0;
  2139. }
  2140. // n++;
  2141. }
  2142. if((peakcnt = peakno) == 0) {
  2143. for(n=0;n<maxwlen;n++) /* SET WINDOW SCALING TO 1.0 */
  2144. window_level0[n] = 1.0;
  2145. return(FINISHED);
  2146. }
  2147. /* Get scaling ratio */
  2148. peakno = 0;
  2149. /* go from peak to peak: where is snd1 atk_window in relation to peaks in snd2 */
  2150. if(atk_window > last_window_in_peak(peak[0])) {
  2151. while(last_window_in_peak(peak[peakno]) < atk_window) {
  2152. peakno++;
  2153. if(peakno >= peakcnt) {
  2154. for(n=0;n<maxwlen;n++) /* SET WINDOW SCALING TO 1.0 */
  2155. window_level0[n] = 1.0;
  2156. return(FINISHED);
  2157. }
  2158. }
  2159. }
  2160. for(n=0;n<atk_window;n++)
  2161. dz->parray[2][n] = 1.0; /* Set scaling, as far as atk_window, to 1: snd2 dominates up to atk moment */
  2162. peakno++; /* get next peak */
  2163. n = peak[peakno]; /* Calc scaling, as far as the peak-at-end-of-peakstep-containing-atk_window */
  2164. scale_at_last_peak = 1.0; /* Start at full level of src0, at the attack window */
  2165. scale_at_this_peak = dz->parray[1][n]/snd1maxlevel; /* End scaled by normalised level of snd2 */
  2166. peakstep = (n * SPEC_ENV_RATIO) - atk_window; /* scaling gradually changes from one to the other */
  2167. scalestep = (scale_at_this_peak - scale_at_last_peak)/peakstep;
  2168. for(k = atk_window,m = 0; k < n * SPEC_ENV_RATIO; k++,m++) {
  2169. scalehere = scale_at_last_peak + (m * scalestep);
  2170. window_level0[k] *= scalehere * window_level1[k]; /* window_level0 contains level of snd1: level multiplied by normd level of snd2 */
  2171. }
  2172. lastn = n;
  2173. peakno++;
  2174. while (peakno < peakcnt) { /* CALC SCALING from peak-to-peak over all subsequent windows */
  2175. n = peak[peakno];
  2176. scale_at_last_peak = dz->parray[1][lastn]/snd1maxlevel;
  2177. scale_at_this_peak = dz->parray[1][n]/snd1maxlevel;
  2178. peakstep = (n - lastn) * SPEC_ENV_RATIO;
  2179. scalestep = (scale_at_this_peak - scale_at_last_peak)/peakstep;
  2180. for(k = lastn * SPEC_ENV_RATIO,m = 0; k < n * SPEC_ENV_RATIO; k++,m++) {
  2181. scalehere = scale_at_last_peak + (m * scalestep) * window_level1[k];
  2182. window_level0[k] *= scalehere * window_level1[k];
  2183. }
  2184. lastn = n;
  2185. peakno++;
  2186. }
  2187. n = envlen; /* CALC SCALING from Final to peak to end of file (assume scaled to zero) */
  2188. scale_at_last_peak = dz->parray[1][lastn]/snd1maxlevel;
  2189. scale_at_this_peak = 0.0;
  2190. peakstep = wlen1 - (lastn * SPEC_ENV_RATIO);
  2191. scalestep = (scale_at_this_peak - scale_at_last_peak)/peakstep;
  2192. for(k = lastn * SPEC_ENV_RATIO,m = 0; k < wlen1; k++,m++) {
  2193. scalehere = scale_at_last_peak + (m * scalestep) * window_level1[k];
  2194. window_level0[k] *= scalehere * window_level1[k];
  2195. }
  2196. /* Now the amplitude scaling is in dz->parray[2] */
  2197. return FINISHED;
  2198. }
  2199. /************************************ LAST_WINDOW_IN_PEAK ******************************/
  2200. int last_window_in_peak(int peak)
  2201. {
  2202. int win_start = peak * SPEC_ENV_RATIO;
  2203. int win_end = win_start + SPEC_ENV_RATIO - 1;
  2204. return win_end;
  2205. }
  2206. /************************************ EXTEND_STABLE_PITCH_TO_START ******************************/
  2207. #define STABILITY_INTERVAL (5) /* pitch is stable when it remains within STABILITY_INTERVAL semitones */
  2208. #define STABILITY_WINDOWS (3) /* pitch is stable if remains within interval for STABILITY_WINDOWS windows */
  2209. int extend_stable_pitch_to_start(dataptr dz)
  2210. {
  2211. int stability_cnt = 0;
  2212. int n, k;
  2213. double stability1 = pow(2,(double)STABILITY_INTERVAL/SEMITONES_PER_OCTAVE);
  2214. double stability2 = 1.0/stability1, ratio;
  2215. for(n=1;n<dz->itemcnt;n++) {
  2216. ratio = dz->pitches[n]/dz->pitches[n-1];
  2217. if(ratio <= stability1 && ratio >= stability2)
  2218. stability_cnt++;
  2219. else
  2220. stability_cnt = 0;
  2221. if(stability_cnt >= STABILITY_WINDOWS) {
  2222. for(k = 0;k < n-4;k++)
  2223. dz->pitches[k] = dz->pitches[n-3];
  2224. fprintf(stdout,"INFO: Stable pitch found at %lf\n",(n-3) * dz->frametime);
  2225. fflush(stdout);
  2226. return FINISHED;
  2227. }
  2228. }
  2229. return GOAL_FAILED;
  2230. }